LogoKalli
Server

Roles & Tags

Roles & Tags

Le routeur apps/server/src/routers/roles-tags.ts gère le système de rôles applicatifs et de tags utilisé pour le filtrage contextuel des index FAISS. Ce système est distinct des rôles Better Auth (user.role) mais s'y intègre.

Concept général

Tags       → étiquettes attachées aux chunks/qa_pairs
Roles      → groupes d'utilisateurs avec des droits d'accès aux tags
Role-Tags  → association : quel rôle voit quels tags
Item-Tags  → association : quel chunk/qa_pair porte quel tag

Lors de la génération d'un index FAISS, seuls les chunks/qa_pairs ayant des tags accessibles pour le rôle de l'utilisateur sont inclus. Cela permet à chaque rôle de disposer d'un sous-ensemble contextualisé de la base de connaissances.

Héritage de tags (role hierarchy)

La procédure getEffectiveRoleTags retourne les tags effectifs pour un rôle, incluant les tags hérités des rôles dont le display_order est supérieur ou égal. Les rôles avec un display_order plus petit ont plus de priorité (0 = super admin). Un rôle hérite donc des tags des rôles de priorité inférieure.

Initialisation

ensureDefaultRoles() (appelé au démarrage du serveur) crée automatiquement:

  • adminisSuperAdmin: true, displayOrder: 0
  • userisSuperAdmin: false, displayOrder: 1

Procédures Tags

getAllTags — admin

Input: aucun
Output: Tag[] — tous les tags triés par nom.

type Tag = {
  id: string;        // UUID
  name: string;      // Unique, max 50 chars
  description: string | null;
  color: string;     // Hex color, default "#6366f1"
  createdAt: Date;
  createdBy: string | null;
  lastUpdatedAt: Date;
  lastUpdatedBy: string | null;
}

createTag — admin

Input:

{
  name: string;   // min 1, max 50
  color?: string; // regex /^#[0-9a-fA-F]{6}$/, default "#6366f1"
}

Output: Tag — le tag créé.

updateTag — admin

Input:

{
  id: string;      // UUID
  name?: string;   // min 1, max 50
  color?: string;  // regex /^#[0-9a-fA-F]{6}$/
}

Output: Tag — le tag mis à jour.

deleteTag — admin

Input: { id: string } (UUID)
Output: { success: true } — supprime en cascade les associations role_tags et item_tags.


Procédures Roles

getAllRoles — admin

Input: aucun
Output: Role[] — triés par isSuperAdmin DESC, puis displayOrder ASC.

type Role = {
  id: string;
  name: string;
  description: string | null;
  displayOrder: number;
  isSuperAdmin: boolean;
  createdAt: Date;
}

createRole — admin

Input:

{
  name: string;          // min 1, max 50
  isSuperAdmin?: boolean; // default false
}

Output: Role — le rôle créé.

Comportement: si isSuperAdmin: true, tous les rôles existants sont décalés (displayOrder += 1) et le nouveau rôle obtient displayOrder: 0. Sinon, il est placé en fin de liste.

updateRole — admin

Input:

{
  id: string;
  name?: string;
  isSuperAdmin?: boolean;
}

Output: Role — le rôle mis à jour. Si passage à isSuperAdmin: true, les autres rôles sont décalés (transaction).

deleteRole — admin

Input: { id: string } (UUID)
Output: { success: true } — supprime en cascade les role_tags.

reorderRoles — admin

Input: [{ id: string, displayOrder: number }]
Output: { success: true } — met à jour displayOrder pour chaque rôle.


Procédures Role-Tag

getRoleTags — admin

Input: { roleId: string } (UUID)
Output: liste des tags directement associés au rôle.

type RoleTag = {
  id: string;
  roleId: string;
  tagId: string;
  tagName: string;
  tagColor: string;
}

getAllRoleTags — admin

Input: aucun
Output: toutes les associations role-tag (tous rôles confondus).

getEffectiveRoleTags — admin

Input: { roleId: string } (UUID)
Output: tags effectifs (propres + hérités) pour ce rôle.

type EffectiveRoleTag = {
  tagId: string;
  tagName: string;
  tagColor: string;
  roleId: string;
  roleName: string;
  isInherited: boolean;  // true si le tag vient d'un rôle parent
}

Requête SQL: sélectionne les tags des rôles dont display_order >= display_order du rôle cible.

setRoleTags — admin

Input:

{
  roleId: string;
  tagIds: string[]; // UUIDs
}

Output: { success: true } — remplace entièrement les tags du rôle (delete + insert).


Procédures Item-Tag

Les items peuvent être soit des chunk soit des qa_pair.

getItemTags — protégé

Input:

{
  itemId: string;                      // UUID
  itemType: "chunk" | "qa_pair";
}

Output: tags attachés à cet item.

getItemTagsBatch — protégé

Input:

{
  itemIds: string[];                   // UUID[]
  itemType: "chunk" | "qa_pair";
}

Output: tous les tags pour les items demandés (un seul appel DB).

setItemTags — admin

Input:

{
  itemId: string;
  itemType: "chunk" | "qa_pair";
  tagIds: string[];
}

Output: { success: true } — remplace entièrement les tags de l'item.


Procédures User Role

getUserRole — protégé

Input: { userId: string }
Output: le Role correspondant au champ user.role de Better Auth, ou null.

setUserRole — admin

Input:

{
  userId: string;
  roleName: string;  // doit correspondre à un nom dans la table roles
}

Output: { success: true } — met à jour user.role dans la table Better Auth.


Flux de travail type

  1. Admin crée des tags (ex: RH, Juridique, IT).
  2. Admin crée des rôles (ex: responsable_rh, juriste) avec les bons displayOrder.
  3. Admin associe des tags à chaque rôle via setRoleTags.
  4. Admin étiquette les chunks/qa_pairs avec setItemTags.
  5. Admin déclenche la régénération des index via regenerateIndex (un index par rôle est créé dans la table indexes).
  6. Lors d'une question dans le chatbot, le rôle de l'utilisateur est résolu et l'index correspondant est chargé depuis la DB.