a57bf3607b
Add three documentation files for the posts module: - `api.md`: public API reference (list, slug, categories, images) - `admin-api.md`: admin API reference with all CRUD endpoints - `integration.md`: Next.js integration examples with code snippets
3.1 KiB
3.1 KiB
Usage programmatique — Module Posts
Idéal pour les cron jobs, scripts d'import ou fetchers automatisés.
Fonctions disponibles
import {
createPost, // Créer un post
updatePost, // Modifier un post
getPostBySlug, // Chercher par slug
getPostByField, // Chercher par n'importe quel champ JSONB
upsertPost, // Créer ou mettre à jour (idempotent)
getPosts, // Liste avec pagination
deletePost, // Supprimer
} from '@zen/core/modules/posts/crud';
upsertPost(postType, rawData, uniqueField)
Crée le post s'il n'existe pas, le met à jour sinon.
postType: le type de post ('cve','actualite'...)rawData: les données du post (mêmes champs que pourcreatePost)uniqueField: le champ de déduplication ('slug'par défaut)
Retourne { post, created: boolean }.
Champs relation dans rawData
Les champs relation reçoivent un tableau d'IDs de posts existants.
// Correct
{ tags: [7, 8, 12], source: [3] }
// Incorrect
{ tags: ['openssh', 'vuln'], source: { id: 3 } }
Si les posts liés n'existent pas encore, les créer d'abord avec upsertPost puis utiliser leurs IDs.
Exemple : fetcher de CVE
// src/cron/fetch-cves.js
import { upsertPost } from '@zen/core/modules/posts/crud';
export async function fetchAndImportCVEs() {
const response = await fetch('https://api.example.com/cves/recent');
const { cves } = await response.json();
const results = { created: 0, updated: 0, errors: 0 };
for (const cve of cves) {
try {
// Résoudre les relations : s'assurer que les tags existent
const tagIds = [];
for (const tagName of (cve.tags || [])) {
const { post: tag } = await upsertPost('tag', { title: tagName }, 'slug');
tagIds.push(tag.id);
}
// Upsert du CVE, dédupliqué sur cve_id
const { created } = await upsertPost('cve', {
title: cve.title,
cve_id: cve.id,
severity: cve.severity,
score: String(cve.cvssScore),
product: cve.affectedProduct,
date: cve.publishedAt,
description: cve.description,
tags: tagIds,
}, 'cve_id');
created ? results.created++ : results.updated++;
} catch (err) {
console.error(`[CVE import] Error for ${cve.id}:`, err.message);
results.errors++;
}
}
console.log(`[CVE import] Done — created: ${results.created}, updated: ${results.updated}, errors: ${results.errors}`);
return results;
}
Exemple : fetcher d'actualités avec source
import { upsertPost } from '@zen/core/modules/posts/crud';
export async function fetchAndImportActualites(sourceName, articles) {
// S'assurer que la source existe
const { post: source } = await upsertPost('source', { title: sourceName }, 'slug');
for (const article of articles) {
await upsertPost('actualite', {
title: article.title,
date: article.publishedAt,
resume: article.summary,
content: article.content,
source: [source.id],
tags: [],
}, 'slug');
}
}