Skip to content

Référence API : FAQ et Wiki ​

Gestion des entrées FAQ et des pages Wiki dans une base de connaissances : import, recherche, édition et restauration de versions.

Les deux groupes sont des sous-ressources de contenu KB : lecture — Viewer+ et droit de lecture KB (clé API retrieve/full) ; écriture — « créateur de la KB OU Admin+ » et droit d’écriture KB (clé API ingest/full), sous réserve de la liste blanche KB. La recherche Wiki inter-KB POST /wiki-search n’a pas de KB dans le chemin : Viewer+ et clé API retrieve/full ; le handler vérifie pour chaque KB cible la allow-list et le droit Viewer sur les bases partagées.

FAQ (/api/v1/knowledge-bases/:id/faq) ​

GET /api/v1/knowledge-bases/:id/faq/entries ​

Rôle : Lister les entrées FAQ.

ParamètreTypeObligatoireDescription
page / page_sizeintnonPagination
tag_idintnonAncien seq_id d’étiquette unique
tag_idsstringnonUUID d’étiquettes séparés par des virgules
keywordstringnonMot-clé
search_fieldstringnonstandard_question/similar_questions/answers (tous les champs par défaut)
sort_orderstringnonasc (par défaut tri par date de mise à jour décroissante)
is_enabledboolnonFiltrer par état activé : true uniquement actives, false uniquement désactivées, omis = toutes ; autre valeur → 400

Réponse : 200 {"success":true,"data":{liste paginée FAQEntry}}

bash
curl "$BASE/api/v1/knowledge-bases/kb-1/faq/entries?page=1&is_enabled=false" -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledge-bases/:id/faq/entries/export ​

Rôle : Exporter les FAQ. Paramètre de requête : format (csv par défaut / json).

Réponse : 200 téléchargement de fichier (text/csv ou application/json).

bash
curl -OJ "$BASE/api/v1/knowledge-bases/kb-1/faq/entries/export?format=csv" -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledge-bases/:id/faq/entries/:entry_id ​

Rôle : Détail d’une entrée FAQ (entry_id = seq_id entier).

Réponse : 200 {"success":true,"data":{FAQEntry}}

bash
curl $BASE/api/v1/knowledge-bases/kb-1/faq/entries/12 -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledge-bases/:id/faq/entries ​

Rôle : Upsert / import en lot (tâche asynchrone). Méthode handler UpsertEntries.

ChampTypeObligatoireDescription
entries[]FAQEntryPayloadoui (binding:"required")Entrées en lot
modestringoui (binding:"oneof=append replace")Ajout ou remplacement
knowledge_idstringnonID de l’entité de connaissance FAQ
task_idstringnonID de tâche personnalisé : lettres, chiffres, _, - uniquement, max 128 caractères, sinon 400
dry_runboolnonValidation seule, sans persistance

Réponse : 200 {"success":true,"data":{"task_id"}}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/entries -H "X-API-Key: $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"mode":"append","entries":[{"standard_question":"Comment obtenir un remboursement?","answers":["Contacter le support"]}]}'

POST /api/v1/knowledge-bases/:id/faq/entry ​

Rôle : Créer une entrée FAQ. Corps (types.FAQEntryPayload) :

ChampTypeObligatoireDescription
standard_questionstringoui (binding:"required")Question standard
similar_questions[]stringnonQuestions similaires
negative_questions[]stringnonQuestions négatives (contre-exemples)
answers[]stringnonListe de réponses
answer_strategystringnonall / random
tag_idint64nonseq_id d’étiquette
tag_namestringnonNom d’étiquette
is_enabled / is_recommended*boolnonActivée / recommandée

Réponse : 200 {"success":true,"data":{FAQEntry}}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/entry -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"standard_question":"Comment obtenir un remboursement?","answers":["Remboursement sous 7 jours"]}'

PUT /api/v1/knowledge-bases/:id/faq/entries/:entry_id ​

Rôle : Mettre à jour une entrée FAQ (même corps que la création).

Réponse : 200 {"success":true,"data":{FAQEntry}}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/entries/12 -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"standard_question":"Comment obtenir un remboursement?","answers":["Remboursement sous 30 jours"]}'

POST /api/v1/knowledge-bases/:id/faq/entries/:entry_id/similar-questions ​

Rôle : Ajouter des questions similaires. Corps : {"similar_questions":["..."]} (binding:"required,min=1").

Réponse : 200 {"success":true,"data":{FAQEntry}}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/entries/12/similar-questions \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"similar_questions":["Comment faire un remboursement"]}'

PUT /api/v1/knowledge-bases/:id/faq/entries/fields ​

Rôle : Mise à jour en lot de champs d’entrées (is_enabled/is_recommended/tag_id).

ChampTypeObligatoireDescription
by_idmap[int64]objectnonMise à jour par seq_id d’entrée
by_tagmap[int64]objectnonMise à jour en lot par étiquette
exclude_ids[]int64nonEntrées exclues avec by_tag

Réponse : 200 {"success":true}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/entries/fields -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"by_id":{"12":{"is_enabled":false}}}'

PUT /api/v1/knowledge-bases/:id/faq/entries/tags ​

Rôle : Modifier en lot les étiquettes des entrées. Corps : {"updates":{"<entry_id>":<tag_id|null>}} (binding:"required,min=1" ; null retire l’étiquette).

Réponse : 200 {"success":true}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/entries/tags -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"updates":{"12":3}}'

DELETE /api/v1/knowledge-bases/:id/faq/entries ​

Rôle : Supprimer des entrées en lot. Corps : {"ids":[int64]} (binding:"required,min=1").

Réponse : 200 {"success":true}

bash
curl -X DELETE $BASE/api/v1/knowledge-bases/kb-1/faq/entries -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"ids":[12,13]}'

POST /api/v1/knowledge-bases/:id/faq/search ​

Rôle : Recherche FAQ (sémantique lecture seule ; une clé limitée retrieve peut aussi appeler).

ChampTypeObligatoireDescription
query_textstringoui (binding:"required")Requête
vector_thresholdfloat64nonSeuil vectoriel, défaut 0,7
match_countintnonDéfaut 10, plafond 50
first_priority_tag_ids / second_priority_tag_ids[]int64nonFiltre par priorité d’étiquettes
only_recommendedboolnonUniquement les entrées recommandées

Réponse : 200 {"success":true,"data":[FAQEntry(avec match_type/score)]}

bash
curl -X POST $BASE/api/v1/knowledge-bases/kb-1/faq/search -H "X-API-Key: $API_KEY" \
  -H 'Content-Type: application/json' -d '{"query_text":"remboursement"}'

PUT /api/v1/knowledge-bases/:id/faq/import/last-result/display ​

Rôle : Définir l’affichage du panneau du dernier résultat d’import. Corps : {"display_status":"open|close"} (binding:"required,oneof=open close").

Réponse : 200 {"success":true}

bash
curl -X PUT $BASE/api/v1/knowledge-bases/kb-1/faq/import/last-result/display \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"display_status":"close"}'

GET /api/v1/faq/import/progress/:task_id ​

Rôle : Progression d’import FAQ / dry-run (tâches isolées par espace). Permissions : Viewer+ ; clé API retrieve/ingest/full.

Réponse : 200 {"success":true,"data":{status,progress,failed_entries,...}}

bash
curl $BASE/api/v1/faq/import/progress/task-1 -H "X-API-Key: $API_KEY"

Wiki (/api/v1/knowledgebase/:kb_id/wiki) ​

Note : le préfixe de ce groupe est /knowledgebase/:kb_id/wiki (singulier, sans trait d’union). Handler : internal/handler/wiki_page.go. Les réponses de ce groupe sont souvent des objets bruts (sans enveloppe success).

GET /api/v1/knowledgebase/:kb_id/wiki/pages ​

Rôle : Lister les pages Wiki.

ParamètreTypeObligatoireDescription
page_typestringnonTypes séparés par des virgules
statusstringnonStatut de page
querystringnonRecherche full-text
category_pathstringnonFiltre de chemin séparé par /
folder_idstringnonFiltre exact de dossier (chaîne vide = racine)
category_depthintnonProfondeur de catégorie
page / page_sizeintnonPagination (défaut 1/20)
sort_by / sort_orderstringnonChamps de tri : title, created_at, updated_at, page_type, wiki_path, sort_order, depth ; autre valeur → updated_at ; défaut updated_at desc

Réponse : 200 WikiPageListResponse

bash
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/pages?page=1" -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/pages ​

Rôle : Créer une page. Corps (types.WikiPage) : slug, title, content, folder_id, page_type, etc. (tous optionnels ; slug généré automatiquement si absent).

Réponse : 201 WikiPage

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/pages -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"title":"Vue d’ensemble de l’architecture","content":"# Vue d’ensemble"}'

PUT /api/v1/knowledgebase/:kb_id/wiki/move-page ​

Rôle : Déplacer une page vers un dossier. Corps : {"slug":"<slug de page>","folder_id":"<ID dossier|vide=racine>"} (slug obligatoire).

Réponse : 200 WikiPage

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/move-page -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"slug":"overview","folder_id":"f-1"}'

GET /api/v1/knowledgebase/:kb_id/wiki/pages/*slug ​

Rôle : Obtenir une page (*slug = chemin wildcard).

Réponse : 200 WikiPageDetail. Conserve tous les champs de WikiPage et ajoute in_link_titles, qui mappe les slugs présents dans in_links vers le titre affiché, par ex. {"concept/example":"Titre d’exemple"}. Objet vide s’il n’y a pas de liens entrants résolvables ; les cibles inexistantes n’apparaissent pas. Échec de résolution des titres → 500, pour éviter une réponse « succès » incomplète.

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/pages/overview -H "Authorization: Bearer $TOKEN"

PUT /api/v1/knowledgebase/:kb_id/wiki/pages/*slug ​

Rôle : Mettre à jour une page (même corps que la création). L’ancienne version est entièrement snapshotée dans wiki_page_revisions, version est incrémentée, last_edit_source vaut user (outil Agent → agent).

Réponse : 200 WikiPage

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/pages/overview -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"content":"# Vue d’ensemble mise à jour"}'

GET /api/v1/knowledgebase/:kb_id/wiki/revisions/*slug ​

Rôle : Historique des versions de la page (migration 000075). Permissions : Viewer+ + KBAccessRead.

ParamètreTypeObligatoireDescription
versionintnonSi fourni, retourne le contenu intégral de cette version (pour diff) ; invalide ou < 1 → 400 ; introuvable → 404 (versions antérieures à la migration ou snapshots purgés par la rétention : normal)
limitintnonDéfaut 50, plafond 200 ; mode liste uniquement
offsetintnonDécalage de pagination

Sans version : liste d’historique (numéros décroissants, sans corps) plus la version courante de la page ; chaque entrée inclut edit_source (pipeline / agent / user / revert), editor_id, edited_at.

Rétention à deux niveaux : plafond souple 50 versions ne rogne que les snapshots pipeline et source vide ; plafond dur 200 pour toutes les sources, donc les éditions manuelles ne sont pas effacées par le pipeline.

bash
# Liste d’historique
curl $BASE/api/v1/knowledgebase/kb-1/wiki/revisions/entity/acme-corp -H "Authorization: Bearer $TOKEN"
# Contenu intégral de la version 3
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/revisions/entity/acme-corp?version=3" -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/revert ​

Rôle : Restaurer une page à une version historique. Permissions : propriétaire KB ou Admin+ + KBAccessWrite.

ChampTypeObligatoireDescription
slugstringouiPage cible
versionintouiNuméro de version cible (≥ 1)

Le revert ne recule pas le numéro de version : le contenu de la version cible est écrit comme nouvelle version, last_edit_source = revert, donc un revert peut être annulé. Revert vers la version courante → 400 (souvent liste d’historique obsolète côté client).

Réponse : 200 WikiPage

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/revert -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"slug":"entity/acme-corp","version":3}'

DELETE /api/v1/knowledgebase/:kb_id/wiki/pages/*slug ​

Rôle : Supprimer une page.

Réponse : 204 No Content

bash
curl -X DELETE $BASE/api/v1/knowledgebase/kb-1/wiki/pages/overview -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/folders ​

Rôle : Lister les dossiers. Paramètres : parent_id (vide = racine), page_types (séparés par des virgules).

Réponse : 200 WikiFolderListResponse

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/folders -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/folders ​

Rôle : Créer un dossier.

ChampTypeObligatoireDescription
namestringouiNom du dossier
parent_idstringnonDossier parent

Réponse : 201 WikiFolder

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/folders -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"Documentation de conception"}'

PUT /api/v1/knowledgebase/:kb_id/wiki/folders/:folder_id ​

Rôle : Renommer / déplacer un dossier. Corps : name, parent_id, move_parent (bool), tous optionnels.

Réponse : 200 WikiFolder

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/folders/f-1 -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"name":"Conception d’architecture"}'

DELETE /api/v1/knowledgebase/:kb_id/wiki/folders/:folder_id ​

Rôle : Supprimer un dossier.

Réponse : 204 No Content

bash
curl -X DELETE $BASE/api/v1/knowledgebase/kb-1/wiki/folders/f-1 -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/index ​

Rôle : Page d’index Wiki (fenêtres groupées par type). Paramètres : types (séparés par des virgules), limit (1–200, défaut 50), cursor.

Réponse : 200 WikiIndexResponse

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/index -H "Authorization: Bearer $TOKEN"

Supprimé

GET /api/v1/knowledgebase/:kb_id/wiki/log (journal des changements Wiki) a été retiré avec la migration 000077_remove_wiki_log ; la table wiki_log_entries a été supprimée. Les changements Wiki sont projetés dans le flux d’activité de la KB : utiliser GET /api/v1/knowledge-bases/:id/activity.

GET /api/v1/knowledgebase/:kb_id/wiki/graph ​

Rôle : Graphe de relations entre pages.

ParamètreTypeObligatoireDescription
modestringnonoverview (défaut) / ego
centerstringnonSlug central en mode ego (obligatoire en mode ego)
depthintnon1–3, défaut 1
typesstringnonFiltre page_type
limitintnonDéfaut 500, plafond 2000

Réponse : 200 WikiGraphData

bash
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/graph?mode=overview" -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/stats ​

Rôle : Statistiques Wiki.

Réponse : 200 WikiStats

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/stats -H "Authorization: Bearer $TOKEN"

Rôle : Recherche de pages. Paramètres : q (obligatoire), limit (défaut 10).

Sémantique de correspondance selon le dialecte de stockage :

  • Postgres : q correspond via regex POSIX (~*, insensible à la casse).
  • SQLite / Lite : correspondance sous-chaîne littérale LIKE ; % / _ échappés, pas traités comme jokers.

Réponse : 200 {"pages":[WikiPage]}

bash
curl "$BASE/api/v1/knowledgebase/kb-1/wiki/search?q=déploiement" -H "Authorization: Bearer $TOKEN"

POST /api/v1/wiki-search ​

Rôle : Recherche de pages Wiki inter-KB (sans session, pas de recherche hybride). Handler : SearchPagesAcross dans internal/handler/wiki_page.go. Même algorithme que GET .../wiki/search sur une KB (titre > slug > summary > corps), une requête sur plusieurs KB puis troncature globale par match_rank. Clé API : retrieve/full.

ChampTypeObligatoireDescription
querystringoui (binding:"required")Comme q mono-KB : regex POSIX sur Postgres (insensible à la casse) ; sous-chaîne LIKE littérale sur SQLite / Lite
knowledge_base_ids[]stringconditionnelMulti-KB ; au moins un de knowledge_base_ids ou knowledge_base_id, max 32
knowledge_base_idstringnonChamp mono-KB de compatibilité, fusionné dans ids
limitintnonTop-N global, défaut 10, max 50

Wiki désactivé sur une KB cible → 400. KB inexistante ou sans lecture → 404. Clé API hors allow-list → 403. Regex invalide (Postgres) → 400.

Réponse : 200 {"success":true,"data":[WikiSearchHit]}. Les hits ne contiennent que des champs de navigation + match_snippet, pas le corps ; le texte intégral via GET /knowledgebase/:kb_id/wiki/pages/{slug}.

Champ réponseTypeDescription
idstringID de page
knowledge_base_idstringKB source, pour construire l’URL de lecture inter-KB
slugstringSlug de page
titlestringTitre
page_typestringType de page
aliases[]stringAlias
summarystringRésumé
match_snippetstringEnviron 60 caractères avant + correspondance + 60 après la première occurrence dans le corps ; omis sans hit dans le corps. Le snippet compile query en regex Go ; sous SQLite, si query contient des métacaractères regex, hit possible en base mais snippet parfois vide

content, arborescence/liens/métadonnées et horodatages ne sont pas dans les résultats de recherche. GET .../wiki/search mono-KB renvoie toujours un WikiPage complet.

bash
curl -X POST $BASE/api/v1/wiki-search -H "X-API-Key: $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"query":"déploiement|release","knowledge_base_ids":["kb-1","kb-2"],"limit":10}'

POST /api/v1/knowledgebase/:kb_id/wiki/rebuild-links ​

Rôle : Reconstruire les liens entre pages. Droits d’écriture. Sans corps.

Réponse : 200 {"message":"Links rebuilt successfully"}

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/rebuild-links -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/lint ​

Rôle : Rapport de cohérence Wiki.

Réponse : 200 WikiLintReport

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/lint -H "Authorization: Bearer $TOKEN"

POST /api/v1/knowledgebase/:kb_id/wiki/auto-fix ​

Rôle : Correction automatique des problèmes lint. Droits d’écriture. Sans corps.

Réponse : 200 {"fixed":N,"message":"Auto-fixed N issues"}

bash
curl -X POST $BASE/api/v1/knowledgebase/kb-1/wiki/auto-fix -H "Authorization: Bearer $TOKEN"

GET /api/v1/knowledgebase/:kb_id/wiki/issues ​

Rôle : Liste des problèmes. Paramètres : slug (filtre par page), status (pending/ignored/resolved).

Réponse : 200 [WikiPageIssue]

bash
curl $BASE/api/v1/knowledgebase/kb-1/wiki/issues -H "Authorization: Bearer $TOKEN"

PUT /api/v1/knowledgebase/:kb_id/wiki/issues/:issue_id/status ​

Rôle : Mettre à jour le statut d’un problème. Droits d’écriture. Corps : {"status":"pending|ignored|resolved"} (binding:"required"). issue_id doit appartenir à la KB du chemin, sinon 404.

Réponse : 200 {"message":"Issue status updated successfully"}

bash
curl -X PUT $BASE/api/v1/knowledgebase/kb-1/wiki/issues/i-1/status -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' -d '{"status":"resolved"}'

Référence d’implémentation ​

Enregistrement des routes : RegisterFAQRoutes et RegisterWikiPageRoutes dans internal/router/routes_knowledge.go. Handlers : internal/handler/faq.go, internal/handler/wiki_page.go.

Documentation issue de WeKnora v0.9.0 · MIT License