Seed
Le script backend/prisma/seed.ts peuple une base vide avec des comptes de démonstration, un tour de loterie et deux commerces partenaires. Il sert au développement et aux démonstrations. Il ne doit pas être lancé sur une base de production.
Lancer le seed
Depuis backend/, sur une base déjà migrée :
npm run prisma:seedLe script npm exécute tsx prisma/seed.ts. Le script importe le client de backend/src/config/prisma.config.ts, donc la configuration complète de l'application : DATABASE_URL et toutes les variables validées par env.config.ts sont lues depuis backend/.env.
À savoir
backend/package.json déclare aussi "prisma": { "seed": "tsx prisma/seed.ts" }. Prisma 7 ne lit plus cette clé : il cherche la commande de seed dans migrations.seed du fichier backend/prisma.config.ts, qui n'en déclare pas. npx prisma db seed répond donc « No seed command configured », et npm run prisma:reset ne relance pas le seed. Seul npm run prisma:seed fonctionne.
Ce que crée le seed
Comptes
Les trois comptes sont créés par upsert sur walletAddress : relancer le seed ne les duplique pas et ne modifie pas un compte existant (update: {}).
| Rôle | walletAddress |
EtherPoints | Particularité | |
|---|---|---|---|---|
maire@etherbay.fr |
ADMIN |
0xadmin0000000000000000000000000000etherbay |
1 000 | |
boulangerie@etherbay.fr |
PARTNER |
0xpartner00000000000000000000000000etherbay |
500 | Gestionnaire des deux commerces |
citoyen@etherbay.fr |
USER |
0xcitizen00000000000000000000000000etherbay |
250 | Parrainé par le compte administrateur |
Les trois comptes ont isEmailVerified à vrai, la double authentification désactivée, un referralCode généré par défaut, l'empreinte bcrypt du mot de passe de démonstration EtherBay2026demo dans passwordHash, et ageVerificationStatus = VERIFIED avec ageVerifiedAt à la date du seed. Ces trois champs sont aussi écrits par la branche update de l'upsert : relancer le seed les remet sur des comptes déjà présents. Le mot de passe est affiché dans le résumé de fin du script (demoPassword).
Points d'attention :
- Adresses factices : ces valeurs contiennent des lettres hors de l'alphabet hexadécimal ; ce ne sont pas des adresses Ethereum. Elles ne servent qu'à satisfaire l'unicité de la colonne.
- Pas de portefeuille intégré :
walletEncryptedKeyest vide. En mode onchain, le premier achat ou la première consultation deGET /lottery/walletcrée un portefeuille et remplacewalletAddresspar la nouvelle adresse (voir Portefeuilles intégrés). Après cela, relancer le seed tente de recréer le compte avec l'adresse factice et échoue sur l'unicité de l'email, déjà pris par le compte modifié. - Soldes sans historique :
pointsBalanceest écrit directement, sans lignePointTransaction. La règle « le solde est la somme des mouvements » n'est pas respectée pour ces comptes ; l'historique des points affiché pour eux est vide alors que le solde ne l'est pas. - Mot de passe public :
EtherBay2026demoest écrit en clair dansbackend/prisma/seed.ts. Le mobile se connecte avec lui (/auth/signin) ; le web continue de passer par l'email et un code à usage unique, qui arrive dans Mailpit (http://localhost:8025). Voir Comptes et connexion. - Âge vérifié sans pièce : aucune ligne
IdentityDocumentn'est créée. Les trois comptes peuvent jouer d'emblée, et la page Identités de la Mairie est vide après un seed. - Double authentification administrateur : avec
ADMIN_MFA_REQUIREDactif (valeur par défaut), les routes d'administration exigent quemaire@etherbay.frconfigure d'abord une double authentification. - Autres comptes : le seed ne crée que ces trois comptes. Les comptes Mairie et partenaires supplémentaires se créent ensuite depuis la page
/mairie/comptesdu web (POST /admin/accounts), qui crée le compte avec un portefeuille intégré, sans mot de passe ni âge vérifié, et envoie l'email d'invitationstaff-invitation.
Tour de loterie
upsert sur contractRoundId à 1 :
| Colonne | Valeur |
|---|---|
contractRoundId |
1 |
status |
OPEN |
prizePool |
12,5 |
| autres colonnes | valeurs par défaut (startedAt à la date du seed, colonnes onchain vides) |
Ce tour n'a aucun ticket : la cagnotte de 12,5 ETH est une valeur d'affichage pour le mode simulé.
En mode onchain, ce tour est en conflit avec la chaîne : le tour 1 du contrat existe aussi, ouvert au déploiement. Tant que le tour 1 est le tour courant du contrat, chaque GET /lottery/status appelle upsertRoundFromChain, qui réécrit le statut, la cagnotte, le prix, la date de fin et le gagnant à partir du contrat. La cagnotte de 12,5 disparaît alors ; startedAt garde la date du seed. L'indexeur, lui, n'écrase pas prizePool lors de RoundOpened pour un tour existant ; il l'incrémente à chaque achat.
Commerces et récompenses
Les deux commerces sont créés par create, avec leurs offres en écriture imbriquée. Leur gestionnaire (ownerId) est le compte boulangerie@etherbay.fr.
| Commerce | Logo | Offre | Coût | Stock total | Stock restant |
|---|---|---|---|---|---|
| La Boulangerie du Port d'EtherBay | https://assets.etherbay.fr/partners/boulangerie.png |
-15% sur les viennoiseries et pains spéciaux | 100 | 100 | 95 |
| Une Galette des Rois offerte pour 2 achetées | 200 | 50 | 50 | ||
| Cinéma Le Phare EtherBay | https://assets.etherbay.fr/partners/cinema.png |
1 Place de Cinéma achetée = 1 Place offerte | 150 | 200 | 180 |
Attention
Contrairement aux comptes et au tour, les commerces ne sont pas créés par upsert. Chaque exécution du seed ajoute deux nouveaux commerces et trois nouvelles offres, en doublon des précédents. Pour repartir d'un état propre, réinitialiser la base (npm run prisma:reset) puis relancer le seed.
Les stocks restants inférieurs aux stocks totaux (95 sur 100, 180 sur 200) simulent des échanges passés, mais aucune ligne ClaimedReward correspondante n'est créée. Les URL de logos pointent vers un domaine qui n'est pas servi par le dépôt.
Ce que le seed ne crée pas
- aucun ticket, aucun mouvement d'EtherPoints, aucune récompense échangée ;
- aucune ligne
ChainCursor: l'indexeur part deCHAIN_START_BLOCK; - aucune donnée Redis (préférences, quêtes, lots de codes promo) ;
- aucune donnée sur la chaîne : les contrats et le premier tour on-chain sont créés par le script de déploiement de
smart-contract/(voir Blockchain locale).
Sortie
En fin d'exécution, le script affiche les emails des trois comptes, le numéro du tour et le nom des deux commerces, puis ferme la connexion Prisma. En cas d'échec, l'erreur est affichée et le process sort avec le code 1.
Début du seeding BlockLucky — Ville d'EtherBay...
Seeding terminé avec succès : {
admin: 'maire@etherbay.fr',
partnerUser: 'boulangerie@etherbay.fr',
citizen: 'citoyen@etherbay.fr',
activeRoundId: 1,
partners: [ "La Boulangerie du Port d'EtherBay", 'Cinéma Le Phare EtherBay' ]
}