Aller au contenu principal

docDevs.page.eyebrow

logo du site

docDevs.page.subtitle

docDevs.page.metaHighlight

Objectif et contexte du projet

Lexikongo est une application Nuxt (SSR) conçue pour promouvoir et préserver la langue Kikongo, avec des fonctionnalités collaboratives permettant aux utilisateurs de soumettre, valider et consulter des mots et verbes en Kikongo, avec des traductions en français et anglais.

L’application est construite pour être évolutive : ajout de nouvelles langues, gestion fine des rôles utilisateurs, historisation des contributions et intégration potentielle avec des systèmes externes (auth centralisée, paiements de soutien, etc.). Le schéma de base de données existant est conservé et enrichi pour éviter toute régression.

Architecture de la base de données (MySQL)

Vue d’ensemble des principales tables utilisées par Lexikongo.

Utilisateurs & rôles

  • users : informations compte (user_id, username, email, password hashé, dates, vérification e-mail…).
  • roles + éventuelle table de jointure (selon version) pour associer les rôles (user, contributor, admin) à chaque utilisateur.

Mots & verbes validés

  • words : mots validés (word_id, singular, plural, class_id, phonetic, derived_word, liens vers mots/verbres dérivants, is_approved, user_id auteur, etc.).
  • verbs : verbes validés (verb_id, name (infinitif), root, suffix, phonetic, active_verb, derived_verb, derived_from, derived_verb_type_id, is_approved, user_id…).
  • word_meanings / verb_meanings : traductions associées via word_id ou verb_id avec language_code (fr, en, …) et meaning.

Soumissions en attente

  • pending_words_submissions / pending_verbs_submissions : données envoyées par les contributeurs avant validation (statut, phonétique, classe, radical, suffixe…).
  • pending_words_translations / pending_verbs_translations : traductions liées aux soumissions via submission_id.
  • pending_words_slugs / pending_verbs_slugs : slugs temporaires générés côté pending avant bascule dans les tables finales.

Slugs & archivage

  • slugs : table unifiée pour les slugs “publics” avec slug_id, slug (unique), word_id ou verb_id et content_type ('word' ou 'verb').
  • archived_submitted_words / archived_submitted_verbs : archivage des soumissions (statut approved/rejected, admin, raison, lien vers l’ID final quand approuvé). Utilisé pour garder un historique sur une durée limitée.
  • languages : langues de traduction (language_id, language_code, language_name).
  • nominal_classes et derived_verb_types : métadonnées linguistiques (classes nominales, types de verbes).

Gestion des rôles et permissions

Lexikongo s’appuie sur des rôles explicites pour contrôler l’accès aux fonctionnalités critiques (modération, admin, etc.) :

  • Utilisateur (user) : accès en lecture seule au dictionnaire public (mots & verbes approuvés). Peut gérer son profil.
  • Contributeur (contributor) : peut soumettre des mots et des verbes. Les données vont dans les tables pending_*_submissions et sont visibles côté admin pour validation.
  • Administrateur (admin) : accès à l’espace admin, validation/rejet des soumissions, archivage, corrections directes dans les tables principales, parfois gestion des utilisateurs.

Côté code, les routes Nitro (server/api/*) vérifient le rôle en se basant sur le JWT décodé (stocké dans un cookie HttpOnly) et appliquent les gardes nécessaires (par ex. autoriser seulement admin sur les endpoints de modération).

API et endpoints (Nitro)

L’API est organisée par ressource dans server/api/…, avec contrôle d’accès via JWT.

Soumission

  • POST /api/contributor/submit-word (exemple) : soumettre un mot → insertion dans pending_words_submissions + pending_words_translations + pending_words_slugs.
  • POST /api/contributor/submit-verb : soumettre un verbe avec name, root, suffix, phonetic, traductions, etc.

Modération

  • POST /api/admin/manage-submissions : endpoint central pour approuver / rejeter / supprimer une soumission. Déclenche :
    • création du mot / verbe final ;
    • transfert des traductions ;
    • création du slug dans slugs ;
    • archivage dans archived_submitted_* ;
    • suppression des tables pending.

Traductions & slugs

  • PUT /api/admin/word/[slug], PUT /api/admin/verb/[slug] : mise à jour d’un mot/verbe validé (surface, traductions, phonétique…).
  • GET /api/words, GET /api/verbs : recherche et listing côté public avec pagination, filtres, etc.
  • Génération de slug unifié : utilitaires internes pour s’assurer de l’unicité dans slugs en fonction de content_type.

Auth & session

  • POST /api/auth/login : authentification, génération de JWT et placement en cookie HttpOnly/SameSite.
  • GET /api/auth/me : renvoie le profil courant + rôles à partir du JWT.

Exemple de flux : validation d’un verbe

Simplification du flux appliqué dans l’endpoint d’admin lors d’un approve.

async function approvePendingVerb(connection, submission_id, admin_id) {
  // 1. Charger la soumission et ses traductions
  const submission = await fetchPendingVerbWithTranslations(connection, submission_id);

  // 2. Créer le verbe officiel
  const [resVerb] = await connection.execute(`
    INSERT INTO verbs (name, root, suffix, phonetic, active_verb,
                       derived_verb, derived_from, is_approved, user_id,
                       derived_verb_type_id)
    VALUES (?, ?, ?, ?, ?, ?, ?, 1, ?, ?)
  `, [
    submission.name,
    submission.root,
    submission.suffix ?? null,
    submission.phonetic ?? null,
    submission.active_verb ?? 1,
    submission.derived_verb ?? 0,
    submission.derived_from ?? null,
    submission.user_id ?? null,
    submission.derived_verb_type_id ?? null,
  ]);

  const newVerbId = resVerb.insertId;

  // 3. Transférer les traductions vers verb_meanings
  for (const tr of submission.translations) {
    if (!tr.language_code || !tr.meaning) continue;
    await connection.execute(
      'INSERT INTO verb_meanings (verb_id, language_code, meaning) VALUES (?, ?, ?)',
      [newVerbId, tr.language_code, tr.meaning.trim()]
    );
  }

  // 4. Créer le slug définitif dans la table unifiée "slugs"
  const slug = await ensureUniqueSlugForVerb(connection, submission.slug, newVerbId);

  // 5. Archiver la soumission puis nettoyer les tables pending
  await archiveVerb(connection, submission, 'approved', admin_id, newVerbId, null);
  await deletePendingVerb(connection, submission_id);
}
      

Le principe est identique pour les mots (words / word_meanings) avec l’écriture dans archived_submitted_words.

Outils de développement & déploiement

Lexikongo utilise la toolchain standard Nuxt (Vite). Quelques commandes utiles :

  • npm install : installation des dépendances.
  • npm run dev : serveur de développement local.
  • npm run build : build de production (SSR).
  • npm run preview (selon config) : prévisualisation locale du build.

Le déploiement actuel cible un environnement compatible Nuxt SSR (par exemple Vercel, avec adaptation du fichier de config). Les scripts de migration et d’évolution de schéma MySQL doivent être versionnés et appliqués de manière maîtrisée.

Workflow Git & mises à jour

Pour collaborer proprement sur Lexikongo, un workflow Git classique est recommandé :

  • création de branches de fonctionnalités (feature/*),
  • pull requests avec revue de code,
  • tests manuels (et automatisés quand disponibles) avant merge,
  • journalisation des changements dans un fichier CHANGELOG ou équivalent.

Les modifications sensibles (auth, rôles, migrations DB) doivent être testées sur un environnement de pré-production avant la mise en ligne.