=chore-finalize-stitch-verification
This commit is contained in:
+780
-250
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ De repository bevat zowel een **werkende MVP-kern** als de volledige product-, a
|
|||||||
|
|
||||||
Reeds geïmplementeerd:
|
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;
|
- PostgreSQL in productie en SQLite voor lokale ontwikkeling;
|
||||||
- Celery-worker en scheduler via Redis;
|
- Celery-worker en scheduler via Redis;
|
||||||
- veilige HTTP-fetcher met domeinbeleid, redirecthercontrole, contentlimieten en SSRF-blokkering;
|
- 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)
|
- [Systeemarchitectuur](docs/architecture/SYSTEM_ARCHITECTURE.md)
|
||||||
- [Datamodel](docs/architecture/DATA_MODEL.md)
|
- [Datamodel](docs/architecture/DATA_MODEL.md)
|
||||||
- [UX- en designspecificatie](docs/design/UX_SPEC.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)
|
- [Bron- en adaptercontract](docs/architecture/SOURCE_ADAPTERS.md)
|
||||||
- [Scoringengine](docs/architecture/SCORING_ENGINE.md)
|
- [Scoringengine](docs/architecture/SCORING_ENGINE.md)
|
||||||
- [Unraid-deployment](docs/operations/UNRAID_DEPLOYMENT.md)
|
- [Unraid-deployment](docs/operations/UNRAID_DEPLOYMENT.md)
|
||||||
|
|||||||
@@ -91,4 +91,12 @@ Uitgevoerde browsermatrix:
|
|||||||
|
|
||||||
Screenshots: `docs/design/validation/`. Deze map en de originele Stitch-referentie zijn via `.dockerignore` uitgesloten van de productiecontainer.
|
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.
|
||||||
|
|||||||
@@ -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;
|
- `product/PRODUCT_REQUIREMENTS.md` — wat het product moet doen;
|
||||||
- `architecture/SYSTEM_ARCHITECTURE.md` — hoe het systeem is opgebouwd;
|
- `architecture/SYSTEM_ARCHITECTURE.md` — hoe het systeem is opgebouwd;
|
||||||
- `design/UX_SPEC.md` — gebruikerservaring en schermgedrag;
|
- `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;
|
- `operations/UNRAID_DEPLOYMENT.md` — productie-installatie;
|
||||||
- `quality/DEFINITION_OF_DONE.md` — afrondingsnorm.
|
- `quality/DEFINITION_OF_DONE.md` — afrondingsnorm.
|
||||||
- `../VERIFICATION_REPORT.md` — bewezen baseline en expliciete verificatiebeperkingen.
|
- `../VERIFICATION_REPORT.md` — bewezen baseline en expliciete verificatiebeperkingen.
|
||||||
|
|||||||
@@ -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;
|
- 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.
|
- 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
|
## Deploymentstatus
|
||||||
|
|
||||||
- `main` is via de bestaande Gitea-SSH-sleutel naar `NuklearRabbit/VacatureRadar` gepusht.
|
- `main` is via de bestaande Gitea-SSH-sleutel naar `NuklearRabbit/VacatureRadar` gepusht.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
import argparse
|
import argparse
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
import zipfile
|
import zipfile
|
||||||
@@ -41,7 +42,17 @@ def is_included(path: Path) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def iter_files() -> Iterable[Path]:
|
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:
|
def sha256(path: Path) -> str:
|
||||||
@@ -52,9 +63,10 @@ def sha256(path: Path) -> str:
|
|||||||
return digest.hexdigest()
|
return digest.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def write_manifest(staging_root: Path) -> None:
|
def write_manifest(staging_root: Path, paths: Iterable[Path] | None = None) -> None:
|
||||||
entries = []
|
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":
|
if not path.is_file() or path.name == "PROJECT_MANIFEST.json":
|
||||||
continue
|
continue
|
||||||
entries.append(
|
entries.append(
|
||||||
@@ -103,6 +115,11 @@ def package(output: Path) -> tuple[int, str]:
|
|||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
parser = argparse.ArgumentParser(description="Maak een schone VacatureRadar-project-ZIP")
|
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(
|
parser.add_argument(
|
||||||
"output",
|
"output",
|
||||||
nargs="?",
|
nargs="?",
|
||||||
@@ -110,6 +127,10 @@ def main() -> int:
|
|||||||
default=ROOT.parent / "VacatureRadar_Project.zip",
|
default=ROOT.parent / "VacatureRadar_Project.zip",
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
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)
|
size, checksum = package(args.output)
|
||||||
print(f"ZIP: {args.output.resolve()}")
|
print(f"ZIP: {args.output.resolve()}")
|
||||||
print(f"Bytes: {size}")
|
print(f"Bytes: {size}")
|
||||||
|
|||||||
Reference in New Issue
Block a user