feat(docs): add comprehensive technical documentation for Memegoat
Includes detailed sections on architecture, stack, data model, security measures, deployment procedures, compliance (GDPR), and API integrations.
This commit is contained in:
257
documentation/content/docs/database.mdx
Normal file
257
documentation/content/docs/database.mdx
Normal file
@@ -0,0 +1,257 @@
|
||||
---
|
||||
title: Modèle de Données
|
||||
description: Structure et organisation des données
|
||||
---
|
||||
|
||||
## 📊 Modèle de Données
|
||||
|
||||
### Conceptuel (MCD)
|
||||
|
||||
Le Modèle Conceptuel de Données décrit les grandes entités du système et leurs relations métier, incluant la gestion des accès et la modération.
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
USER ||--o{ CONTENT : "publie"
|
||||
USER ||--o{ REPORT : "signale"
|
||||
USER ||--o{ USER_ROLE : "possede"
|
||||
USER ||--o{ SESSION : "detient"
|
||||
USER ||--o{ API_KEY : "genere"
|
||||
USER ||--o{ AUDIT_LOG : "genere"
|
||||
|
||||
CONTENT ||--o{ CONTENT_TAG : "possede"
|
||||
TAG ||--o{ CONTENT_TAG : "est_lie_a"
|
||||
CONTENT ||--o{ REPORT : "est_signale"
|
||||
TAG ||--o{ REPORT : "est_signale"
|
||||
|
||||
ROLE ||--o{ USER_ROLE : "attribue_a"
|
||||
ROLE ||--o{ ROLE_PERMISSION : "possede"
|
||||
PERMISSION ||--o{ ROLE_PERMISSION : "est_lie_a"
|
||||
|
||||
USER {
|
||||
string username
|
||||
string email
|
||||
string display_name
|
||||
string status
|
||||
}
|
||||
CONTENT {
|
||||
string title
|
||||
string type
|
||||
string storage_key
|
||||
}
|
||||
TAG {
|
||||
string name
|
||||
string slug
|
||||
}
|
||||
ROLE {
|
||||
string name
|
||||
string slug
|
||||
}
|
||||
REPORT {
|
||||
string reason
|
||||
string status
|
||||
}
|
||||
SESSION {
|
||||
string refresh_token
|
||||
boolean is_valid
|
||||
}
|
||||
API_KEY {
|
||||
string name
|
||||
string prefix
|
||||
boolean is_active
|
||||
}
|
||||
AUDIT_LOG {
|
||||
string action
|
||||
string entity_type
|
||||
jsonb details
|
||||
}
|
||||
```
|
||||
|
||||
### Logique (MLD)
|
||||
|
||||
Le Modèle Logique de Données précise les tables, les colonnes et les clés étrangères (FK).
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
users {
|
||||
uuid uuid PK
|
||||
varchar username
|
||||
bytea email
|
||||
varchar email_hash
|
||||
varchar display_name
|
||||
varchar password_hash
|
||||
user_status status
|
||||
bytea two_factor_secret
|
||||
boolean is_two_factor_enabled
|
||||
varchar terms_version
|
||||
varchar privacy_version
|
||||
timestamp gdpr_accepted_at
|
||||
timestamp last_login_at
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
timestamp deleted_at
|
||||
}
|
||||
contents {
|
||||
uuid id PK
|
||||
uuid user_id FK
|
||||
content_type type
|
||||
varchar title
|
||||
varchar storage_key
|
||||
varchar mime_type
|
||||
integer file_size
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
timestamp deleted_at
|
||||
}
|
||||
tags {
|
||||
uuid id PK
|
||||
varchar name
|
||||
varchar slug
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
}
|
||||
contents_to_tags {
|
||||
uuid content_id PK, FK
|
||||
uuid tag_id PK, FK
|
||||
}
|
||||
roles {
|
||||
uuid id PK
|
||||
varchar name
|
||||
varchar slug
|
||||
varchar description
|
||||
timestamp created_at
|
||||
}
|
||||
permissions {
|
||||
uuid id PK
|
||||
varchar name
|
||||
varchar slug
|
||||
varchar description
|
||||
timestamp created_at
|
||||
}
|
||||
roles_to_permissions {
|
||||
uuid role_id PK, FK
|
||||
uuid permission_id PK, FK
|
||||
}
|
||||
users_to_roles {
|
||||
uuid user_id PK, FK
|
||||
uuid role_id PK, FK
|
||||
}
|
||||
reports {
|
||||
uuid id PK
|
||||
uuid reporter_id FK
|
||||
uuid content_id FK
|
||||
uuid tag_id FK
|
||||
report_reason reason
|
||||
text description
|
||||
report_status status
|
||||
timestamp expires_at
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
}
|
||||
sessions {
|
||||
uuid id PK
|
||||
uuid user_id FK
|
||||
varchar refresh_token
|
||||
varchar user_agent
|
||||
varchar ip_hash
|
||||
boolean is_valid
|
||||
timestamp expires_at
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
}
|
||||
api_keys {
|
||||
uuid id PK
|
||||
uuid user_id FK
|
||||
varchar key_hash
|
||||
varchar name
|
||||
varchar prefix
|
||||
boolean is_active
|
||||
timestamp last_used_at
|
||||
timestamp expires_at
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
}
|
||||
audit_logs {
|
||||
uuid id PK
|
||||
uuid user_id FK
|
||||
varchar action
|
||||
varchar entity_type
|
||||
uuid entity_id
|
||||
jsonb details
|
||||
varchar ip_hash
|
||||
varchar user_agent
|
||||
timestamp created_at
|
||||
}
|
||||
|
||||
users ||--o{ contents : "user_id"
|
||||
users ||--o{ users_to_roles : "user_id"
|
||||
roles ||--o{ users_to_roles : "role_id"
|
||||
roles ||--o{ roles_to_permissions : "role_id"
|
||||
permissions ||--o{ roles_to_permissions : "permission_id"
|
||||
contents ||--o{ contents_to_tags : "content_id"
|
||||
tags ||--o{ contents_to_tags : "tag_id"
|
||||
users ||--o{ reports : "reporter_id"
|
||||
contents ||--o{ reports : "content_id"
|
||||
tags ||--o{ reports : "tag_id"
|
||||
users ||--o{ sessions : "user_id"
|
||||
users ||--o{ api_keys : "user_id"
|
||||
users ||--o{ audit_logs : "user_id"
|
||||
```
|
||||
|
||||
### Physique (MPD)
|
||||
|
||||
Le Modèle Physique de Données détaille l'implémentation spécifique pour **PostgreSQL**.
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
users {
|
||||
uuid uuid "DEFAULT gen_random_uuid()"
|
||||
bytea email "ENCRYPTED, NOT NULL"
|
||||
varchar email_hash "UNIQUE, INDEXED"
|
||||
varchar username "UNIQUE, NOT NULL"
|
||||
varchar password_hash "NOT NULL"
|
||||
bytea two_factor_secret "ENCRYPTED"
|
||||
boolean is_two_factor_enabled "DEFAULT false"
|
||||
timestamp gdpr_accepted_at "NULLABLE"
|
||||
timestamp deleted_at "SOFT DELETE"
|
||||
}
|
||||
contents {
|
||||
uuid id "DEFAULT gen_random_uuid()"
|
||||
uuid user_id "REFERENCES users(uuid)"
|
||||
varchar storage_key "UNIQUE, NOT NULL"
|
||||
integer file_size "NOT NULL"
|
||||
timestamp deleted_at "SOFT DELETE"
|
||||
}
|
||||
reports {
|
||||
uuid id "DEFAULT gen_random_uuid()"
|
||||
uuid reporter_id "REFERENCES users(uuid)"
|
||||
timestamp expires_at "RGPD PURGE"
|
||||
}
|
||||
api_keys {
|
||||
uuid id "DEFAULT gen_random_uuid()"
|
||||
varchar key_hash "UNIQUE, INDEXED, SHA-256"
|
||||
varchar prefix "NOT NULL"
|
||||
}
|
||||
audit_logs {
|
||||
uuid id "DEFAULT gen_random_uuid()"
|
||||
jsonb details "STORED AS JSONB"
|
||||
varchar ip_hash "RGPD COMPLIANT"
|
||||
}
|
||||
sessions {
|
||||
uuid id "DEFAULT gen_random_uuid()"
|
||||
varchar refresh_token "UNIQUE, NOT NULL"
|
||||
varchar ip_hash "RGPD COMPLIANT"
|
||||
}
|
||||
```
|
||||
|
||||
#### Sécurité et Chiffrement
|
||||
- **Chiffrement PGP (Native)** : Les colonnes `email` et `two_factor_secret` sont stockées au format `bytea` et chiffrées/déchiffrées via les fonctions `pgp_sym_encrypt` et `pgp_sym_decrypt` de PostgreSQL (via l'extension `pgcrypto`).
|
||||
- **Hachage aveugle (Blind Indexing)** : La colonne `email_hash` stocke un hash (SHA-256) de l'email pour permettre les recherches d'unicité et les recherches rapides sans déchiffrer la donnée.
|
||||
|
||||
#### Index et Optimisations
|
||||
- **Index B-Tree** systématiques sur toutes les clés étrangères (`user_id`, `role_id`, etc.).
|
||||
- **Index sur `deleted_at`** : Pour optimiser les requêtes excluant les données supprimées logiciellement.
|
||||
- **Index unique sur `email_hash`** et `username`.
|
||||
|
||||
#### Conformité RGPD
|
||||
- **Soft Delete** : Implémenté via `deleted_at` pour permettre le "droit à l'oubli" tout en conservant l'intégrité référentielle temporaire.
|
||||
- **Purge Automatique** : La colonne `expires_at` dans la table `reports` permet de programmer la suppression automatique des données de signalement après traitement.
|
||||
Reference in New Issue
Block a user