Invariants — Pense-bête

INVARIANTS — Pense-bête

0) Rôle du document

Ce document fixe les invariants techniques, structurels, métier, visuels et ergonomiques du projet Pense-bête.

Il sert de source de vérité pour :

  • l’infrastructure locale et serveur
  • les conventions Docker / Compose
  • la structure Django / React
  • les variables d’environnement
  • les règles frontend/backend
  • la cohérence visuelle avec les autres applications existantes
  • les consignes à respecter par Codex et tout autre agent

En cas de conflit entre une proposition de code et ce document, ce document prévaut.


1) Identité du projet

1.1 Nommage canonique

  • Nom humain : Pense-bête
  • Nom dépôt Git : pense_bete
  • Slug technique : pb
  • Répertoire DEV : ~/projets/pense_bete
  • Répertoire PROD : /opt/apps/pb

1.2 Variables d’identité

Les variables suivantes sont obligatoires :

APP_NAME=Pense-bête
APP_DEPOT=pense_bete
APP_SLUG=pb
APP_ENV=dev|prod
APP_NO=<entier unique>

1.3 Rôle de APP_NO

APP_NO est l’identifiant numérique unique de l’application dans l’écosystème local. Il sert à dériver les ports hôte en DEV.


2) Principes d’architecture

2.1 Stack imposée

Le projet utilise exclusivement :

  • PostgreSQL
  • Django + Django REST Framework
  • SimpleJWT
  • React + Vite
  • Docker Compose
  • Traefik comme frontal unique côté serveur

2.2 Interdictions

Il est interdit de :

  • remplacer PostgreSQL par SQLite
  • remplacer Django par un autre backend
  • remplacer Vite/React par une autre stack frontend
  • exposer directement les apps en PROD sur 80/443
  • contourner Traefik
  • introduire une seconde architecture concurrente
  • modifier les noms canoniques des services Compose
  • stocker des secrets dans les fichiers .env.dev ou .env.prod

2.3 Objectif du projet

Pense-bête est une application de capture rapide et de suivi léger.

Ce n’est pas un agenda centré sur l’heure.

L’application est conçue pour :

  • noter rapidement une idée ou une tâche
  • suivre un dossier ouvert
  • revoir des choses à penser ou à relancer
  • distinguer ce qui est à faire, en attente, à acheter ou à revoir

3) Répertoires, nommage Docker et conventions système

3.1 Répertoires

  • DEV : ~/projets/${APP_DEPOT}
  • PROD : /opt/apps/${APP_SLUG}

3.2 Nommage Docker

  • Containers : ${APP_SLUG}_<service>_${APP_ENV}
  • Réseau par défaut : ${APP_SLUG}_appnet
  • Volume DB recommandé : ${APP_SLUG}_db_data

3.3 Services Compose canoniques

Les services autorisés et attendus sont :

  • db
  • backend
  • vite
  • frontend

Ces noms sont stables et ne doivent pas être renommés.


4) Ports dérivés de APP_NO

4.1 Règle canonique

Si APP_NO = N, alors en DEV :

DEV_DB_PORT   = 5432 + N
DEV_API_PORT  = 8001 + N
DEV_VITE_PORT = 5173 + N

4.2 Ports internes fixes

Les ports internes des conteneurs sont toujours :

  • DB : 5432
  • backend : 8000
  • vite : 5173

Seuls les ports hôte varient via APP_NO.

4.3 Exemple pour Pense-bête

Si APP_NO=5, alors :

DEV_DB_PORT=5437
DEV_API_PORT=8006
DEV_VITE_PORT=5178

5) Environnements et secrets

5.1 Fichiers canoniques

Fichiers versionnés :

  • .env.dev
  • .env.prod
  • .env.local.example

Fichier non versionné :

  • .env.local

Symlink canonique :

.env -&gt; .env.$(APP_ENV)

5.2 Règles de secrets

Interdit dans .env.dev et .env.prod :

  • POSTGRES_PASSWORD
  • DJANGO_SECRET_KEY
  • ADMIN_USERNAME
  • ADMIN_EMAIL
  • ADMIN_PASSWORD
  • tout autre secret réel

Autorisé dans .env.local seulement :

  • POSTGRES_PASSWORD
  • DJANGO_SECRET_KEY
  • ADMIN_USERNAME
  • ADMIN_EMAIL
  • ADMIN_PASSWORD

5.3 Exemples

.env.dev

APP_ENV=dev
APP_NAME=Pense-bête
APP_DEPOT=pense_bete
APP_SLUG=pb
APP_NO=5

POSTGRES_USER=${APP_SLUG}_pg_user
POSTGRES_DB=${APP_SLUG}_pg_db

DEV_DB_PORT=5437
DEV_API_PORT=8006
DEV_VITE_PORT=5178

VITE_API_BASE=/api

.env.prod

APP_ENV=prod
APP_NAME=Pense-bête
APP_DEPOT=pense_bete
APP_SLUG=pb
APP_NO=5
APP_HOST=pb.mon-site.ca

POSTGRES_USER=${APP_SLUG}_pg_user
POSTGRES_DB=${APP_SLUG}_pg_db

VITE_API_BASE=/api

.env.local.example

POSTGRES_PASSWORD=change_me
DJANGO_SECRET_KEY=change_me
ADMIN_USERNAME=admin
ADMIN_EMAIL=admin@example.test
ADMIN_PASSWORD=change_me

6) Postgres — invariants de connexion

6.1 Invariants

  • Host compose : db
  • Port interne : 5432
  • Utilisateur : ${POSTGRES_USER} = ${APP_SLUG}_pg_user
  • Base : ${POSTGRES_DB} = ${APP_SLUG}_pg_db

6.2 Accès hors conteneur

En DEV, si publication activée :

localhost:${DEV_DB_PORT}

En PROD :

  • ne pas publier la DB publiquement
  • privilégier un tunnel SSH ponctuel si nécessaire

6.3 Commandes psql canoniques

Depuis le conteneur backend :

docker compose --env-file .env.dev -f docker-compose.dev.yml exec backend \
  psql -h db -p 5432 -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c '\\dt'

Depuis l’hôte si port publié :

psql -h localhost -p "$DEV_DB_PORT" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c 'select 1;'

7) Conteneurisation (Compose)

7.1 Règles générales

  • utiliser exclusivement docker compose
  • toujours fournir --env-file
  • conserver deux fichiers :
docker-compose.dev.yml
docker-compose.prod.yml

7.2 Services

  • db : Postgres
  • backend : Django API
  • vite : serveur dev frontend
  • frontend : build statique / service web selon le mode

7.3 Healthchecks et dépendances

  • backend dépend de db healthy
  • vite peut dépendre de backend en DEV
  • le système doit démarrer sans ordre implicite fragile

7.4 PROD et exposition réseau

En PROD :

  • ne jamais publier 80/443 depuis l’application
  • Traefik reste le frontal unique
  • un bind local 127.0.0.1:PORT->8000 peut exister pour debug/health local seulement

8) Backend Django (API)

8.1 Règles générales

  • commande DEV : python manage.py runserver 0.0.0.0:8000
  • toutes les routes backend sont sous le préfixe /api/
  • auth JWT via SimpleJWT
  • API REST via DRF
  • base de données PostgreSQL uniquement

8.2 Règles d’auth

  • JWTAuthentication doit être activé
  • les endpoints JWT doivent exister
  • une route whoami doit exister
  • l’API doit être utilisable via le proxy Vite /api
  • l’application doit être protégée par authentification

8.3 Structure recommandée

backend/
├── api/
│   ├── migrations/
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── serializers.py
│   ├── permissions.py
│   ├── urls.py
│   ├── views.py
│   ├── views_auth.py
│   └── views_login.py / views_logout.py
├── pb/
│   ├── settings.py
│   ├── urls.py
│   ├── asgi.py
│   └── wsgi.py
├── Dockerfile.dev
├── Dockerfile.prod
├── manage.py
└── requirements.txt

8.4 Permissions

Chaque utilisateur ne voit que ses propres objets.

Règles :

  • filtrer les querysets par request.user
  • object-level permissions strictes
  • pas de fuite de données inter-utilisateurs

9) Métier — modèle central

9.1 Entité principale

L’entité principale est Item.

Un Item représente :

  • tâche
  • achat
  • suivi
  • appel
  • question
  • idée
  • document à obtenir

9.2 Champs métier minimaux

Le modèle Item doit prévoir au minimum :

  • title
  • details
  • kind
  • status
  • priority
  • context
  • contact_name
  • due_date
  • review_at
  • completed_at
  • created_at
  • updated_at
  • user

9.3 Types (kind)

Valeurs minimales :

  • task
  • buy
  • followup
  • call
  • question
  • idea
  • document

9.4 Statuts (status)

  • inbox
  • next
  • waiting
  • scheduled
  • done
  • archived

9.5 Priorité (priority)

  • low
  • normal
  • high

9.6 Distinction importante

due_date et review_at ne doivent pas être confondus.

  • due_date = échéance réelle
  • review_at = moment où l’item doit revenir dans l’attention

9.7 Historique

Prévoir une entité ItemEvent pour tracer :

  • création
  • modification
  • changement de statut
  • report de revue
  • marquage terminé

10) API métier

10.1 Endpoints minimaux

  • GET /api/items/
  • POST /api/items/
  • GET /api/items/{id}/
  • PATCH /api/items/{id}/
  • DELETE /api/items/{id}/

10.2 Endpoints utiles

  • /api/items/inbox/
  • /api/items/today/
  • /api/items/waiting/
  • /api/items/buy/
  • /api/items/review/
  • /api/items/overdue/

10.3 Actions rapides

  • POST /api/items/{id}/mark_done/
  • POST /api/items/{id}/move_to_inbox/
  • POST /api/items/{id}/set_waiting/
  • POST /api/items/{id}/reschedule_review/

10.4 Recherche / filtres

GET /api/items/ doit permettre de filtrer par :

  • status
  • kind
  • priority
  • q

11) Frontend React / Vite

11.1 Stack frontend

  • React
  • Vite
  • proxy /api vers http://backend:8000
  • VITE_API_BASE=/api

11.2 Règles frontend

  • ne jamais coder une base API absolue
  • utiliser VITE_API_BASE
  • passer par le proxy Vite

11.3 Structure recommandée

frontend/src/
├── api.js
├── App.jsx
├── main.jsx
├── styles.css
├── components/
│   ├── QuickCapture.jsx
│   ├── ItemForm.jsx
│   ├── ItemList.jsx
│   ├── ItemCard.jsx
│   ├── ItemFilters.jsx
│   ├── StatusBadge.jsx
│   └── ToastProvider.jsx
└── pages/
    ├── LoginPage.jsx
    ├── InboxPage.jsx
    ├── TodayPage.jsx
    ├── WaitingPage.jsx
    ├── BuyPage.jsx
    ├── AllItemsPage.jsx
    └── ItemDetailPage.jsx

11.4 Token frontend

Clé recommandée :

pb.jwt

11.5 Intercepteur

Un intercepteur 401 peut rediriger vers la page de login.


12) Vues fonctionnelles minimales

  • Login
  • Inbox
  • Aujourd’hui
  • En attente
  • Achats
  • Tous
  • Détail item

13) Invariants UX

Principe fondamental

La capture rapide est la fonctionnalité centrale.

Créer un item simple doit être plus rapide qu’ouvrir un formulaire classique.

Règles

  • capture immédiate
  • champs obligatoires minimaux
  • tri possible après création

14) Invariants UI / visuels

Objectif

L’application doit rester cohérente avec les autres applications existantes.

Principes :

  • interface sobre
  • lisibilité
  • hiérarchie claire
  • composants homogènes

15) Fragments normatifs

Vite proxy

proxy: {
  '/api': {
    target: 'http://backend:8000'
  }
}

16) Makefile — cibles attendues

  • help
  • envlink
  • ensure-env
  • up
  • down
  • restart
  • ps
  • logs
  • logs-backend
  • logs-frontend
  • logs-db
  • makemigrations
  • migrate
  • createsuperuser
  • psql

17) Vérification des invariants

Script recommandé :

scripts/verifier-invariants.sh

18) Checklist avant merge

  • invariants vérifiés
  • proxy Vite OK
  • JWT configuré
  • secrets hors repo
  • cohérence UI

19) Emplacement du document

Chemin recommandé :

docs/INVARIANTS.md

20) Consignes permanentes pour Codex

  1. relire ce document
  2. respecter les invariants
  3. proposer des snippets prêts à copier
  4. maintenir la cohérence cross-apps

21) Extension cross-apps

Ce document est une déclinaison du template commun des applications :

  • conventions Docker
  • conventions API
  • conventions .env
  • cohérence frontend