Files
sales-trainer/docs/engineering-log/2026-08-16-s4-4-importer-errorhandler-commit.md
Macky 2c40fc7502 feat(import): commit S4.4 JSON→PostgreSQL importer + API error-handler hardening
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.
2026-08-16 07:42:32 +07:00

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 JSON HTTPException error handler so non-/api framework errors (404/405/etc.) under /api/* return {"error": ...} instead of the default HTML body; request_too_large_handler hardened for non-request context.
  • backend/app/factory.py_register_frontend now abort(404) for api/health paths (parse-safe, no ("not found", 404) tuple); HTTPException handler 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.