feat: update API documentation and project specifications
This commit is contained in:
+97
-25
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user