Files
backend/docs/DATABASE_SCHEMA.md
T

108 lines
3.3 KiB
Markdown

# Visione Database Schema
Schema truth is `migrations/*.sql`. This file is compact human map of current DB.
## 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
## 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
## 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
- `allowed_boundaries`
active allowed municipal containment geometry, currently seeded with `BARI`
## 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
- category/team/area delete behavior is soft delete via `active = FALSE`
## 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`
- Containment check for admin area polygons is simple vertex-inside check