LogoKalli
Server

Server Functioning & Core Logic

Fonctionnement & logique principale

  • Serveur HTTP: Hono, RPC via ORPC, sessions via Better Auth.
  • Flux: Requête Web → CORS/Logger → Auth (si /api/auth/**) → ORPC /rpc/* → REST endpoints → Handlers.
  • Données: PostgreSQL via Drizzle (schemas auth et naivi).

Initialisation au démarrage

apps/server/src/index.ts exécute ensureDefaultRoles() au démarrage: crée les rôles admin (isSuperAdmin: true) et user (isSuperAdmin: false) s'ils n'existent pas encore dans la table roles.

Points d'entrée

  • apps/server/src/index.ts

    • Middlewares: logger, cors (origines dynamiques + CORS_ORIGIN), credentials: true.
    • Auth Better Auth monté sur POST/GET /api/auth/**auth.handler().
    • ORPC: new RPCHandler(appRouter) monté sur /rpc/* avec createContext().
    • Santé: GET /, GET /health, GET /ready retournent OK.
    • i18n REST: GET /api/i18n — sert les traductions frontend depuis I18N_JSON (env), /app/i18n.json (Docker), ou ../../i18n.json (local).
    • Debug: GET /api/i18n/debug — diagnostique les chemins de fichiers i18n.
  • apps/server/src/lib/context.ts

    • createContext() lit la session: auth.api.getSession({ headers }).
    • Met à jour user.lastConnection quand l'utilisateur est authentifié.
  • apps/server/src/lib/orpc.ts

    • publicProcedure — accessible sans auth.
    • protectedProcedure — exige une session valide, sinon UNAUTHORIZED.
    • adminProcedure — exige role === 'admin', sinon FORBIDDEN.

Routeur RPC

apps/server/src/routers/index.ts agrège:

export const appRouter = {
  healthCheck,  // public
  i18n,         // public — retourne les données i18n depuis le ConfigMap/fichier
  ...authRouter,
  ...naiviRouter,
  ...rolesTagsRouter,
};

Handlers Auth — apps/server/src/routers/auth.ts

ProcédureAccèsDescription
getMepublicRetourne l'utilisateur courant ou null
getAllUsersprotégéListe tous les utilisateurs
getUserNamesprotégéRetourne id+nom de tous les utilisateurs
getUserbyIdadminUtilisateur par ID
getUserbyEmailadminUtilisateur par email
getUserLastConnectionadminDernière connexion d'un utilisateur

Handlers Naivi — apps/server/src/routers/naivi.ts

Fichiers (table unifiée files)

ProcédureAccèsInputDescription
getFilesprotégé{ type: "regular" | "qa" }Liste les fichiers par type avec infos d'assignation
getUserFilesprotégé{ userId, type }Fichiers assignés à un utilisateur
updateFileNameprotégé{ fileId, name, userId }Renomme un fichier (sauvegarde l'ancien nom dans old_name)
updateFileStatusprotégé{ fileId, status, userId }Mise à jour du statut de classification
deleteFileadmin{ fileId, deleterId }Supprime un fichier et ses enfants (cascade)
getFileNameprotégé{ fileId }Retourne le nom d'un fichier
getFileHistoryprotégé{ fileId }Retourne old_name
getFileAssignmentsprotégé{ fileId }Retourne les assignations d'un fichier
assignFileToUsersadmin{ fileId, userIds[], assignedBy }Assigne un fichier à plusieurs utilisateurs
processUploadedFileadmin{ fileContent, fileName, fileType, uploaderId, chunkSize, overlap }Upload + chunking via document-processor microservice
processUploadedQAadmin{ fileContent, fileName, fileType, uploaderId }Upload + parsing CSV Q&A

Chunks

ProcédureAccèsInputDescription
getFileChunksprotégé{ fileId }Chunks d'un fichier, triés par rank
updateChunksCategoryprotégé[{ chunkId, category, userId }]Mise à jour en lot des catégories
updateChunkContentprotégé{ chunkId, content, userId }Modifie le contenu (sauvegarde dans old_content)
deleteChunkprotégé{ chunkId, userId }Supprime un chunk
getChunkCategoryprotégé{ chunkId }Retourne la catégorie d'un chunk
getChunkHistoryprotégé{ chunkId }Retourne old_content
insertChunkprotégé{ fileId, rank, content, category, userId }Insère un chunk à un rang précis
addManualChunkadmin{ content, category, userId }Crée un chunk sans fichier parent
getFileProgressprotégé{ fileId }Progression de classification (chunks)

QA Pairs

ProcédureAccèsInputDescription
getQasFromFileprotégé{ fileId }QA pairs d'un fichier, triés par rank
updateQaPairprotégé{ id, question?, answer?, userId }Modifie question/réponse
updateQaPairCategoryprotégé{ id, category, userId }Catégorie d'une paire
updateQaPairsCategoryprotégé[{ id, category, userId }]Mise à jour en lot des catégories
deleteQaPairprotégé{ id, userId }Supprime une paire
getQaPairHistoryprotégé{ pairId }Retourne old_question + old_answer
insertQAPairprotégé{ fileId, rank, question, answer, category, userId }Insère une paire à un rang précis
addManualQAPairadmin{ question, answer, category, userId }Crée une paire sans fichier parent
getQaFileProgressprotégé{ fileId }Progression de classification (QA pairs)

Divers

ProcédureAccèsDescription
getLogopublicRetourne le logo actif (exclut logo_dark/logo_light), données en base64
regenerateIndexadminAppelle POST ${INDEX_API_URL}/regenerate-index pour régénérer les index FAISS

Handlers Roles & Tags — apps/server/src/routers/roles-tags.ts

Voir la page dédiée server/roles-tags.mdx pour le détail complet. Résumé:

  • Tags CRUD: getAllTags, createTag, updateTag, deleteTag (admin)
  • Roles CRUD: getAllRoles, createRole, updateRole, deleteRole, reorderRoles (admin)
  • Associations role-tag: getRoleTags, getAllRoleTags, getEffectiveRoleTags, setRoleTags (admin)
  • Associations item-tag: getItemTags, getItemTagsBatch (protégé), setItemTags (admin)
  • Gestion rôle utilisateur: getUserRole (protégé), setUserRole (admin)

Utilitaires métiers

FichierResponsabilité
utils/regular-processing.tsUpload fichier → appel document-processor → insertion chunks en DB
utils/qa-processing.tsParsing CSV Q&A → insertion qa_pair en DB
utils/chunk-operations.tsCRUD chunks: catégorie, contenu, suppression, progression
utils/file-operations.tsRenommage fichier, statut de classification, assignations
utils/qa-operations.tsCRUD qa_pair: update question/réponse/catégorie, suppression
utils/manual-operations.tsAjout de chunk/QA pair manuel (sans fichier parent)
utils/document-processor-client.tsClient HTTP vers le microservice document-processor
utils/sanitize.tsSanitisation de texte pour PostgreSQL
utils/user-operations.tsMise à jour lastConnection utilisateur

Extension

  • Nouveau handler ORPC: créez une méthode dans apps/server/src/routers/*.ts, utilisez publicProcedure/protectedProcedure/adminProcedure, exportez via spread dans routers/index.ts.
  • Contexte: ajoutez des infos dans createContext() si vos handlers en ont besoin.
  • Accès DB: passez par apps/server/src/db/index.ts et apps/server/src/db/schema/*.ts pour requêtes typées Drizzle.
  • Erreurs: standardisez via les utilitaires ORPC (ORPCError) pour une gestion uniforme côté Web.