How naina-sriv/ftp works
1. Overall shape
This is a single FastAPI backend for civic issue reporting. It is organized as a layered monolith: HTTP routers at the edge, service-like auth/dependency helpers in app/core, SQLAlchemy ORM models in app/models, and Pydantic schemas in app/schema.
2. Request entrypoint
app/main.py is the application bootstrap. It creates the FastAPI app and wires in the route modules under app/routers, so all client traffic enters through one API process.
3. API boundary
The functional API is split by concern:
- auth.py for registration and login
- issue.py for issue CRUD
- comments.py for issue comments
- votes.py for voting and escalation logic
This separation is important for diagramming because each router maps to a distinct user action and resource type.
4. Identity and access control
Authentication is JWT-based, backed by password hashing in app/core/security.py. The get_current_user dependency in app/core/dependencies.py is the main enforcement point for protected routes. The README indicates the token also carries constituency information, which scopes what each user can see and modify.
5. Domain model and persistence
The database layer centers on five core entities in app/models: User, Constituency, Issue, Comment, and Vote. These form the persistent domain graph:
- users belong to a constituency
- issues are reported within a constituency
- comments attach to issues
- votes attach to issues and are used for threshold validation
6. Data validation layer
app/schema contains the Pydantic request/response contracts for each domain object, plus token schemas. This is the boundary between external JSON and internal ORM objects, and it is where API payload shape and response serialization are enforced.
7. Database infrastructure
app/db.py is the database/session boundary. The repository is designed to run against PostgreSQL in normal use, but the tests use SQLite. This makes the persistence layer portable while keeping local and test execution lightweight.
8. Issue lifecycle and escalation
The key business rule is threshold-based escalation. Issues start as open; when enough unique users vote, the issue transitions to escalated and a threshold flag is set. The vote endpoint triggers this check asynchronously via FastAPI BackgroundTasks, so the API response returns immediately while the status update happens after the write.
9. Constituency scoping as a system-wide constraint
Constituency is not just metadata; it is a hard access boundary. Reads and writes for issues, comments, and votes are constrained to the user’s constituency, which prevents cross-constituency interaction and keeps the data model aligned with the product goal.
10. Testing architecture
tests/conftest.py provides an in-memory SQLite fixture, and tests/test_routes.py exercises the API end-to-end. The tests cover auth, CRUD, comment flows, voting rules, duplicate vote prevention, and threshold escalation, so the test suite validates the full request-to-database path rather than isolated units.
11. Configuration and runtime inputs
app/core/config.py centralizes environment-driven settings such as database URL, secret key, signing algorithm, and token expiry. That makes runtime behavior configurable without changing application code, which is important for diagramming deployment dependencies.
12. External-facing interfaces
The only externally visible interface is the HTTP API. There are no queues, caches, or separate worker services in the current implementation; async behavior is handled in-process with FastAPI background tasks, and persistence is the database.
13. Practical architecture summary
The clearest diagram is: client → FastAPI routers → auth/dependency layer → ORM/models → SQLAlchemy session/database, with background tasks branching off from voting to perform escalation checks. The main cross-cutting concerns are JWT auth, constituency scoping, and schema validation.
Main entry points: auth.py Auth API · test_routes.py Route tests · issue.py Issue API · votes.py Vote API
Components 22
Application
FastAPI app bootstrap and HTTP entrypoints
- App startup · Creates the FastAPI application and wires routers.
app/main.py - Auth API · Registration and login endpoints.
app/routers/auth.py - Issue API · Issue CRUD endpoints.
app/routers/issue.py - Comment API · Issue comment endpoints.
app/routers/comments.py - Vote API · Voting and escalation endpoints.
app/routers/votes.py
Core
Auth, config, and request dependencies
- Settings · Environment-driven runtime settings.
app/core/config.py - Security · Password hashing and JWT handling.
app/core/security.py - Auth guard · Current-user dependency and access enforcement.
app/core/dependencies.py
Domain
Persistent business entities
- User · Authenticated user records.
app/models/user.py - Constituency · Scoping boundary for users and issues.
app/models/constituency.py - Issue · Reported civic issues and status.
app/models/issue.py - Comment · Comments attached to issues.
app/models/comment.py - Vote · Issue votes used for threshold checks.
app/models/vote.py
Schemas
Pydantic request and response contracts
- User schema · User request and response payloads.
app/schema/user.py - Constituency schema · Constituency payload contracts.
app/schema/constituency.py - Issue schema · Issue payload contracts.
app/schema/issue.py - Comment schema · Comment payload contracts.
app/schema/comment.py - Vote schema · Vote payload contracts.
app/schema/vote.py - Token schema · JWT and auth token payloads.
app/schema/token.py
Persistence
Database/session boundary
- DB session · SQLAlchemy session and database boundary.
app/db.py
Tests
End-to-end API coverage
- Route tests · End-to-end API and persistence coverage.
tests/test_routes.py - Test DB · SQLite test database fixture.
tests/conftest.py
Connections 33
- App startup → Auth API: includes · Registers auth routes.
- App startup → Issue API: includes · Registers issue routes.
- App startup → Comment API: includes · Registers comment routes.
- App startup → Vote API: includes · Registers vote routes.
- Auth API → Security: hash/sign · Uses JWT and password utilities.
- Auth API → DB session: reads/writes · Persists and validates user records.
- Issue API → Auth guard: protects · Enforces authenticated and scoped access.
- Issue API → DB session: reads/writes · Persists issue changes.
- Comment API → Auth guard: protects · Uses current-user dependency.
- Comment API → DB session: reads/writes · Persists comments.
- Vote API → Auth guard: protects · Uses current-user dependency.
- Vote API → DB session: reads/writes · Persists votes and status updates.
- Vote API → Issue: escalates · Triggers threshold-based issue escalation.
- Auth guard → User: loads · Resolves the authenticated user.
- Auth guard → Constituency: scopes · Constrains access by constituency.
- Issue → Constituency: belongs to · Issues are reported within a constituency.
- Comment → Issue: attaches to · Comments belong to issues.
- Vote → Issue: attaches to · Votes belong to issues.
- User → Constituency: belongs to · Users are assigned to a constituency.
- Auth API → User schema: serializes · Uses user payload contracts.
- Issue API → Issue schema: serializes · Uses issue payload contracts.
- Comment API → Comment schema: serializes · Uses comment payload contracts.
- Vote API → Vote schema: serializes · Uses vote payload contracts.
- Auth API → Token schema: issues · Returns JWT/token payloads.
- Issue API → Constituency schema: serializes · Uses constituency payload contracts.
- Auth API → Settings: configures · Uses secret, algorithm, and expiry settings.
- DB session → Settings: configured by · Database URL comes from settings.
- Route tests → Test DB: uses · Runs against SQLite test database.
- Route tests → Auth API: covers · Exercises auth endpoints.
- Route tests → Issue API: covers · Exercises issue CRUD.
- Route tests → Comment API: covers · Exercises comment flows.
- Route tests → Vote API: covers · Exercises voting and escalation.
- Route tests → DB session: verifies · Validates request-to-database behavior.