Phase 4-5: entrant + manager web flow, Docker bring-up #3

Merged
kiro_agent merged 3 commits from feature/phase-4-5-web into main 2026-10-24 08:41:00 +00:00
Owner

Summary

Phase 4+5 delivers three surfaces:

1. Entrant web flow

Public upload path (/upload, /upload/preview, /upload/submit) that validates email-match, a 5-digit PIN, and the Declaration, auto-detects the log format, never rejects a submission for rule issues (R17), enforces the Submission Window before ingest (R21), handles PinMismatch/DuplicateEntry, and sends a confirmation email via the file backend by default. Entrant-facing views expose public fields only.

2. Manager web flow

Authenticated manager surface where every mutation (account create/disable/reset, flag resolve, QSO edit, score adjust, window override, PIN reset, reference add/remove/toggle/clear-review) follows the mutate -> flush -> record_audit(actor=current manager) -> single-commit pattern (R20/N7), with visible audit markers. PIN reset stores neither PIN nor hash. The privacy split (R25) holds: email, operator name, address, and Declaration appear only in the manager entry-detail view.

3. Docker bring-up

Stateless containers with all state under ./data: libpq5 in the image, ./data/app and ./data/db bind mounts, a Postgres healthcheck with depends_on: service_healthy, and an idempotent entrypoint (alembic upgrade head -> bootstrap -> uvicorn). An absolute build context avoids the worktree parent-path quirk.

Testing

  • Full pytest suite: 122 passed (93 baseline + 11 + 14 + 4 new).
  • Live Docker container bring-up end-to-end: alembic migration + bootstrap, entrant upload stored with correct score and .eml confirmation, manager login, and data surviving a web-container recreate.
  • Two Postgres-only issues found and fixed during container verification (migration server_default drift and a SAEnum name-vs-value mismatch); CVE pins raised.

Note

The Dutch Locator Reference contents remain provisional and are deferred; only the editing UI over the reference DB table was built in this phase. The reference starter data is unchanged in this branch.

## Summary Phase 4+5 delivers three surfaces: ### 1. Entrant web flow Public upload path (`/upload`, `/upload/preview`, `/upload/submit`) that validates email-match, a 5-digit PIN, and the Declaration, auto-detects the log format, never rejects a submission for rule issues (R17), enforces the Submission Window before ingest (R21), handles PinMismatch/DuplicateEntry, and sends a confirmation email via the file backend by default. Entrant-facing views expose public fields only. ### 2. Manager web flow Authenticated manager surface where every mutation (account create/disable/reset, flag resolve, QSO edit, score adjust, window override, PIN reset, reference add/remove/toggle/clear-review) follows the mutate -> flush -> record_audit(actor=current manager) -> single-commit pattern (R20/N7), with visible audit markers. PIN reset stores neither PIN nor hash. The privacy split (R25) holds: email, operator name, address, and Declaration appear only in the manager entry-detail view. ### 3. Docker bring-up Stateless containers with all state under `./data`: libpq5 in the image, `./data/app` and `./data/db` bind mounts, a Postgres healthcheck with `depends_on: service_healthy`, and an idempotent entrypoint (`alembic upgrade head` -> bootstrap -> uvicorn). An absolute build context avoids the worktree parent-path quirk. ## Testing - Full pytest suite: 122 passed (93 baseline + 11 + 14 + 4 new). - Live Docker container bring-up end-to-end: alembic migration + bootstrap, entrant upload stored with correct score and `.eml` confirmation, manager login, and data surviving a web-container recreate. - Two Postgres-only issues found and fixed during container verification (migration server_default drift and a SAEnum name-vs-value mismatch); CVE pins raised. ## Note The Dutch Locator Reference contents remain provisional and are deferred; only the editing UI over the reference DB table was built in this phase. The reference starter data is unchanged in this branch.
Build the shared server-rendered web infrastructure (SessionMiddleware,
Jinja2 templating bound to app.i18n, request-scoped get_db dependency over
the lazy engine, /static mount, /lang language switch) and the entrant
journey on top of the Phase 1-3 core: upload form with explicit A-F Section
dropdown and format auto-detect, parsed preview (QSO count, per-band Monthly
Score, advisory Flags), stateless submit via ingest_parsed_log enforcing the
one-Entry invariant + PIN-gated re-upload, Submission Window enforcement via
MonthlyContest.is_locked, and a confirmation email backend (SMTP or file
fallback). Bilingual (Dutch default, English selectable).
Add app/bootstrap.py (initial Manager + current ContestYear + 12 MonthlyContests, idempotent), entrypoint.sh (alembic upgrade head -> bootstrap -> uvicorn), libpq in the Dockerfile on python:3.15-slim, and docker-compose db bind mount + healthcheck + env. Fix two Postgres-only defects found during the live bring-up: missing server_default on created_at/at/uploaded_at in the initial migration, and SAEnum columns persisting member names instead of values (band). Raise dependency floors to CVE-patched releases.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
public/vrza-contestrobot!3
No description provided.