- Python 68.6%
- JavaScript 27.5%
- CSS 2.8%
- Jinja 0.3%
- Dockerfile 0.3%
- Other 0.4%
- "Maison" : la porte (petite zone dédiée, pas tout le bâtiment) devient la seule cible pour entrer — le bâtiment reste solide/décoratif partout ailleurs. "Sortie" à l'intérieur était déjà une petite zone équivalente. - Murs intérieurs : bordure de 4 TileSprites (texture tuilable générée, ajoutée au pipeline generate_terrain.py) tout autour de la pièce, avec collision — la pièce ne "flottait" plus dans le vide. - Icônes Soigner/Gronder/Féliciter pour le menu rapide (mode object). - decorationIcons.js : mapping nom→icône extrait de VillageIndoorScene.js vers un module partagé, réutilisé dans ShopView.jsx (catalogue, mes habits, mon inventaire affichent maintenant l'icône si connue). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0116RfuTFidH9dsCUWNt5Lqn |
||
|---|---|---|
| .forgejo/workflows | ||
| alembic | ||
| ansible | ||
| app | ||
| deploy | ||
| docs | ||
| frontend | ||
| scripts | ||
| tests | ||
| .dockerignore | ||
| .env.example | ||
| .env.prod.example | ||
| .gitignore | ||
| alembic.ini | ||
| docker-compose.prod.yml | ||
| docker-compose.yml | ||
| Dockerfile | ||
| pytest.ini | ||
| README.md | ||
| requirements.txt | ||
Tamagotchi
Recréation du gadget Tamagotchi en application web multiusers : stats vitales, aptitudes, système d'évolution par lignées, économie interne et personnalisation. Architecture pensée pour accueillir une dimension sociale en v2 (temps réel, amis, visites).
Documentation
Rangée dans docs/ : reference/ (vision produit, architecture, style guide — la référence stable), process/ (roadmap, état du projet, journal du pipeline d'assets), features/ (specs des fonctionnalités implémentées), v2/ (idées et brouillons pas encore implémentés — un fichier migre vers features/ une fois développé).
docs/reference/tamagotchi_concept.md— vision produit, règles de gameplaydocs/reference/tamagotchi_architecture.md— architecture technique de référence (v1 complète)docs/reference/tamagotchi_style_guide.md— style guide définitif des assets visuels (palette, prompts, pipeline)docs/process/tamagotchi_poc_roadmap.md— découpage du PoC en phasesdocs/process/tamagotchi_project_status.md— état actuel du projet et reste à faire (pour briefer une nouvelle session)docs/process/tamagotchi_asset_pipeline_tests.md— journal des itérations de calibration du styledocs/features/tamagotchi_minigames.md— détail des mini-jeux (implémentés)docs/features/tamagotchi_shop_economy.md— règles et catalogue de la boutique/économie (implémentée)docs/features/tamagotchi_version_footer.md— badge version/environnement en pied de page (implémenté)docs/features/tamagotchi_leaderboards.md— classements par mini-jeu (implémentés)docs/v2/— idées en réflexion pour la v2, pas encore implémentées
Stack
- Backend : FastAPI (async), SQLAlchemy 2.0 + Alembic, PostgreSQL
- Auth : JWT, hashing argon2, rate limiting (slowapi + Redis) sur
/auth/loginet/auth/register - Notifications : Celery + Redis, tâche périodique de détection des tamagotchis en état critique (fondation backend — pas de vraies notifications navigateur pour l'instant)
- Frontend : React (Vite), servi via Docker (Node.js pas nécessaire sur l'hôte)
Démarrage local
# Base de données + Redis + frontend (Node tourne uniquement en conteneur)
docker compose up -d
# Environnement Python (backend)
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env
# Migrations
.venv/bin/alembic upgrade head
# Seed de données de dev (user + tamagotchi de test)
.venv/bin/python -m scripts.seed
# Lancer l'API (port 8000 pris par un autre projet sur cette machine → 8010)
.venv/bin/uvicorn app.main:app --reload --port 8010
# Tests (unitaires + API, la base de test "tamagotchi_test" est créée automatiquement)
.venv/bin/pytest
# Optionnel : worker + beat Celery (notifications périodiques, pas requis pour l'API elle-même)
.venv/bin/celery -A app.tasks.celery_app worker --beat --loglevel=info
L'API est servie sur http://localhost:8010 (GET /health pour vérifier), le frontend sur http://localhost:5173 (voir frontend/README.md).
Tester l'API manuellement
Le plus simple : ouvrir http://localhost:8010/docs (Swagger UI généré automatiquement par FastAPI). Cliquer sur "Authorize" (cadenas en haut à droite), renseigner username = ton email et password = ton mot de passe (les champs client_id/client_secret/scope restent vides), valider. Swagger attache ensuite automatiquement le token à toutes les routes protégées testées via "Try it out".
/auth/login suit volontairement le format standard OAuth2 password flow (username/password en application/x-www-form-urlencoded, username porte l'email) pour être compatible nativement avec le bouton "Authorize" de Swagger — /auth/register reste en JSON classique.
Auth access + refresh : /auth/login renvoie un access token JWT (20 min) et pose un cookie httpOnly refresh_token (14 jours, sameSite=strict, secure uniquement en HTTPS). POST /auth/refresh régénère un access token à partir du cookie, POST /auth/logout l'invalide. Le frontend gère ça tout seul (401 → refresh silencieux → retry) ; via Swagger, l'access token de 20 min expire plus vite qu'avant (24h en PoC) — il suffit de re-cliquer "Authorize" après expiration, ou d'appeler /auth/refresh (le cookie posé par le navigateur suffit, pas besoin de renseigner de champ).
Sinon en ligne de commande :
BASE=http://localhost:8010
# Inscription
curl -X POST $BASE/auth/register -H "Content-Type: application/json" \
-d '{"email":"moi@example.com","password":"password123"}'
# Connexion — récupère le token (form-urlencoded, champ "username" = email)
TOKEN=$(curl -s -X POST $BASE/auth/login -H "Content-Type: application/x-www-form-urlencoded" \
-d "username=moi@example.com&password=password123" | python3 -c "import json,sys;print(json.load(sys.stdin)['access_token'])")
# Créer son tamagotchi (un seul par compte en PoC)
curl -X POST $BASE/tamagotchis -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Fifi"}'
# Consulter l'état (id renvoyé par la création, ex: 1)
curl $BASE/tamagotchis/1 -H "Authorization: Bearer $TOKEN"
# Actions disponibles : feed, play, clean, sleep, wake, heal, scold, praise, pet
curl -X POST $BASE/tamagotchis/1/actions/feed -H "Authorization: Bearer $TOKEN"
Pour observer la maladie/mort sans attendre des heures réelles, on peut avancer last_tick_at artificiellement en base :
docker compose exec postgres psql -U tamagotchi -d tamagotchi \
-c "UPDATE tamagotchis SET last_tick_at = now() - interval '100 hours' WHERE id = 1;"
Un GET /tamagotchis/1 déclenchera alors la décroissance complète, puis (aléatoirement, avec plusieurs essais) le passage en malade.
Pour tester l'évolution (6 lignées : Force, Intelligence, Charisme, Créativité, Discipline, Chance), booster les aptitudes en base puis appeler /evolve autant de fois que de stades à franchir (œuf → bébé → enfant → ado → adulte) :
docker compose exec postgres psql -U tamagotchi -d tamagotchi \
-c "UPDATE aptitudes SET force = 80, intelligence = 30, charisme = 10, discipline = 70 WHERE tamagotchi_id = 1;"
curl -X POST $BASE/tamagotchis/1/evolve -H "Authorization: Bearer $TOKEN" # -> baby
curl -X POST $BASE/tamagotchis/1/evolve -H "Authorization: Bearer $TOKEN" # -> child, lineage="force", variant selon discipline (et poids à l'âge adulte)
Pour observer le cimetière et l'héritage : forcer la mort (comme ci-dessus), puis consulter l'historique et recréer un œuf — il hérite de 10 % des aptitudes du précédent :
curl $BASE/users/me/cemetery -H "Authorization: Bearer $TOKEN"
curl -X POST $BASE/tamagotchis -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Successeur"}'
Avancement du PoC
Voir tamagotchi_poc_roadmap.md pour le détail des phases.
- Phase 0 — Setup & scaffolding
- Phase 1 — Modèles de données (subset PoC)
- Phase 2 — Auth simplifiée
- Phase 3 — Service de tick
- Phase 4 — Endpoint tamagotchi + actions
- Phase 5 — Service d'évolution (réduit)
- Phase 6 — Frontend minimal (React)
- Phase 7 — Test end-to-end & bilan
Bilan Phase 7
Parcours complet testé sans bug bloquant, dans le navigateur (Chrome piloté) : inscription → connexion → création de l'œuf → actions répétées (feed/clean/praise/scold/pet) reflétées en direct → aptitudes boostées en base (à défaut de mini-jeux) → évolution œuf → bébé → enfant (lignée "intelligence", variante "distrait" cohérente avec la discipline basse) → maladie déclenchée en avançant last_tick_at → guérison via "heal".
Frictions relevées
- Mot de passe sans contrainte de longueur côté backend (seul le frontend imposait 8 caractères) — trouvé en testant l'inscription en direct, corrigé dans cette phase (
Field(min_length=8)surUserCreate). Déconnexion au rechargement de page— comblé :POST /auth/refresh+ cookie httpOnly/sameSite=strict, l'access token reste en mémoire JS (jamais localStorage) mais se régénère silencieusement au chargement de la page via le cookie.- Messages d'erreur bruts et en anglais renvoyés tels quels par l'API et affichés dans l'UI (ex. "Tamagotchi is not sick") — pas de traduction ni de formatage convivial.
Pas de mini-jeux jouables— comblé : 5/5 mini-jeux jouables (voirdocs/features/tamagotchi_minigames.md).- Pas de bouton de rafraîchissement manuel dans le dashboard — l'état ne se resynchronise qu'au montage du composant ou après une action.
Pas de tests automatisés sur les routes API— comblé :tests/conftest.pyfournit une base Postgres de test dédiée (tamagotchi_test, créée automatiquement), isolation par transaction/savepoint annulée après chaque test, 18 tests couvrant auth/tamagotchis/actions/evolve en plus des 21 tests unitaires sur les services purs./auth/loginsuit le format OAuth2 form (username/password) pour être compatible avec le bouton "Authorize" de Swagger, alors que/auth/registerreste en JSON — incohérence mineure mais assumée et documentée plus haut.
Priorités proposées pour la suite
Par ordre de valeur/effort estimé, à trancher ensemble avant de reprendre docs/reference/tamagotchi_architecture.md :
Tests API automatisés— fait.Refresh token + stockage httpOnly— fait.Mini-jeux jouables— 5/5 faits (Punching bag, Memory, Dialogue, Pari, Mosaïque).Lignées manquantes— fait.Boutique/économie(monnaie, habits, déco) — fait.Cimetière/héritage— fait.Poids/obésité— fait.Formes différenciées par stade— fait.Évolution automatique— fait (seuils d'âge depuisborn_at, rattrape plusieurs stades d'un coup si besoin).Social minimal (FRIENDSHIPS)— fait.Rate limiting auth— fait.Notifications (fondation)— fait (détection + endpoint, pas de push navigateur).- Piste plus lointaine : village explorable façon Stardew Valley — a du sens une fois la boucle cœur solide, pas avant.
Vers la v1 — cimetière, héritage, poids, formes différenciées
- Cimetière —
CEMETERY(nom, lignée finale, durée de vie, cause de mort), consultable viaGET /users/me/cemetery. Table indépendante du cycle de vie du tamagotchi (pas de FK verstamagotchis), conforme à l'architecture. - Héritage — un compte peut désormais créer un nouvel œuf dès que son tamagotchi précédent est mort (avant : bloqué à vie après un seul). Le nouvel œuf hérite de 10 % des aptitudes finales du précédent (
heritage_service.compute_inherited_aptitudes, fonction pure). - Poids — augmente légèrement à chaque
feed(0.05), décroît passivement avec le temps via le tick (métabolisme, plancher à 0.5). Statutsmaigre/normal/obeseselon des seuils. - Formes différenciées par stade — chaque lignée a désormais un pool de variantes distinct à l'enfance, l'adolescence et l'âge adulte (au lieu d'une seule forme réutilisée). Le poids influence la forme uniquement à l'âge adulte : au-delà du seuil d'obésité, une variante dédiée prend le dessus sur la discipline (ex. force → "colosse"), fidèle à l'obésité de l'original.
Validé par 59 tests automatisés (12 nouveaux : héritage, formes par stade, poids, cimetière) + parcours complet dans un vrai navigateur (mort → cimetière visible sur l'écran de création → nouvel œuf avec aptitudes héritées affichées).
Vers la v1 (suite) — évolution auto, social minimal, rate limiting, notifications
- Évolution automatique —
evolution_service.check_auto_evolutionfait avancer le stade dès que l'âge (born_at) dépasse le seuil du stade suivant, appelé à chaque tick (consultation ou action). Rattrape plusieurs stades d'un coup si le compte n'a pas été consulté depuis longtemps. Le bouton "evolve →" manuel reste disponible en plus (pratique pour les tests). DELETE /tamagotchis/{id}— endpoint manquant de l'architecture, ajouté.- Social minimal — table
FRIENDSHIPS+GET /friendships,POST /friendships/request(par email),POST /friendships/{id}/accept. Volontairement minimal (pas de messagerie, pas de visites) : sert de fondation pour la v2 sociale sans remodeler le schéma plus tard. - Rate limiting —
slowapi+ Redis, 5 tentatives/minute sur/auth/loginet/auth/register(par IP). - Notifications (fondation backend) — Celery + Redis, tâche périodique (
check_critical_tamagotchis, toutes les 30 min) qui détecte les tamagotchis en état critique (faim/bonheur/propreté sous le seuil, ou malades) et crée une entrée dansNOTIFICATIONS, consultable viaGET /users/me/notifications+POST /users/me/notifications/{id}/read. Pas de vraies notifications navigateur (push) pour l'instant — décision explicite pour rester sur une fondation backend simple.
Validé par 104 tests automatisés (22 nouveaux) + vérifications manuelles (rate limit, delete, friendships, scan de notifications sur la vraie base).
Vers la v1 (suite) — boutique & économie
- Boutique —
ITEMS(catalogue),INVENTORY_ITEMS(possession compte : décoration, consommables),TAMA_ITEMS(possession tamagotchi : habits, perdus à la mort).GET /shop/items,POST /shop/items/{id}/buy,GET/POST /tamagotchis/{id}/items(/equip|/unequip|/consume),GET /users/me/inventory. Catalogue de démarrage seedé (scripts/seed_shop.py), détail complet dansdocs/features/tamagotchi_shop_economy.md. - Habits achetés puis équipés/déséquipés séparément ; bonus = mutation directe de la vraie stat/aptitude (choix explicite). Décoration : bonus unique à l'achat, objet conservé en collection. Rare/Légendaire laissés de côté (pas de quête pour les distribuer).
- Frontend
ShopView.jsx, bouton "🛒 Boutique" sur le dashboard, testé de bout en bout en navigateur (achat des 3 catégories, équiper/déséquiper, consommer, mise à jour pièces/stats).
Validé par 127 tests automatisés (22 nouveaux) + parcours complet dans un vrai navigateur.