=chore-finalize-stitch-verification

This commit is contained in:
Jens
2026-07-21 23:05:58 +02:00
parent 479f61fc6a
commit 598d3ec18a
6 changed files with 825 additions and 255 deletions
+780 -250
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -8,7 +8,7 @@ De repository bevat zowel een **werkende MVP-kern** als de volledige product-, a
Reeds geïmplementeerd:
- Django 5.2-modulaire monoliet met Nederlandstalige responsieve interface;
- Django 5.2-modulaire monoliet met Nederlandstalige responsive dark/light Intelligence Cockpit;
- PostgreSQL in productie en SQLite voor lokale ontwikkeling;
- Celery-worker en scheduler via Redis;
- veilige HTTP-fetcher met domeinbeleid, redirecthercontrole, contentlimieten en SSRF-blokkering;
@@ -180,6 +180,7 @@ Lees [`SECURITY.md`](SECURITY.md) en [`docs/quality/THREAT_MODEL.md`](docs/quali
- [Systeemarchitectuur](docs/architecture/SYSTEM_ARCHITECTURE.md)
- [Datamodel](docs/architecture/DATA_MODEL.md)
- [UX- en designspecificatie](docs/design/UX_SPEC.md)
- [Stitch-integratieplan en schermmapping](docs/design/STITCH_INTEGRATION_PLAN.md)
- [Bron- en adaptercontract](docs/architecture/SOURCE_ADAPTERS.md)
- [Scoringengine](docs/architecture/SCORING_ENGINE.md)
- [Unraid-deployment](docs/operations/UNRAID_DEPLOYMENT.md)
+9 -1
View File
@@ -91,4 +91,12 @@ Uitgevoerde browsermatrix:
Screenshots: `docs/design/validation/`. Deze map en de originele Stitch-referentie zijn via `.dockerignore` uitgesloten van de productiecontainer.
De volledige afrondingsgate en actuele aantallen worden onderaan dit rapport toegevoegd na `scripts/codex_verify.sh`.
Volledige afrondingsgate:
- Ruff: geslaagd;
- Django system check: geslaagd;
- migratiecontrole: geen wijzigingen;
- pytest: 146 geslaagd, 2 optionele Playwrightvarianten overgeslagen met geslaagde HTML/a11y-fallback;
- branch-aware codedekking: 82,00%, boven de vereiste 70%;
- taakledger: 36 taken, waarvan 28 done, 5 blocked-external, 3 deferred en 0 ready;
- repositorydocumentatie en configuratie: geldig.
+2
View File
@@ -10,6 +10,8 @@ De documentatie is opgesplitst per beslisniveau zodat een mens of coding agent a
- `product/PRODUCT_REQUIREMENTS.md` — wat het product moet doen;
- `architecture/SYSTEM_ARCHITECTURE.md` — hoe het systeem is opgebouwd;
- `design/UX_SPEC.md` — gebruikerservaring en schermgedrag;
- `design/STITCH_INTEGRATION_PLAN.md` — mapping van de Stitch Intelligence Cockpit naar echte Django-routes en data;
- `design/validation/` — responsieve browservalidatiebeelden van VR-118 (niet in de productiecontainer);
- `operations/UNRAID_DEPLOYMENT.md` — productie-installatie;
- `quality/DEFINITION_OF_DONE.md` — afrondingsnorm.
- `../VERIFICATION_REPORT.md` — bewezen baseline en expliciete verificatiebeperkingen.
+8
View File
@@ -33,6 +33,14 @@ Release-audit op 2026-07-21:
- een echte Dockerimagebuild op de Unraid-server, migratiecontrole en live LAN-smoke voor liveness, readiness, login en static assets zijn geslaagd;
- deploymenthardening voorkomt gelijktijdige migraties door worker/scheduler, schakelt de Gunicorn-controlsocket uit voor de read-only container en houdt de lokale healthcheckhost toegestaan.
VR-118-herverificatie op 2026-07-21:
- 146 geslaagde tests en 2 optioneel overgeslagen pytest-Playwrightvarianten; HTML/a11y-fallback geslaagd;
- 82,00% branch-aware codedekking;
- Ruff, Django system check en migratiecontrole geslaagd;
- taakledger geldig met 36 taken: 28 done, 5 blocked-external, 3 deferred en 0 ready;
- geïntegreerde browservalidatie op zes viewports en beide thema's geslaagd.
## Deploymentstatus
- `main` is via de bestaande Gitea-SSH-sleutel naar `NuklearRabbit/VacatureRadar` gepusht.
+24 -3
View File
@@ -4,6 +4,7 @@ from __future__ import annotations
import argparse
import hashlib
import json
import os
import shutil
import tempfile
import zipfile
@@ -41,7 +42,17 @@ def is_included(path: Path) -> bool:
def iter_files() -> Iterable[Path]:
return sorted(path for path in ROOT.rglob("*") if is_included(path))
files: list[Path] = []
for directory, dirnames, filenames in os.walk(ROOT):
dirnames[:] = sorted(name for name in dirnames if name not in EXCLUDED_DIRS)
base = Path(directory)
if base == ROOT / "local":
dirnames.clear()
for filename in sorted(filenames):
path = base / filename
if is_included(path):
files.append(path)
return sorted(files)
def sha256(path: Path) -> str:
@@ -52,9 +63,10 @@ def sha256(path: Path) -> str:
return digest.hexdigest()
def write_manifest(staging_root: Path) -> None:
def write_manifest(staging_root: Path, paths: Iterable[Path] | None = None) -> None:
entries = []
for path in sorted(staging_root.rglob("*")):
candidates = sorted(paths) if paths is not None else sorted(staging_root.rglob("*"))
for path in candidates:
if not path.is_file() or path.name == "PROJECT_MANIFEST.json":
continue
entries.append(
@@ -103,6 +115,11 @@ def package(output: Path) -> tuple[int, str]:
def main() -> int:
parser = argparse.ArgumentParser(description="Maak een schone VacatureRadar-project-ZIP")
parser.add_argument(
"--manifest-only",
action="store_true",
help="Werk alleen PROJECT_MANIFEST.json in de repository bij.",
)
parser.add_argument(
"output",
nargs="?",
@@ -110,6 +127,10 @@ def main() -> int:
default=ROOT.parent / "VacatureRadar_Project.zip",
)
args = parser.parse_args()
if args.manifest_only:
write_manifest(ROOT, iter_files())
print(f"Manifest: {(ROOT / 'PROJECT_MANIFEST.json').resolve()}")
return 0
size, checksum = package(args.output)
print(f"ZIP: {args.output.resolve()}")
print(f"Bytes: {size}")