LogoKalli
Database

Schéma & rôles des tables

Schéma & rôles des tables

Le schéma PostgreSQL est défini via Drizzle ORM. Les fichiers de référence sont:

  • apps/server/src/db/schema/auth.ts — tables Better Auth
  • apps/server/src/db/schema/naivi.ts — tables métier nAI'vi

Le DDL complet se trouve dans server/database.mdx.

Organisation

Deux groupes de tables coexistent dans la même base PostgreSQL:

DB naivi
├── [auth]         user, session, account, verification
└── [naivi]        files, chunks, qa_pair, file_assignments, logo,
                   tags, roles, role_tags, item_tags, indexes, index_chunks

Tables Auth

Gérées automatiquement par Better Auth (via Drizzle adapter). Ne pas modifier directement.

TableRôle
userComptes utilisateurs (id, email, role Better Auth, lastConnection)
sessionSessions actives (token JWT, expiration, user_id)
accountComptes OAuth liés (provider_id, access_token, refresh_token)
verificationTokens de vérification email et reset password

Tables Naivi — Métier

files

Table unifiée (remplace les anciennes regular_files + qa_files).

ColonneTypeDescription
iduuid PKIdentifiant unique
nametextNom courant du fichier
old_nametextNom précédent (avant renommage)
typeenum file_typeregular = document chunké; qa = CSV Q&A
created_bytext → user.idUploadeur
classification_statusenumpending / in_progress / completed
created_attimestamptzDate de création
last_updated_attimestamptzDernière modification
last_updated_bytext → user.idDernier modificateur

chunks

Segments de texte extraits d'un fichier regular.

ColonneTypeDescription
iduuid PK
rankintegerPosition du chunk dans le fichier
contenttextContenu textuel du chunk
old_contenttextContenu avant dernière modification
categoryenum categorydynamic, static, not an info, finetuned, not categorized
file_iduuid → files.id CASCADEFichier parent
embeddingbyteaVecteur embedding sérialisé (float32, calculé par le chatbot)
last_updated_attimestamptz
last_updated_bytext → user.id

qa_pair

Paires question/réponse issues d'un fichier qa (CSV).

ColonneTypeDescription
iduuid PK
file_iduuid → files.id CASCADEFichier parent
rankintegerPosition dans le fichier
questiontextQuestion
old_questiontextQuestion avant modification
answertextRéponse
old_answertextRéponse avant modification
categoryenum categorydefault: not categorized
embeddingbyteaEmbedding de "question : answer"
last_updated_attimestamptz
last_updated_bytext → user.id

file_assignments

Association fichier ↔ utilisateur (contrôle d'accès au niveau fichier).

ColonneTypeDescription
file_iduuid → files.id CASCADE
assigned_totext → user.idUtilisateur cible
assigned_bytext → user.idAdmin qui a assigné
UNIQUE(file_id, assigned_to)Un fichier assigné une seule fois par user

Logos du bot (branding, chargés par le chatbot au démarrage).

ColonneTypeDescription
nametextNom du logo (logo, logo_dark, logo_light…)
databyteaDonnées binaires de l'image
mime_typetextType MIME (image/png, image/svg+xml…)
is_activebooleantrue = logo actuellement utilisé

tags

Étiquettes pour catégoriser les chunks/qa_pairs selon leur audience.

ColonneTypeDescription
nametext UNIQUENom du tag (ex: RH, Juridique)
colortextCouleur hexadécimale (ex: #6366f1)
descriptiontextDescription optionnelle

roles

Rôles applicatifs (distincts des rôles Better Auth). Utilisés pour le filtrage des index FAISS.

ColonneTypeDescription
nametext UNIQUENom du rôle (ex: responsable_rh)
display_orderintegerOrdre de priorité (0 = super admin)
is_super_adminbooleanAccès à tous les tags si true

role_tags

Association rôle ↔ tag. Détermine les tags visibles par un rôle.

ColonneTypeContrainte
role_iduuid → roles.id CASCADE
tag_iduuid → tags.id CASCADE
UNIQUE(role_id, tag_id)

item_tags

Association chunk/qa_pair ↔ tag.

ColonneTypeDescription
item_iduuidID du chunk ou qa_pair (sans FK explicite)
item_typeenum item_typechunk ou qa_pair
tag_iduuid → tags.id CASCADE
UNIQUE(item_id, item_type, tag_id)

indexes

Index FAISS sérialisés, un par rôle applicatif.

ColonneTypeDescription
serialized_indexbyteaIndex FAISS sérialisé (pickle)
role_iduuid → roles.id SET NULLRôle propriétaire de cet index
is_activebooleantrue = index le plus récent pour ce rôle

index_chunks

Mapping index ↔ chunks inclus (chunks + qa_pairs).

ColonneTypeDescription
index_iduuid → indexes.id CASCADEIndex FAISS parent
chunk_iduuidID du chunk ou qa_pair (sans FK explicite)
UNIQUE(index_id, chunk_id)

Relations clés

user ──< file_assignments >── files ──< chunks
                                    └──< qa_pair
files ──< chunks >── item_tags >── tags
files ──< qa_pair >── item_tags >── tags
roles >── role_tags >── tags
roles ──< indexes ──< index_chunks

Migrations

# Générer une nouvelle migration après modification du schéma
cd apps/server
bun run db:generate

# Appliquer les migrations
bun run db:migrate

Les fichiers de migration sont générés dans apps/server/drizzle/.

Enums PostgreSQL

EnumValeurs
file_typeregular, qa
classification_statuspending, in_progress, completed
categorydynamic, static, not an info, finetuned, not categorized
item_typechunk, qa_pair