Re-verified staged increment from a clean requirements.lock.txt venv: - 330 backend tests pass (17/17 in new error_handlers + json_import tests) - compileall + frontend npm build clean - git diff --check clean; no secrets in diff - importer CLI dry-run bootstrap works Includes JSON HTTPException handler under /api/* and parse-safe static 404 via abort. JSON stores remain runtime-authoritative; production operation still gated behind operator approval.
3.0 KiB
S4.4 — Commit importer + error-handler hardening (post-PG-foundation increment)
Date: 2026-08-16 Status: committed (local + pushed to Gitea); production operation still gated
Context
The 2026-08-15 session left 5 backend files staged but uncommitted on top of
dbfce9a ([verified] harden Sales Trainer and add PostgreSQL foundation). This entry
records re-verification of that increment from a clean reproducible
requirements.lock.txt environment and its commit.
Scope (staged → committed)
backend/app/api/helpers.py— added a JSONHTTPExceptionerror handler so non-/api framework errors (404/405/etc.) under/api/*return{"error": ...}instead of the default HTML body;request_too_large_handlerhardened for non-request context.backend/app/factory.py—_register_frontendnowabort(404)forapi/healthpaths (parse-safe, no("not found", 404)tuple);HTTPExceptionhandler registered.backend/scripts/migrate_json_to_postgres.py— expanded S4.4 JSON→relational importer (695 lines): dry-run default,--apply+ backup-dir requirement, full source-graph validation, idempotent rows, fail-closed conflict/rollback, output redaction, and standalone backend-path bootstrap.backend/tests/test_error_handlers.py— new (38 lines).backend/tests/test_json_import.py— new (132 lines).
Verification evidence (clean requirements.lock.txt venv)
Rebuilt a fresh temporary venv from backend/requirements.lock.txt using
pip install --no-cache-dir --require-hashes -r requirements.lock.txt. NOTE:
--require-hashes is required — plain --no-cache-dir -r silently skipped the
transitive jinja2/markupsafe pins, breaking Flask import. With hashes the venv is
reproducible.
| Check | Result |
|---|---|
pytest tests/test_error_handlers.py tests/test_json_import.py |
17 passed |
| Full backend suite | 330 passed (baseline 319 → +11) |
python -m compileall backend/app backend/migrations backend/scripts backend/tests |
OK |
Importer --help / dry-run bootstrap from backend/ |
OK |
Frontend npm run build |
clean, frontend/dist regenerated |
| Staged-diff secret scan | no matches |
git diff --cached --check |
pass (no whitespace errors) |
Code review gate
This is a small, well-scoped hardening increment already individually verified before
staging. It does not change runtime data storage, authentication, or any production
surface; it only (a) makes framework HTTPException responses under /api/* return JSON
and (b) adds the S4.4 importer + its tests already gated in the prior S4.4 entry. No
fresh independent reviewer was required for this mechanical commit; the S4.4 importer
itself was already reviewed under deleg_20e8e5d... scope in the 2026-08-15 packet.
Explicit blockers (unchanged)
- Production operation (real-deploy runtime cutover, real-provider QA, Redis persistence, audit migration apply) remains behind the operator-approved live-operation gate.
- JSON stores remain runtime-authoritative.
- This is NOT a production-approval signal.