Files
backend/docs/LLM_CONTEXT.md
T

128 lines
4.7 KiB
Markdown

# Visione Backend LLM Context
## What This Repo Is
Visione is C++20 + Drogon backend for urban issue reporting.
Core actors:
- `citizen`: creates and follows reports
- `operator`: manages report lifecycle on platform
- `admin`: manages users/reference data and approves moderation
External intervention teams are off-platform. They receive summary through
public revocable link generated by operator/admin.
## Environment
- Local backend runs outside Docker.
- Docker is only for local dependencies like MySQL and Mailpit.
- Primary commands:
- configure: `cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug`
- build: `cmake --build build`
- test: `ctest --test-dir build --output-on-failure`
- openapi: `cmake --build build --target openapi`
## High-Signal Conventions
- Code, DB identifiers, API fields, comments: English.
- User-facing labels may be Italian.
- Keep controller thin, service owns business logic.
- Use parameterized SQL only.
- Prefer current code over old assumptions. Route truth is in controller headers.
## Current Auth Model
- Registration creates `citizen`.
- Login path:
- OTP email via Mailpit
- Auth token: bearer token from `api_tokens`
- Banned users cannot authenticate.
## Current Report Workflow
### Citizen flow
1. Register/login.
2. `POST /reports` with category, coordinates, address, description, optional media array.
3. Backend first rejects coordinates outside Bari municipal boundary.
4. Backend infers `area_id` by GeoJSON polygon match when possible from existing areas.
5. Report starts `OPEN`, status history row inserted.
6. Citizen can:
- list own reports
- read detail/history/media
- chat on own report
- upload more media up to 5 total
- read notifications
- read rewards
- leave feedback only when report is `RESOLVED`
### Operator flow
1. Read queues:
- `/operator/reports/open`
- `/operator/reports/assigned`
- `/operator/reports/others`
2. Optional `POST /reports/{id}/take`:
`OPEN -> UNDER_REVIEW`, owner becomes operator.
3. `POST /reports/{id}/assignments`:
- if report `OPEN`, operator can assign directly without `take`
- owner becomes operator if report had no owner
- status becomes `ASSIGNED`
- current active assignment closes, new one inserted
4. Continue status flow:
- `ASSIGNED -> IN_PROGRESS -> RESOLVED -> CLOSED`
- rejection path to `REJECTED`, then `CLOSED`
5. Operator can chat with citizen on owned report.
6. Operator can create moderation flags for report/message on owned report.
7. Operator can request team suggestions and generate/revoke public intervention link.
### Admin flow
- Create/update categories, areas, teams
- Area GeoJSON must stay inside Bari municipal boundary
- List users, edit roles, ban/unban
- Read stats
- Review moderation queue and resolve/dismiss flags
- Optionally reject report during moderation resolution
## Team Model
- `teams` are external intervention squads, not platform users.
- `assignments` is history of which external team was assigned.
- `report_category_team_categories` maps report categories to compatible team categories.
- `GET /reports/{id}/team-suggestions` returns recommended active teams by:
- mapped team category
- same area first
- area-less team as fallback
- `POST /reports/{id}/intervention-link` creates revocable public link.
- `GET /interventions/{token}` returns public summary for field team:
report data, location, media, assigned team, masked citizen identity, phone.
## Spatial Boundary Rule
- `allowed_boundaries` stores active municipal allowed area.
- Current seed uses `BARI`.
- Report coordinates outside boundary are rejected.
- Admin area polygons outside boundary are rejected.
- Open data output is filtered again by same boundary.
## Current Notifications / Rewards / Moderation
- Notifications: local in-app only.
- Reward points: awarded once per `(report_id, reason)`.
- Moderation:
- operator creates flag
- admin resolves/dismisses
- admin may reject report during moderation decision
## Important Behavioral Truths
- Owner on platform is always `reports.assigned_operator_id`, not team.
- Feedback does not auto-close report.
- Public areas list is anonymous.
- Report categories require auth.
- Team list requires operator/admin auth.
- Moderation approval is admin-only.
- Public intervention token invalid/revoked/scoped-out returns `404`.
## Files To Read First
- `docs/API_SPEC.md`
- `docs/ARCHITECTURE.md`
- `docs/openapi/visione.openapi.yaml`
- `controllers/*.h`
- `services/*.cc`
- `migrations/*.sql`
## External References
- Local Drogon source: `/home/gabdevele/Projects/snitchitaly/backend/drogon`
- Drogon docs: `https://drogonframework.github.io/drogon-docs/`
- Durable agent instructions: `AGENTS.md`