AgenticOS
One place to build, run and govern your company's AI agents. Self-hosted, open source, and yours.
Gestion des tests CACES® pour les organismes testeurs certifiés
Translation pending
BusinessTypeScript · PLpgSQLGitHub @goubiniban-coderOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
création de logiciel de forma
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Logiciel SaaS pour les organismes testeurs certifiés (OTC) CACES® : préparation des sessions de test, passage des tests sur tablette (y compris hors connexion), puis délivrance et vérification des certificats.
« Certipilot » est un nom de code provisoire, centralisé dans
lib/constants.ts. CACES® est une marque déposée de la Cnam : le nom de l'application ne doit pas la contenir.
Structure : app/ (pages et actions), components/, lib/rules/ (règles métier pures,
testées à 100 %), lib/offline/ (base locale et synchronisation de l'application testeur),
lib/certificates/ et lib/export/ (PDF et ZIP), supabase/migrations/ (schéma, RLS,
triggers de conformité).
corepack enable)pnpm install
cp .env.example .env.local
pnpm db:start # démarre Supabase en local (Postgres, Auth, Storage)
pnpm supabase status # affiche l'URL et les clés à copier dans .env.local
Renseignez dans .env.local les valeurs API URL, anon key et service_role key
affichées par pnpm supabase status.
pnpm dev
L'application est disponible sur http://localhost:3000. Le Studio Supabase local est sur http://127.0.0.1:54323 et les e-mails envoyés (invitations) sont visibles dans Mailpit sur http://127.0.0.1:54324.
pnpm db:reset recrée la base à partir des migrations de supabase/migrations et du
jeu de données supabase/seed.sql.
| Commande | Contenu |
|---|---|
pnpm test | Tests unitaires (Vitest) |
pnpm test:coverage | Tests unitaires avec couverture ; les règles métier de lib/rules/ doivent être couvertes à 100 % |
pnpm test:db | Tests de la base (isolation entre organisations par la RLS, triggers) ; nécessite pnpm db:start |
pnpm test:e2e | Parcours principaux dans un navigateur, sur ordinateur et sur tablette (Playwright) ; la première fois : pnpm exec playwright install chromium. Le rechargement de l'application testeur sans réseau n'est vérifié qu'avec une version de production (pnpm build && pnpm start, ce que fait l'intégration continue) |
pnpm lint et pnpm typecheck | Qualité du code |
Si Supabase ne peut pas tourner en local, les tests de la base fonctionnent aussi sur un
PostgreSQL 16 classique. Le script crée une base jetable avec une imitation minimale des
schémas auth et storage de Supabase, puis applique les migrations et le seed :
ADMIN_DATABASE_URL=postgresql://postgres:[email protected]:5432/postgres pnpm db:test-bootstrap
DATABASE_URL=postgresql://postgres:[email protected]:5432/certipilot_test pnpm test:db
C'est ce que fait l'intégration continue.
supabase/migrations/ : le schéma, la RLS, les triggers de conformité et d'audit, le
stockage et le référentiel par défaut (les 8 recommandations, leurs catégories et deux
grilles d'exemple). Ce référentiel est copié dans chaque organisme à son inscription,
qui peut ensuite l'adapter. Les grilles d'exemple ne sont pas officielles et sont
marquées « À VALIDER avec un testeur ».supabase/seed.sql : un organisme de démonstration, pour le développement local
uniquement. Comptes (mot de passe certipilot-demo) :
[email protected], [email protected],
[email protected], [email protected]. La « Session du jour
(démo) » attribue deux épreuves pratiques du jour à testeur1 (Marc Testeur), et un
historique de trois certificats délivrés il y a environ cinq ans alimente les
renouvellements du tableau de bord.Le testeur se connecte sur la tablette et arrive sur /testeur : la liste de ses
candidats du jour. Tant que la tablette a du réseau, les épreuves du jour (grilles,
photos des candidats) sont téléchargées dans la tablette (IndexedDB, via Dexie).
Ensuite tout se fait sans réseau : contrôle d'identité (type et numéro de pièce, case « vérifié » horodatée), démarrage de l'épreuve, notation critère par critère avec le score en direct et le chronomètre, résultat, puis signature au doigt. Chaque action est mise dans une file d'attente et envoyée dans l'ordre dès le retour du réseau. Le serveur refait tous les contrôles (identité, testeur, engin, calcul du résultat) : si une modification est refusée, elle reste sur la tablette avec le message d'erreur et peut être renvoyée une fois le problème corrigé.
L'indicateur en haut de l'écran affiche « Hors ligne », « Synchronisation en cours »,
« Synchronisé » ou « Erreur de synchronisation ». Avec une version de production
(pnpm build && pnpm start), un service worker (public/sw.js) garde aussi la page
disponible hors connexion : elle se recharge même sans réseau, et peut être installée
sur l'écran d'accueil de la tablette.
Sur la page d'une session, le bouton « Délivrer le certificat » apparaît pour un candidat
dès que la théorie (QCM, et QCM-IPR pour la R.482) et au moins une catégorie pratique sont
réussies. La base refait ces contrôles, numérote le certificat (PRÉFIXE-ANNÉE-000001) et
calcule la fin de validité depuis le référentiel (5 ans par défaut, 10 ans pour la R.482,
modifiable par recommandation ou par catégorie). Seuls le responsable et le secrétariat
délivrent.
Le PDF (lib/certificates/) est généré côté serveur avec @react-pdf/renderer : photo du
candidat, catégories obtenues uniquement, dates, et un QR code vers la page publique
/verifier/[jeton]. Il est rangé dans le bucket privé certificates et téléchargé par une
URL signée d'une minute. Un certificat ne se modifie jamais : il peut seulement être
révoqué par le responsable, avec un motif, et la page de vérification affiche alors
« Révoqué ».
Les photos des candidats sont réenregistrées en JPEG (800 px maximum, sans métadonnées EXIF ni GPS) au moment de l'envoi.
Sur la page d'une session, le responsable du centre peut « Exporter le dossier d'audit (ZIP) ». L'archive contient, en CSV lisibles dans Excel : la session, les testeurs et leurs CACES® personnels, les engins et leur dernière vérification périodique, les candidats et leur contrôle d'identité, les résultats de théorie, les épreuves pratiques (testeur, engin, horaires, score), la grille de chaque épreuve critère par critère, les signatures, les certificats PDF et le journal des modifications (qui a fait quoi, quand). Chaque export est lui-même tracé dans le journal.
anon et la clé
service_role (Project Settings › API).pnpm supabase login
pnpm supabase link --project-ref <référence-du-projet>
pnpm supabase db push # applique supabase/migrations, sans les données de démo
Ne lancez jamais supabase/seed.sql en production.vercel.json place les fonctions à Paris (cdg1).
Ajoutez les variables d'environnement :
NEXT_PUBLIC_APP_URL : l'adresse publique (utilisée dans les QR codes et les
invitations) ;NEXT_PUBLIC_SUPABASE_URL et NEXT_PUBLIC_SUPABASE_ANON_KEY ;SUPABASE_SERVICE_ROLE_KEY (secrète, jamais exposée au navigateur)./inscription pour créer le premier organisme et son compte responsable, puis
invitez le secrétariat et les testeurs depuis « Utilisateurs ».Les photos, pièces d'identité, signatures et certificats sont dans des buckets privés, servis uniquement par des URL signées de courte durée. La durée de conservation des données des candidats se règle dans « Organisme » (10 ans par défaut) ; la purge RGPD anonymise les candidats hors délai et efface leurs photos.