feat(app) : phase 1 — registre, profils, moteur de recommandation, export markdown
- Schémas Zod partagés ($lib/schemas) : modèle, profil (PRD §4), null = « à vérifier », sources[] obligatoires à chaque écriture - Persistance YAML dans DATA_DIR + commits git automatiques (simple-git) ; seeds PRD au premier démarrage (1 modèle §4.1, 5 profils, 2 templates) - CRUD registre et profils : pages liste/édition/création, form actions, champs tri-état, messages d'erreur Zod, commit par écriture - Moteur de recommandation pur et testé (12 cas : nominal, licence null, seuil, statut mort, vram, modalité, fraîcheur, pénalités) : filtrage dur (requiert/exclut/obligatoire/mort) puis scoring pondéré (préférences, rang arena, fraîcheur, pénalités statut et champs null), justification et warnings (attribution, seuil, garde-fous, déclarations plateformes) - POST /api/recommander (SSO requis) + page /recommander - Exporteur markdown /exports : templates éditables, génération depuis le registre (tableaux registre + classements), commit par document - Vérifié : check/lint/test (22) /build verts, test fumée HTTP complet (seed + git init, CRUD par form action, exports générés, filtres API, 401/404), svelte-autofixer propre sur les 11 composants
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { existsSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { simpleGit, type SimpleGit } from 'simple-git';
|
||||
import { config } from './config';
|
||||
|
||||
let git: SimpleGit | null = null;
|
||||
|
||||
/**
|
||||
* Dépôt git du data_dir (versionning local de la source de vérité).
|
||||
* Initialisé au premier accès ; identité locale dédiée à l'app.
|
||||
* Le push vers une forge distante est volontairement hors périmètre (optionnel, manuel).
|
||||
*/
|
||||
export async function gitDonnees(): Promise<SimpleGit> {
|
||||
if (git) return git;
|
||||
const instance = simpleGit(config.dataDir);
|
||||
if (!existsSync(join(config.dataDir, '.git'))) {
|
||||
await instance.init();
|
||||
}
|
||||
await instance.addConfig('user.name', 'veille-ia');
|
||||
await instance.addConfig('user.email', 'veille-ia@app.local');
|
||||
await instance.addConfig('commit.gpgsign', 'false');
|
||||
git = instance;
|
||||
return git;
|
||||
}
|
||||
|
||||
/** Commit atomique en français des chemins donnés (relatifs au data_dir). */
|
||||
export async function committer(chemins: string[], message: string): Promise<void> {
|
||||
const g = await gitDonnees();
|
||||
await g.add(chemins);
|
||||
// Ne rien faire si aucun changement (écriture idempotente).
|
||||
const statut = await g.status();
|
||||
if (statut.staged.length === 0) return;
|
||||
await g.commit(message);
|
||||
}
|
||||
Reference in New Issue
Block a user