arcmates

Guide d’installation — Arcmates (Supabase)

Ce guide couvre la mise en route de la persistance Supabase. Le reste (D3, zoom, panneau) fonctionne déjà tel quel, sans build ni dépendance — arc-diagram.html charge simplement D3, le SDK Supabase, puis data.js, storage.js, chart.js via des balises <script> classiques.

1. Le projet Supabase

Projet déjà créé : https://izzwaxgtwikjweebtcgs.supabase.co. (Si tu dois en recréer un : supabase.com → New project → choisir une région → attendre la fin du provisioning, ~2 min.)

2. Créer les tables (schema.sql)

  1. Dans le dashboard Supabase, aller dans SQL Editor (icône </>) → New query.
  2. Ouvrir scripts/schema.sql, copier tout son contenu, le coller dans l’éditeur.
  3. Run. Ça crée les tables people et events, un trigger qui met à jour modifie_le automatiquement, et active la Row Level Security (RLS) avec les policies décrites dans le plan (lecture publique sur les deux tables, écriture/suppression publique sur events).

    ⚠️ Exécute aussi scripts/2026-09-add-person-email-and-write-policies.sql (colonne email + écriture ouverte sur people, pour l’écran “qui es-tu” et l’ajout de personne depuis la sidebar — avant cette migration, people était en lecture seule depuis l’app).

    ⚠️ Si tu avais déjà exécuté schema.sql avant l’ajout de la suppression d’évènement, ta base n’a pas encore la policy de delete — exécute une fois scripts/2024-08-add-delete-policy.sql pour la rattraper (les nouvelles installations n’ont pas besoin de cette étape, elle est déjà dans schema.sql).

    ⚠️ Si tu avais déjà exécuté schema.sql avant l’ajout du temps réel, ta base n’a pas encore events dans la publication Realtime — exécute une fois scripts/2026-08-enable-realtime.sql pour la rattraper (les nouvelles installations n’ont pas besoin de cette étape, elle est déjà dans schema.sql). Rien à activer côté dashboard : c’est cette ligne SQL qui fait tout (équivalent au toggle “Realtime” du Table Editor Supabase sur la table events).

3. Ajouter les personnes (seed-people.sql)

  1. Toujours dans le SQL Editor, New query.
  2. Ouvrir scripts/seed-people.sql, remplacer la liste d’exemple par la vraie liste des membres (nom + emoji optionnel).
  3. Run.
  4. Pour ajouter quelqu’un plus tard, pas besoin de tout rejouer : un simple

    insert into people (nom, emoji) values ('Nouveau Nom', '🎸');
    

    suffit, exécuté à la volée dans le SQL Editor.

    Ce n’est plus la seule façon d’ajouter quelqu’un : le bouton “+ Ajouter une personne” dans la sidebar de l’app fait la même chose depuis l’interface (cf. étape 8 pour la notification email qui accompagne ces créations).

4. Brancher la clé dans le code

  1. Dans le dashboard Supabase : Project Settings (roue crantée) → API.
  2. Récupérer :
    • Project URL (ex. https://izzwaxgtwikjweebtcgs.supabase.co)
    • anon / public key — aussi appelée publishable key sur les projets Supabase récents (elle commence par sb_publishable_... ou ressemble à un long JWT selon la version du dashboard). C’est la même clé, juste un nom différent selon l’interface.
  3. Ouvrir storage.js, renseigner les deux constantes tout en haut du fichier :

    const SUPABASE_URL = "https://izzwaxgtwikjweebtcgs.supabase.co";
    const SUPABASE_ANON_KEY = "...";
    

    ⚠️ Utilise bien la clé anon/publishable, jamais la clé service_role/secret. La clé anon est faite pour être publique et visible dans le code client — c’est normal, ce n’est pas un secret à cacher. C’est la Row Level Security (les policies définies dans schema.sql) qui protège les données, pas la confidentialité de cette clé. La clé service_role, elle, contourne complètement la RLS : elle ne doit jamais apparaître dans du code qui tourne dans un navigateur.

5. Tester en local

Ouvrir arc-diagram.html directement dans un navigateur (double-clic, ou open arc-diagram.html depuis le dossier du projet). La frise doit se charger avec les personnes du seed (sans événement au départ — normal, la table events est vide). Cliquer sur une zone vide de la frise doit ouvrir le panneau de création, et le clic sur “Créer” doit faire apparaître un nouveau nœud après un court instant (aller-retour réseau vers Supabase).

En cas d’erreur, un bandeau apparaît en haut de l’écran (#load-status) — ouvrir la console du navigateur (F12) pour le détail de l’erreur Supabase (clé invalide, RLS mal configurée, etc.).

Pour vérifier le temps réel : ouvrir arc-diagram.html dans deux onglets, créer/modifier/supprimer un évènement dans l’un, il doit apparaître dans l’autre après un court instant sans recharger la page. Si ça ne marche pas alors que la création fonctionne bien dans l’onglet d’origine, la cause la plus probable est events pas encore dans la publication Realtime — cf. l’avertissement de l’étape 2 ci-dessus.

Purger les évènements de test

Après une session de tests, scripts/purge-events.sql vide la table events (sans toucher à people) : à coller/exécuter dans le SQL Editor Supabase. Il contient aussi des variantes en commentaire pour ne purger qu’une partie des évènements (par date de création, par personne…).

6. Tests unitaires

La logique pure (calcul des arcs, conversion des dates, mapping camelCase ↔ snake_case) est couverte par des tests Node, sans framework ni build — juste le test runner intégré à Node (node --test) :

npm install   # une fois, installe d3 comme dépendance de test
npm test

Les fichiers data.js/storage.js restent chargés en <script> classique dans le navigateur (aucun changement de comportement) ; ils exposent en plus un module.exports (ignoré par le navigateur, utilisé par les tests) pour que tests/*.test.js puisse les require(). À faire à chaque modif de data.js/storage.js/chart.js avant de commit, pour attraper vite une régression sur le calcul des arcs ou le mapping Supabase.

8. Notification email à l’admin (ajout de personne)

Pas de validation admin bloquante sur l’ajout d’une personne (décision produit, cf. plans/roadmap.md) — à la place, un email t’est envoyé à chaque création, via une Edge Function déclenchée par un Database Webhook côté base (pas depuis le JS du client — cf. le commentaire en tête de supabase/functions/notify-new-person/index.ts pour le pourquoi). Ces étapes sont manuelles, rien n’est automatisable par du code versionné :

Tout se fait depuis le dashboard web, pas besoin d’installer le CLI Supabase :

  1. Créer un compte sur resend.com (offre gratuite largement suffisante pour ce volume) et récupérer une clé API.
  2. Dashboard Supabase → Edge FunctionsDeploy a new function (ou Create function). Nommer la fonction exactement notify-new-person (ce nom se retrouve dans l’URL finale). Dans l’éditeur de code qui s’ouvre, remplacer tout le contenu par celui de supabase/functions/notify-new-person/index.ts, puis Deploy.
  3. La page de la fonction affiche son URL une fois déployée, format https://<projet>.supabase.co/functions/v1/notify-new-person.
  4. Choisir un secret partagé arbitraire (ex. une longue chaîne aléatoire) et renseigner les 3 secrets dans Edge Functions → Secrets (ou Manage secrets) : RESEND_API_KEY, ADMIN_EMAIL, WEBHOOK_SECRET. ⚠️ Contrairement à la clé anon (§ 4), ces valeurs sont de vrais secrets : RESEND_API_KEY permettrait à qui l’obtiendrait d’envoyer des emails arbitraires depuis ton compte Resend. Elles ne doivent jamais apparaître dans un fichier chargé par le navigateur (storage.js & compagnie) — uniquement ici, côté secrets serveur.
  5. Déclencher l’appel à la fonction à chaque nouvelle personne : exécuter scripts/2026-09-notify-admin-new-person-trigger.sql dans le SQL Editor — un trigger Postgres qui appelle la fonction via l’extension pg_net à chaque INSERT sur people (équivalent à un “Database Webhook”, absent du menu Database de certains dashboards — celui-ci ne dépend d’aucune entrée de menu particulière). Remplacer <TON_WEBHOOK_SECRET> dans le script par la vraie valeur choisie à l’étape 4 avant de l’exécuter.
  6. Vérification : créer une personne de test depuis l’app (bouton sidebar), confirmer la réception de l’email. Pas de test automatisé pour ce point (effet de bord réel = envoi d’un vrai email, hors périmètre de node --test/Playwright).

9. Déployer (GitHub Pages)

Le site est 100% statique (pas de build), donc GitHub Pages suffit :

  1. Sur le repo GitHub (jgresse/arcmates) → SettingsPages.
  2. Source : Deploy from a branch, branche main, dossier / (root).
  3. Save. L’URL de déploiement apparaît en haut de la page quelques minutes après (format https://jgresse.github.io/arcmates/).
  4. Ouvrir arc-diagram.html via cette URL une fois déployé — c’est le lien à partager avec la rabbeutique.

Pas de variable d’environnement à gérer côté déploiement : la clé anon est déjà en dur dans storage.js, committée avec le reste du code (cf. § 4 — c’est voulu).