Modèle de données¶
Schéma complet : sql/carbure.sql (MariaDB/MySQL, InnoDB, utf8mb4). Les évolutions
d'une base existante sont dans sql/migrations/ et appliquées par Migrator (voir
Migrations).
erDiagram
users ||--o{ devices : "possède"
users ||--o{ api_tokens : "possède"
users ||--o{ bank_account : "a ajouté"
users ||--o{ bank_transaction : "rattachement"
bank_transaction_category ||--o{ bank_transaction : "catégorise"
bank_transaction_category ||--o{ bank_transaction_category : "parent"
bank_transaction_category ||--o{ bank_transaction_category_keyword : "mots-clés"
bank_transaction_category ||--o{ budget : "budgétée"
users {
int id PK
varchar username UK
varchar password "bcrypt"
varchar firstname
varchar lastname
varchar email UK
tinyint is_admin
varchar language "fr ou en"
decimal alert_threshold "seuil d'alerte, NULL = désactivé"
datetime last_login
tinyint failed_logins
datetime locked_until "NULL = non bloqué"
}
devices {
int id PK
int user_id FK
varchar name
varchar token UK "token APNs"
timestamp lastLogin
}
api_tokens {
int id PK
int user_id FK
varchar name
char token_hash UK "SHA-256"
varchar token_hint
timestamp created_at
datetime last_used_at
datetime expires_at "NULL = sans expiration"
}
bank_account {
int id PK
varchar bank_name "backend woob"
varchar account_number
int user_id FK "qui l'a ajouté"
datetime last_sync_at
enum last_sync_status "OK, ERROR"
varchar last_sync_message
}
bank_transaction {
bigint id PK
varchar uuid UK "md5(rdate, libellé, montant)"
timestamp imported
date date "indexée"
date rdate "date réelle"
tinyint type
varchar label
tinyint category FK
decimal amount
varchar card
tinyint pointed "vérifiée"
int user FK
}
bank_transaction_category {
tinyint id PK
varchar name UK
tinyint parent_category FK
enum type "DEBIT, CREDIT, HORS-BUDGET"
varchar icon
varchar color
}
bank_transaction_category_keyword {
int id PK
varchar keyword UK
tinyint category FK
}
budget {
bigint id PK
tinyint category FK
decimal amount
date date "1er du mois"
}
budget_insight {
int id PK
varchar name
varchar color
varchar icon
varchar sql "requête avec {month} et {year}"
}
settings {
varchar name PK
varchar value
}
schema_migrations {
varchar version PK
timestamp applied_at
}
Tables¶
| Table | Rôle |
|---|---|
users |
Comptes. is_admin donne le profil administrateur ; language la langue du portail ; alert_threshold le montant à partir duquel une nouvelle dépense déclenche une notification (NULL = désactivé) ; last_login la dernière connexion réussie ; failed_logins les échecs de connexion d'affilée et locked_until la fin du blocage (24 h après 5 échecs). |
devices |
Appareils iOS (token APNs), enregistrés à la connexion. Supprimés avec l'utilisateur. |
api_tokens |
Jetons d'accès des agents IA (serveur MCP) : seule l'empreinte SHA-256 (token_hash) est stockée, token_hint (début du jeton) sert à le reconnaître ; expires_at NULL = sans expiration. Supprimés avec l'utilisateur. |
bank_account |
Comptes bancaires suivis par le foyer : account_number@bank_name forme le bankId passé à woob. user_id est l'utilisateur qui a ajouté le compte (« Ajouté par ») ; last_sync_at, last_sync_status, last_sync_message décrivent la dernière synchronisation. Unicité (account_number, bank_name, user_id) ; l'API refuse en plus un compte déjà suivi par le foyer. |
bank_transaction |
Transactions. uuid unique sert au dédoublonnage ; user = premier utilisateur ayant ajouté le compte (MIN(user_id)), sans effet sur la visibilité ; suppression de l'utilisateur interdite tant qu'il a des transactions (ON DELETE RESTRICT) ; index transaction_date sur date. |
bank_transaction_category |
Catégories hiérarchiques (parent_category, 0 = racine). La catégorie 0 « Non catégorisé » (HORS-BUDGET) est créée par l'installation et protégée. |
bank_transaction_category_keyword |
Règles : mots-clés (en majuscules) recherchés dans les libellés pour catégoriser automatiquement. |
budget |
Budget d'une catégorie pour un mois (unique par catégorie et date), en DECIMAL(10,2). |
budget_insight |
Insights : requête SQL renvoyant une colonne amount, avec les marqueurs {month} et {year} remplacés par des entiers ; icon (icône Material, facultative) et color (13 couleurs). |
settings |
Réglages modifiés depuis le portail (mcp_enabled). |
schema_migrations |
Migrations appliquées et leur date ; créée par sql/carbure.sql (version 2026-10-13_base) ou par Migrator. La version du schéma est la dernière migration enregistrée. |
Migrations¶
Les migrations de la version 1.0 (2026-10-03_audit à 2026-10-13_rule_notify : droits
administrateur, alertes, utf8mb4, statut de synchronisation, jetons d'API, réglages,
dernière connexion, verrouillage, notification des règles) sont intégrées à
sql/carbure.sql et ont été retirées du dépôt. Une base créée depuis sql/carbure.sql a la
version 2026-10-13_base.
Les prochaines migrations iront dans sql/migrations/ avec leur ligne
-- applied-if: <requête>, qui permet de reconnaître une migration déjà appliquée (à la
main, ou par sql/carbure.sql). Voir Développement.
Modèle « foyer »¶
Toutes les données (comptes, transactions, budgets, catégories, insights) sont partagées
par les utilisateurs. bank_account.user_id et bank_transaction.user indiquent qui a
ajouté le compte synchronisé, sans restreindre la visibilité. Seuls les appareils, les
jetons d'accès et les préférences (langue, seuil d'alerte) sont propres à chaque
utilisateur.
Limites connues¶
budget_insightstocke du SQL exécuté par le serveur : il est encadré (administrateurs seulement, mots-clés et tables interdits, transaction en lecture seule), mais des indicateurs définis dans le code seraient plus sûrs. Une requête d'insight écrite avecMONTH(date)/YEAR(date)n'utilise pas l'index sur les dates : préférer un intervalle.