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:
9
documentation/content/docs/_meta.json
Normal file
9
documentation/content/docs/_meta.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"index": "Introduction",
|
||||
"stack": "Stack Technologique",
|
||||
"database": "Modèle de Données",
|
||||
"api": "API & Intégrations",
|
||||
"security": "Sécurité",
|
||||
"compliance": "Conformité (RGPD)",
|
||||
"deployment": "Déploiement & Tests"
|
||||
}
|
||||
21
documentation/content/docs/api.mdx
Normal file
21
documentation/content/docs/api.mdx
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
title: API & Intégrations
|
||||
description: Documentation des API et services tiers
|
||||
---
|
||||
|
||||
## 🔌 API & Intégrations
|
||||
|
||||
### Documentation API
|
||||
|
||||
Documentation MDX.
|
||||
|
||||
### Authentification
|
||||
|
||||
Le système utilise plusieurs méthodes d'authentification sécurisées :
|
||||
- **Sessions (JWT)** : Utilisation de JSON Web Tokens signés pour les sessions utilisateurs via le web. Les sessions sont persistées en base de données (`sessions`) pour permettre la révocation (Logout) et le suivi des appareils connectés.
|
||||
- **API Keys** : Pour les intégrations programmatiques. Les clés sont hachées en base de données (`key_hash`) et associées à un utilisateur. Elles peuvent être nommées et révoquées individuellement.
|
||||
- **Double Authentification (2FA)** : Support natif (TOTP) avec secret chiffré en base de données.
|
||||
|
||||
### Webhooks / Services Externes
|
||||
|
||||
Liste des intégrations tierces.
|
||||
44
documentation/content/docs/compliance.mdx
Normal file
44
documentation/content/docs/compliance.mdx
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Conformité (RGPD & France)
|
||||
description: Mesures prises pour la conformité au RGPD et aux réglementations françaises.
|
||||
---
|
||||
|
||||
## ⚖️ Conformité Réglementaire
|
||||
|
||||
Le projet Memegoat s'inscrit dans une démarche de respect de la vie privée et de protection des données à caractère personnel, conformément au **Règlement Général sur la Protection des Données (RGPD)** de l'Union Européenne et aux recommandations de la **CNIL**.
|
||||
|
||||
### 🛡️ Principes Fondamentaux
|
||||
|
||||
- **Minimisation des données** : Seules les données strictement nécessaires au fonctionnement du service sont collectées.
|
||||
- **Transparence** : Les utilisateurs sont informés de la finalité des traitements de leurs données.
|
||||
- **Sécurité** : Mise en œuvre de mesures techniques et organisationnelles pour protéger les données.
|
||||
|
||||
### 🔒 Mesures Techniques de Protection
|
||||
|
||||
Conformément à la section [Sécurité](/docs/security), les mesures suivantes sont appliquées :
|
||||
- **Chiffrement au repos** : Utilisation de **PGP (pgcrypto)** pour les données identifiantes.
|
||||
- **Hachage aveugle** : Pour permettre les opérations sur données chiffrées sans compromettre la confidentialité.
|
||||
- **Hachage des mots de passe** : Utilisation de l'algorithme **Argon2id**.
|
||||
- **Communications sécurisées** : Utilisation de **TLS 1.3** via Caddy.
|
||||
|
||||
### 👤 Droits des Utilisateurs
|
||||
|
||||
Conformément au RGPD, les utilisateurs disposent des droits suivants, facilités par l'architecture technique :
|
||||
- **Droit à l'effacement (droit à l'oubli)** : Mis en œuvre via un mécanisme de **Soft Delete** (`deleted_at`), suivi d'une purge définitive des données après un délai de conservation légal.
|
||||
- **Droit d'accès et portabilité** : L'utilisation de schémas structurés (Drizzle/PostgreSQL) permet l'extraction facile des données d'un utilisateur sur demande.
|
||||
- **Gestion du consentement** : Suivi rigoureux des versions de CGU et de politique de confidentialité acceptées (`terms_version`, `privacy_version`, `gdpr_accepted_at`).
|
||||
|
||||
### ⏳ Conservation et Purge
|
||||
|
||||
- **Purge Automatique** : Les données liées aux signalements (`reports`) disposent d'une date d'expiration (`expires_at`) pour garantir qu'elles ne sont pas conservées au-delà du nécessaire.
|
||||
- **Anonymisation technique** : Les adresses IP stockées dans les tables `audit_logs` et `sessions` sont hachées (`ip_hash`), ce qui permet d'identifier des comportements malveillants tout en protégeant l'identité réelle de l'utilisateur.
|
||||
- **Logs d'Audit** : Les journaux d'audit sont conservés pendant une période glissante pour répondre aux obligations de sécurité tout en respectant la minimisation.
|
||||
|
||||
### 📍 Hébergement des Données
|
||||
|
||||
Les données sont hébergées au sein de l'Union Européenne sur des serveurs dédiés chez **Hetzner**, garantissant un cadre juridique protecteur pour les données des citoyens européens.
|
||||
|
||||
### 🔗 Références
|
||||
|
||||
- [Site officiel de la CNIL](https://www.cnil.fr/fr/reglement-europeen-protection-donnees)
|
||||
- [Texte officiel du RGPD](https://eur-lex.europa.eu/legal-content/FR/TXT/?uri=CELEX%3A32016R0679)
|
||||
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.
|
||||
18
documentation/content/docs/deployment.mdx
Normal file
18
documentation/content/docs/deployment.mdx
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Déploiement & Tests
|
||||
description: Procédures de déploiement et stratégie de tests
|
||||
---
|
||||
|
||||
## 🚀 Déploiement
|
||||
|
||||
### Architecture de service
|
||||
|
||||
Un conteneur **Caddy** est utilisé en tant que reverse proxy pour fournir le TLS et la gestion du FQDN.
|
||||
|
||||
### Pré-requis
|
||||
|
||||
Liste des outils nécessaires (Node.js, pnpm, Docker).
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
- **Unitaires** : sur le backend
|
||||
@@ -1,13 +1,42 @@
|
||||
---
|
||||
title: Hello World
|
||||
description: Your first document
|
||||
title: Introduction
|
||||
description: Détails techniques du projet Memegoat
|
||||
---
|
||||
|
||||
Welcome to the docs! You can start writing documents in `/content/docs`.
|
||||
# 🐐 Détails Techniques - Memegoat
|
||||
|
||||
## What is Next?
|
||||
Ce document regroupe l'ensemble des spécifications techniques du projet Memegoat.
|
||||
|
||||
<Cards>
|
||||
<Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
|
||||
<Card title="Learn more about Fumadocs" href="https://fumadocs.dev" />
|
||||
</Cards>
|
||||
## 🏗️ Architecture Globale
|
||||
|
||||
### Vue d'ensemble
|
||||
|
||||
Description de l'architecture en monorepo et des interactions entre les services.
|
||||
|
||||
### Diagrammes
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
User([Utilisateur])
|
||||
Caddy[Reverse Proxy: Caddy]
|
||||
Frontend[Frontend: Next.js]
|
||||
Backend[Backend: NestJS]
|
||||
DB[(Database: PostgreSQL)]
|
||||
Storage[Storage: S3 Compatible]
|
||||
|
||||
User <--> Caddy
|
||||
Caddy <--> Frontend
|
||||
Caddy <--> Backend
|
||||
Backend <--> DB
|
||||
Backend <--> Storage
|
||||
```
|
||||
|
||||
### Navigation
|
||||
|
||||
Consultez les différentes sections pour plus de détails :
|
||||
- [Stack Technologique](/docs/stack)
|
||||
- [Modèle de Données](/docs/database)
|
||||
- [Sécurité](/docs/security)
|
||||
- [Conformité RGPD](/docs/compliance)
|
||||
- [API & Intégrations](/docs/api)
|
||||
- [Déploiement](/docs/deployment)
|
||||
|
||||
26
documentation/content/docs/security.mdx
Normal file
26
documentation/content/docs/security.mdx
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Sécurité
|
||||
description: Mesures de sécurité implémentées
|
||||
---
|
||||
|
||||
## 🔐 Sécurité
|
||||
|
||||
### Protection des Données (At Rest)
|
||||
|
||||
- **Chiffrement PGP Natif** : Les données identifiantes (PII) comme l'email, le nom d'affichage et le **secret 2FA** sont chiffrées dans PostgreSQL via `pgcrypto` (`pgp_sym_encrypt`). Les clés de déchiffrement ne sont jamais stockées en base de données.
|
||||
- **Hachage aveugle (Blind Indexing)** : Pour permettre la recherche et l'unicité sur les données chiffrées (comme l'email), un hash non réversible (SHA-256) est stocké séparément (`email_hash`).
|
||||
- **Hachage des mots de passe** : Utilisation d'**Argon2id** (via `@node-rs/argon2`), configuré selon les recommandations de l'ANSSI pour résister aux attaques par force brute et par table de correspondance.
|
||||
|
||||
### Sécurité des Communications (In Transit)
|
||||
|
||||
- **TLS 1.3** : Assuré par le reverse proxy **Caddy** avec renouvellement automatique des certificats Let's Encrypt.
|
||||
- **Protocoles d'Authentification** :
|
||||
- **Sessions (JWT)** : Les jetons de rafraîchissement (`refresh_token`) sont stockés de manière sécurisée en base de données. L'IP de l'utilisateur est hachée (`ip_hash`) pour concilier sécurité et respect de la vie privée.
|
||||
- **API Keys** : Les clés API sont hachées en base de données (**SHA-256**) via la colonne `key_hash`. Seul un préfixe est conservé en clair pour l'identification.
|
||||
|
||||
### Infrastructure & Défense
|
||||
|
||||
- **Rate Limiting** : Protection contre le brute-force et le déni de service (DoS).
|
||||
- **CORS Policy** : Restriction stricte des origines autorisées.
|
||||
- **RBAC (Role Based Access Control)** : Gestion granulaire des permissions avec une structure complète de rôles et de permissions liées (`roles`, `permissions`, `roles_to_permissions`).
|
||||
- **Audit Logs** : Traçabilité complète des actions sensibles via la table `audit_logs`. Elle enregistre l'action, l'entité concernée, les détails au format JSONB, ainsi que l'IP hachée et le User-Agent pour l'imputabilité.
|
||||
27
documentation/content/docs/stack.mdx
Normal file
27
documentation/content/docs/stack.mdx
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Stack Technologique
|
||||
description: Technologies utilisées dans le projet Memegoat
|
||||
---
|
||||
|
||||
## 🛠️ Stack Technologique
|
||||
|
||||
### Frontend
|
||||
|
||||
- **Framework** : NextJS
|
||||
- **Gestion d'état** : Zustand
|
||||
- **Style** : Tailwind CSS
|
||||
- **Composants UI** : Shadcn/ui
|
||||
|
||||
### Backend
|
||||
|
||||
- **Framework** : NestJS
|
||||
- **Langage** : TypeScript
|
||||
- **Base de données** : PostgresQL
|
||||
- **ORM** : DrizzleORM
|
||||
|
||||
### Infrastructure & DevOps
|
||||
|
||||
- **Conteneurisation** : Docker / Docker Compose
|
||||
- **Reverse Proxy & TLS** : Caddy
|
||||
- **CI/CD** : Gitea Actions
|
||||
- **Hébergement** : Hetzner Dedicated Server
|
||||
Reference in New Issue
Block a user