Skip to content

feat: backport production hardening and architecture improvements#7

Merged
jeanpaulsio merged 1 commit intomainfrom
feat/backport-step-thru-learnings
Mar 30, 2026
Merged

feat: backport production hardening and architecture improvements#7
jeanpaulsio merged 1 commit intomainfrom
feat/backport-step-thru-learnings

Conversation

@jeanpaulsio
Copy link
Copy Markdown
Owner

Summary

Backports battle-tested improvements discovered while using this starter template in production. Covers bug fixes, production hardening, DX improvements, and architectural refinements.

Bug Fixes (Priority 1)

  • Fix validation error serialization — Pydantic ctx fields can contain non-JSON-serializable objects (ValueError instances), causing 500s on certain invalid inputs
  • Add 30s PostgreSQL statement timeout — prevents runaway queries from exhausting the connection pool
  • Fix access_token cookie TTL — was 24h on frontend but 30min on backend, causing silent auth failures

Production Hardening (Priority 2)

  • Sentry error reporting in API client — captures 5xx errors (excluding 401s/auth endpoints) with status + URL tags
  • Lower connection pool defaults — 10/20 was oversized for Render starter plan, now 5/5
  • Redis via app.state — idiomatic FastAPI pattern instead of global variable in database.py
  • Switch to slowapi — decorator-based rate limiting replaces custom Redis middleware

Architecture (Priority 3)

  • Replace Zustand with React Query — useCurrentUser() + useLogout() hooks; server state belongs in React Query, not a client store
  • Add query helpers — escape_like() for safe LIKE/ILIKE queries, parse_enum_filter() for comma-separated enum params
  • Bump pagination max — 100 to 250

DX (Priority 4)

  • CI parallelization — split backend into parallel lint + test jobs, add pip caching
  • SSE streaming client — reusable streamSSE() utility for LLM/streaming endpoints
  • Remove withCredentials — unnecessary with Bearer header auth pattern

Files Changed

  • 30 files: 506 insertions, 396 deletions
  • New: server/app/limiter.py, server/app/utils/query.py, web/hooks/useAuth.ts, web/lib/sse-client.ts
  • Deleted: server/app/middleware/rate_limit.py, web/stores/auth-store.ts

Test plan

  • Backend: cd server && ruff check app/ tests/ && ruff format --check app/ tests/ && mypy app/ --ignore-missing-imports && pytest tests/ -v
  • Frontend: cd web && npm install && npm run lint && npm run typecheck && npm test
  • Verify health endpoint still reports postgres + redis status
  • Verify auth flow: register -> login -> dashboard -> logout
  • Verify rate limiting on auth endpoints (5 rapid register attempts should 429)

Apply battle-tested improvements discovered while using this starter
template in production. Addresses bug fixes, production hardening, DX
improvements, and architectural refinements.

Backend:
- Fix validation error serialization (non-JSON-safe ctx fields)
- Add 30s PostgreSQL statement timeout to prevent runaway queries
- Lower connection pool defaults (10/20 to 5/5) for Render starter plan
- Switch from custom Redis rate-limit middleware to slowapi (decorator-based)
- Add query helpers: escape_like(), parse_enum_filter()
- Bump pagination max limit from 100 to 250
- Move Redis connection to app.state (idiomatic FastAPI pattern)

Frontend:
- Fix access_token cookie TTL mismatch (24h to 30min to match backend)
- Add Sentry error reporting for 5xx API errors in client interceptor
- Replace Zustand auth store with React Query (useCurrentUser/useLogout)
- Add SSE streaming client utility for LLM/streaming endpoints
- Remove withCredentials (unnecessary with Bearer header auth)

CI:
- Split backend CI into parallel lint + test jobs
- Add pip caching for faster backend CI runs
@jeanpaulsio jeanpaulsio merged commit da77914 into main Mar 30, 2026
@jeanpaulsio jeanpaulsio deleted the feat/backport-step-thru-learnings branch March 30, 2026 21:06
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