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,41 @@
|
||||
import { error, fail, redirect } from '@sveltejs/kit';
|
||||
import { modeleSchema } from '$lib/schemas';
|
||||
import { erreursZod, modeleDepuisFormulaire } from '$lib/server/formulaires';
|
||||
import { ecrireRegistre, lireRegistre } from '$lib/server/stockage';
|
||||
import type { Actions, PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ params }) => {
|
||||
const registre = await lireRegistre();
|
||||
const modele = registre.find((m) => m.id === params.id);
|
||||
if (!modele) error(404, 'Modèle introuvable');
|
||||
return { modele };
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
enregistrer: async ({ request, params }) => {
|
||||
const data = await request.formData();
|
||||
const brut = modeleDepuisFormulaire(data);
|
||||
// L'identifiant d'un modèle existant n'est pas modifiable (champ readonly).
|
||||
const resultat = modeleSchema.safeParse({ ...(brut as object), id: params.id });
|
||||
if (!resultat.success) {
|
||||
return fail(400, { erreurs: erreursZod(resultat.error), brut });
|
||||
}
|
||||
|
||||
const registre = await lireRegistre();
|
||||
const index = registre.findIndex((m) => m.id === params.id);
|
||||
if (index === -1) error(404, 'Modèle introuvable');
|
||||
|
||||
registre[index] = resultat.data;
|
||||
await ecrireRegistre(registre, `feat : mise à jour du modèle ${params.id}`);
|
||||
redirect(303, '/registre');
|
||||
},
|
||||
|
||||
supprimer: async ({ params }) => {
|
||||
const registre = await lireRegistre();
|
||||
const restant = registre.filter((m) => m.id !== params.id);
|
||||
if (restant.length === registre.length) error(404, 'Modèle introuvable');
|
||||
|
||||
await ecrireRegistre(restant, `feat : suppression du modèle ${params.id}`);
|
||||
redirect(303, '/registre');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user