feat: update API documentation and project specifications

This commit is contained in:
gabdevele
2026-06-15 12:01:34 +02:00 Unverified
parent 170fadbfe0
commit 088a2ed866
9 changed files with 547 additions and 257 deletions
+97 -25
View File
@@ -1,31 +1,103 @@
# Visione Database Schema
The schema is stored in ordered SQL migrations under `migrations/`.
Schema truth is `migrations/*.sql`. This file is compact human map of current DB.
Persistence currently uses `drogon::orm::DbClient` with raw parameterized SQL.
The project does not use Drogon generated models or `Mapper<T>` while the schema
is still evolving.
## Migration Set
- `001_initial_schema.sql`
base auth, users, reports, areas, teams, messages, feedback, rewards
- `004_report_workflow.sql`
`reports.assigned_operator_id`, workflow indexes, richer media columns
- `006_completion_features.sql`
notifications, moderation flags, reward uniqueness
- `007_reference_data_and_intervention_links.sql`
category-to-team-category mapping, public intervention links
Important tables:
## Core Auth Tables
- `users`
identity, profile, password hash, points, `banned`, `must_change_password`
- `roles`
- `permissions`
- `role_permissions`
- `user_roles`
- `otp_challenges`
OTP flow, hashed codes, expiry, consumption
- `api_tokens`
bearer token hashes, expiry, revocation
- `users`: identity, personal data, password hash, points and moderation flags.
- `roles`, `permissions`, `role_permissions`, `user_roles`: authorization.
- `otp_challenges`: local OTP login flow.
- `api_tokens`: bearer tokens for the local API.
- `report_categories`: report classification.
- `areas`: named city areas with GeoJSON polygon boundaries.
- `team_categories`, `teams`: municipal intervention teams.
- `reports`: citizen reports with coordinates, address, status, area and assigned operator.
- `report_status_history`: immutable status transition log.
- `assignments`: report-to-team assignment history.
- `report_photos`: uploaded report media URL, original filename, content type,
media kind and size. The table name is historical; rows can be images or videos.
- `messages`: citizen/operator report conversation.
- `feedback`: citizen rating and comment after resolution.
- `reward_events`: indirect gamification points ledger.
- `notifications`: local in-app notifications for status changes, messages and
reward events.
- `moderation_flags`: report/message review queue for abusive or invalid content.
## Reference Data
- `report_categories`
citizen-facing report categories, `active`
- `areas`
named municipal areas, GeoJSON polygon in `boundary_geojson`, `active`
- `team_categories`
category of external intervention team
- `teams`
external teams, optional `area_id`, `team_category_id`, `active`
- `report_category_team_categories`
explicit compatibility mapping:
report category -> team category
GeoJSON is intentionally used instead of MySQL Spatial in milestone 1 to keep
the local setup simple and portable.
## Report Domain
- `reports`
owner citizen, category, inferred area, coordinates, address, description,
status, `assigned_operator_id`
- `report_status_history`
immutable workflow log
- `assignments`
historical report -> external team assignments, active row has `ended_at IS NULL`
- `report_photos`
historical name; stores both images and videos
current columns include `original_filename`, `content_type`, `media_kind`,
`size_bytes`
- `messages`
citizen/operator conversation per report
- `feedback`
one row per report, unique on `report_id`
## Engagement / Moderation
- `reward_events`
points ledger, unique `(report_id, reason)`
- `notifications`
local in-app notifications
- `moderation_flags`
operator-created flags, admin-resolved moderation queue
- `intervention_access_links`
public revocable hashed links for external teams, tied to `report_id` and
`assignment_id`
## Ownership Model
- Platform owner of report: `reports.assigned_operator_id`
- External team linkage: `assignments`
- Public field-team access: `intervention_access_links`
## Status Model
`reports.status` enum:
- `OPEN`
- `UNDER_REVIEW`
- `ASSIGNED`
- `IN_PROGRESS`
- `RESOLVED`
- `REJECTED`
- `CLOSED`
## Important Constraints / Semantics
- `users.email` unique
- `users.fiscal_code` unique
- `teams.name` unique
- `areas.name` unique
- `report_categories.name` unique
- `feedback.report_id` unique
- `reward_events(report_id, reason)` unique
- `api_tokens.token_hash` unique
- `intervention_access_links.token_hash` unique
## Current Query Model
- No generated ORM models
- No `Mapper<T>`
- Raw parameterized SQL through `drogon::orm::DbClient`
- JSON serialization helpers in `repositories/Sql.*`
## Current Gaps
- No dedicated table for external team personnel
- No route-optimization/routing tables
- No audit table for intervention link access beyond `last_accessed_at`