Skip to content

feat: production-grade hardening (persistence, auth, Docker, tests, CI) - #4

Open
R-zin wants to merge 1 commit into
mainfrom
feature/production-hardening
Open

R-zin wants to merge 1 commit into
mainfrom
feature/production-hardening

Conversation

@R-zin

@R-zin R-zin commented Aug 26, 2026

Copy link
Copy Markdown
Owner

Backend:

  • app/settings.py: pydantic-settings (OSM2NS3_* env prefix, derived data/static dirs)
  • app/store.py: SQLite job store (WAL, retention pruning, startup recovery of interrupted jobs) replacing the in-memory dict
  • app/worker.py: PipelineRunner with semaphore concurrency cap; job cancellation that SIGKILLs the process group before task.cancel() (wait_for won't reap children on cancel); cancel-vs-completion race fixed by re-checking the store before marking done
  • main.py: create_app factory; streamed 1 MiB uploads with size cap; /live + /ready probes; API-key auth off by default (X-API-Key, env-enabled on /jobs/*); CORS fixed from wildcard; SPA StaticFiles mount with deep-link fallback

Tests + CI:

  • 118 tests (90% coverage): models, command builders, store, full API with mocked SUMO, cancellation machinery
  • CI rewritten: backend job (pytest --cov ≥80% + uvicorn /health smoke) and frontend job (npm ci + tsc/vite build)

Frontend:

  • API-key input persisted to localStorage and sent as X-API-Key
  • Schema drift fix: configSchema.ts deleted; form generated from live GET /schema (caught real drift: old code shipped lowercase sotl_phase, wire value SOTL_PHASE)
  • Job cancel button, blob download (no key-in-URL), cancelled status styling, /health -> /ready switch

Ops:

  • Multi-stage Dockerfile (node build -> ubuntu22.04+SUMO+sumo-tools, non-root, /data volume), .dockerignore, docker-compose.yml
  • black/isort/ruff config in pyproject.toml + one-time reformat; Lint.yml pinned to the same profile

Backend:
- app/settings.py: pydantic-settings (OSM2NS3_* env prefix, derived data/static dirs)
- app/store.py: SQLite job store (WAL, retention pruning, startup recovery of
  interrupted jobs) replacing the in-memory dict
- app/worker.py: PipelineRunner with semaphore concurrency cap; job cancellation
  that SIGKILLs the process group before task.cancel() (wait_for won't reap
  children on cancel); cancel-vs-completion race fixed by re-checking the store
  before marking done
- main.py: create_app factory; streamed 1 MiB uploads with size cap; /live +
  /ready probes; API-key auth off by default (X-API-Key, env-enabled on /jobs/*);
  CORS fixed from wildcard; SPA StaticFiles mount with deep-link fallback

Tests + CI:
- 118 tests (90% coverage): models, command builders, store, full API with mocked
  SUMO, cancellation machinery
- CI rewritten: backend job (pytest --cov ≥80% + uvicorn /health smoke) and
  frontend job (npm ci + tsc/vite build)

Frontend:
- API-key input persisted to localStorage and sent as X-API-Key
- Schema drift fix: configSchema.ts deleted; form generated from live GET /schema
  (caught real drift: old code shipped lowercase sotl_phase, wire value SOTL_PHASE)
- Job cancel button, blob download (no key-in-URL), cancelled status styling,
  /health -> /ready switch

Ops:
- Multi-stage Dockerfile (node build -> ubuntu22.04+SUMO+sumo-tools, non-root,
  /data volume), .dockerignore, docker-compose.yml
- black/isort/ruff config in pyproject.toml + one-time reformat; Lint.yml pinned
  to the same profile

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant