mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
ajout contextes agents
This commit is contained in:
@@ -300,6 +300,129 @@ Si ce n’est pas confirmé comme fonctionnel et utile, **ça n’a rien à fair
|
|||||||
- Idempotence documentée
|
- Idempotence documentée
|
||||||
- Logs corrélés (requestId/traceId)
|
- Logs corrélés (requestId/traceId)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pattern : Contracts-First / Zod-Infer / No-DTO (monorepo TypeScript fullstack)
|
||||||
|
|
||||||
|
- Objectif : avoir une seule source de vérité pour les contrats d’interface entre API et client, sans redéfinition manuelle de types.
|
||||||
|
- Contexte : monorepo TypeScript avec un package partagé (`packages/contracts` ou équivalent), consommé par le backend et le front/mobile.
|
||||||
|
- Quand l’utiliser : dès qu’une API est consommée par un client TypeScript dans le même repo.
|
||||||
|
- Quand l’éviter : si le client est externe (autre organisation, autre langage) — dans ce cas, OpenAPI reste la référence.
|
||||||
|
- Avantage :
|
||||||
|
- Zéro drift entre contrat et implémentation
|
||||||
|
- Types TypeScript gratuits via `z.infer<>` — aucune réécriture
|
||||||
|
- Changement de contrat = erreur de compilation immédiate côté client
|
||||||
|
- Mocks de tests alignés automatiquement
|
||||||
|
- Limites / vigilance :
|
||||||
|
- Ne pas mettre de logique métier dans `packages/contracts` (IO only)
|
||||||
|
- Attention aux dépendances circulaires si le package grossit
|
||||||
|
- Validé le : 07-03-2026
|
||||||
|
- Contexte technique : TypeScript / Zod / NestJS + Expo (React Native) — pattern agnostique framework
|
||||||
|
|
||||||
|
### Implémentation (exemple minimal)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// packages/contracts/src/auth/auth.schemas.ts
|
||||||
|
export const RegisterRequestSchema = z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
password: z.string().min(8),
|
||||||
|
});
|
||||||
|
export type RegisterRequest = z.infer<typeof RegisterRequestSchema>; // type GRATUIT
|
||||||
|
|
||||||
|
// packages/contracts/src/index.ts
|
||||||
|
export * from ‘./auth/auth.schemas’;
|
||||||
|
export * from ‘./errors/error-code’;
|
||||||
|
|
||||||
|
// apps/api/src/modules/auth/auth.controller.ts
|
||||||
|
import type { RegisterRequest } from ‘@monrepo/contracts’;
|
||||||
|
// + ZodValidationPipe → validation automatique, zéro DTO manuel
|
||||||
|
|
||||||
|
// apps/mobile/src/domains/auth/auth.store.ts
|
||||||
|
import type { RegisterRequest } from ‘@monrepo/contracts’;
|
||||||
|
// même type, même schéma, zéro duplication
|
||||||
|
```
|
||||||
|
|
||||||
|
### Structure cible du package contracts
|
||||||
|
|
||||||
|
```
|
||||||
|
packages/contracts/src/
|
||||||
|
auth/auth.schemas.ts ← request/response auth
|
||||||
|
users/users.schemas.ts ← request/response users
|
||||||
|
billing/billing.schemas.ts ← request/response billing (Epic suivant)
|
||||||
|
errors/error-code.ts ← enum codes d’erreur stables
|
||||||
|
http/envelopes.ts ← { data, meta } / { error, meta }
|
||||||
|
index.ts ← re-export tout
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ce qui appartient à contracts
|
||||||
|
|
||||||
|
- Schémas Zod request/response
|
||||||
|
- Types inférés (`z.infer<>`)
|
||||||
|
- Codes d’erreur applicatifs stables
|
||||||
|
- Enums et constantes partagées (ex : liste officielle de sujets/topics)
|
||||||
|
|
||||||
|
### Ce qui n’appartient PAS à contracts
|
||||||
|
|
||||||
|
- Logique métier
|
||||||
|
- Modules/services/guards framework (NestJS, etc.)
|
||||||
|
- State management client (Zustand, Redux, etc.)
|
||||||
|
|
||||||
|
### Checklist
|
||||||
|
|
||||||
|
- [ ] Zéro DTO manuel dans l’API — uniquement `z.infer<typeof Schema>`
|
||||||
|
- [ ] `ZodValidationPipe` global ou par endpoint pour la validation d’entrée
|
||||||
|
- [ ] Constantes partagées (enums, listes) dans contracts, jamais dupliquées
|
||||||
|
- [ ] Mocks de tests importent les types depuis contracts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pattern : Guard global NestJS — ordre d’enregistrement et décorateurs de bypass
|
||||||
|
|
||||||
|
- Objectif : protéger tous les endpoints par défaut, avec un mécanisme explicite pour les exceptions.
|
||||||
|
- Contexte : API NestJS avec plusieurs guards globaux (authn, authz, feature flags...).
|
||||||
|
- Quand l’utiliser : dès qu’on a 2+ guards globaux dont l’un dépend du résultat de l’autre.
|
||||||
|
- Quand l’éviter : si un seul guard suffit.
|
||||||
|
- Avantage :
|
||||||
|
- Sécurité par défaut (opt-out, pas opt-in)
|
||||||
|
- Ordre d’exécution garanti et explicite
|
||||||
|
- Bypass documenté et traçable via décorateurs
|
||||||
|
- Limites / vigilance :
|
||||||
|
- L’ordre des `APP_GUARD` dans `providers[]` est l’ordre d’exécution — ne pas inverser
|
||||||
|
- Exporter le service depuis son module si injecté dans un guard global d’un autre module
|
||||||
|
- Validé le : 07-03-2026
|
||||||
|
- Contexte technique : NestJS v10+
|
||||||
|
|
||||||
|
### Implémentation (exemple minimal)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// app.module.ts
|
||||||
|
providers: [
|
||||||
|
{ provide: APP_GUARD, useClass: AuthGuard }, // 1er : peuple request.user
|
||||||
|
{ provide: APP_GUARD, useClass: EmailVerifiedGuard }, // 2ème : lit request.user
|
||||||
|
{ provide: APP_GUARD, useClass: EntitlementsGuard }, // 3ème : lit request.user + entitlements
|
||||||
|
]
|
||||||
|
|
||||||
|
// skip-auth.decorator.ts
|
||||||
|
export const SKIP_AUTH = ‘skipAuth’;
|
||||||
|
export const SkipAuth = () => SetMetadata(SKIP_AUTH, true);
|
||||||
|
|
||||||
|
// auth.guard.ts
|
||||||
|
const skip = this.reflector.getAllAndOverride<boolean>(SKIP_AUTH, [
|
||||||
|
context.getHandler(),
|
||||||
|
context.getClass(), // permet @SkipAuth() au niveau classe
|
||||||
|
]);
|
||||||
|
if (skip) return true;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checklist
|
||||||
|
|
||||||
|
- [ ] AuthGuard enregistré en premier dans `providers[]`
|
||||||
|
- [ ] AuthModule exporte AuthService si AuthGuard est dans AppModule
|
||||||
|
- [ ] Décorateur `@SkipAuth()` sur tous les endpoints publics (auth, health, docs)
|
||||||
|
- [ ] Tests unitaires sur le guard avec reflector mocké
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Index (à remplir au fil des validations)
|
### Index (à remplir au fil des validations)
|
||||||
|
|
||||||
- Format d’erreur API standardisé
|
- Format d’erreur API standardisé
|
||||||
@@ -309,6 +432,8 @@ Si ce n’est pas confirmé comme fonctionnel et utile, **ça n’a rien à fair
|
|||||||
- Exécution asynchrone des tâches longues (queue + outbox light)
|
- Exécution asynchrone des tâches longues (queue + outbox light)
|
||||||
- Soft delete et archivage explicite
|
- Soft delete et archivage explicite
|
||||||
- Webhooks sortants robustes et idempotents
|
- Webhooks sortants robustes et idempotents
|
||||||
|
- Contracts-First / Zod-Infer / No-DTO (monorepo TypeScript fullstack)
|
||||||
|
- Guard global NestJS — ordre d’enregistrement et décorateurs de bypass
|
||||||
|
|
||||||
⸻
|
⸻
|
||||||
|
|
||||||
|
|||||||
@@ -197,11 +197,91 @@ Ne jamais :
|
|||||||
- [ ] États loading / disabled gérés
|
- [ ] États loading / disabled gérés
|
||||||
- [ ] Tests sur cas valides et invalides
|
- [ ] Tests sur cas valides et invalides
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pattern : Navigation réactive post-action async (React / Expo Router)
|
||||||
|
|
||||||
|
### Synthèse
|
||||||
|
|
||||||
|
- **Objectif** : déclencher la navigation après une action asynchrone (login, register, submit) de façon idiomatique et sans bypasser la réactivité React.
|
||||||
|
- **Contexte** : SPA ou app mobile React avec state management (Zustand, Redux, Context) et router déclaratif (React Router, Expo Router, Next.js App Router).
|
||||||
|
- **Quand l'utiliser** : dès qu'une navigation dépend du résultat d'une action async.
|
||||||
|
- **Quand l'éviter** : navigations synchrones sans état async impliqué.
|
||||||
|
|
||||||
|
### Analyse
|
||||||
|
|
||||||
|
- **Avantages** :
|
||||||
|
- Respecte le cycle de vie React (pas de lecture de state hors cycle)
|
||||||
|
- Re-render automatique si l'état change entre-temps
|
||||||
|
- Testable : on peut assert sur l'état, pas sur des effets de bord
|
||||||
|
- **Limites / vigilance** :
|
||||||
|
- Ne pas oublier les dépendances du `useEffect` (ESLint react-hooks/exhaustive-deps)
|
||||||
|
- Gérer le cas "composant démonté" si la navigation peut être annulée
|
||||||
|
|
||||||
|
### Validation
|
||||||
|
|
||||||
|
- Validé le : 07-03-2026
|
||||||
|
- Contexte technique : React 18+ / Zustand / Expo Router — pattern applicable sur React Router, Next.js App Router
|
||||||
|
|
||||||
|
### Implémentation (exemple minimal)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ Anti-pattern : lecture de state hors cycle React
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await login(email, password);
|
||||||
|
const { accessToken } = useAuthStore.getState(); // bypasse la réactivité
|
||||||
|
if (accessToken) router.replace('/(tabs)');
|
||||||
|
};
|
||||||
|
|
||||||
|
// ✅ Pattern correct : useEffect réactif sur le state
|
||||||
|
const { accessToken, isLoading, error } = useAuthStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (accessToken && !isLoading && !error) {
|
||||||
|
router.replace('/(tabs)');
|
||||||
|
}
|
||||||
|
}, [accessToken, isLoading, error]);
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
await login(email, password);
|
||||||
|
// la navigation se déclenche via useEffect quand le store se met à jour
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pour les callbacks OAuth (ref nécessaire)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Quand un callback externe déclenche la navigation
|
||||||
|
const pendingOAuth = useRef(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (pendingOAuth.current && accessToken) {
|
||||||
|
pendingOAuth.current = false;
|
||||||
|
router.replace('/(tabs)');
|
||||||
|
}
|
||||||
|
}, [accessToken]);
|
||||||
|
|
||||||
|
const handleOAuth = async () => {
|
||||||
|
pendingOAuth.current = true;
|
||||||
|
await exchangeWithIdp(token);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checklist
|
||||||
|
|
||||||
|
- [ ] Aucun `store.getState()` utilisé pour lire l'état post-action dans un handler
|
||||||
|
- [ ] `useEffect` avec dépendances explicites (state pertinent + isLoading + error)
|
||||||
|
- [ ] Cas d'erreur géré (ne pas naviguer si error est défini)
|
||||||
|
- [ ] `useRef` si le trigger vient d'un callback externe (OAuth, deep link)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Index des patterns
|
### Index des patterns
|
||||||
|
|
||||||
- Gestion explicite des états UI (loading / empty / error)
|
- Gestion explicite des états UI (loading / empty / error)
|
||||||
- Séparation claire server state / client state
|
- Séparation claire server state / client state
|
||||||
- Formulaire robuste avec validation et erreurs explicites
|
- Formulaire robuste avec validation et erreurs explicites
|
||||||
|
- Navigation réactive post-action async (React / Expo Router)
|
||||||
|
|
||||||
⸻
|
⸻
|
||||||
|
|
||||||
|
|||||||
59
AGENTS.md
Normal file
59
AGENTS.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Instructions globales — Lead Tech Copilote
|
||||||
|
# Chargé automatiquement par OpenAI Codex CLI
|
||||||
|
|
||||||
|
## Rôle et posture
|
||||||
|
|
||||||
|
Tu es mon copilote principal : technicien, lead tech, coach et challenger.
|
||||||
|
Priorité absolue : justesse, robustesse, réduction du temps de debug.
|
||||||
|
Jamais de sur-ingénierie. Jamais d'invention de comportements incertains.
|
||||||
|
|
||||||
|
Langue de travail : **français**.
|
||||||
|
|
||||||
|
## Base de connaissance à consulter en priorité
|
||||||
|
|
||||||
|
Ces fichiers sont la mémoire durable inter-projets. Consulte-les avant de proposer
|
||||||
|
une solution dans leur domaine respectif.
|
||||||
|
|
||||||
|
| Fichier | Contenu |
|
||||||
|
|---|---|
|
||||||
|
| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles |
|
||||||
|
| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés |
|
||||||
|
| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend |
|
||||||
|
| `10_frontend_risques_et_vigilance.md` | Risques et anti-patterns frontend |
|
||||||
|
| `40_decisions_et_archi.md` | Décisions techniques (mini-ADR) |
|
||||||
|
| `90_debug_et_postmortem.md` | Post-mortems et bugs capitalisés |
|
||||||
|
|
||||||
|
## Règles de mise à jour
|
||||||
|
|
||||||
|
Quand tu repères qu'un pattern mérite d'être capitalisé :
|
||||||
|
|
||||||
|
```
|
||||||
|
FILE_UPDATE_PROPOSAL
|
||||||
|
Fichier : `<nom_du_fichier>`
|
||||||
|
Pourquoi : <1-2 phrases>
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis propose le contenu à ajouter dans le format du fichier cible.
|
||||||
|
|
||||||
|
## Projets actifs
|
||||||
|
|
||||||
|
| Projet | Stack | Localisation | État |
|
||||||
|
|---|---|---|---|
|
||||||
|
| app-alexandrie | NestJS + Expo (React Native) + Prisma + pnpm monorepo | `/srv/projects/app-alexandrie` (NUC) | Epic 2 en préparation |
|
||||||
|
|
||||||
|
## Patterns clés à appliquer systématiquement
|
||||||
|
|
||||||
|
- **Contracts-First / Zod-Infer / No-DTO** : voir `10_backend_patterns_valides.md`
|
||||||
|
- **Navigation réactive useEffect** : voir `10_frontend_patterns_valides.md`
|
||||||
|
- **Guard NestJS — ordre d'enregistrement** : voir `10_backend_patterns_valides.md`
|
||||||
|
- **Format d'erreur API standardisé** : `{ error: { code, message, requestId } }`
|
||||||
|
- **Sessions avec TTL** : toujours un champ `expiresAt`, filtrer dans les queries
|
||||||
|
|
||||||
|
## Infrastructure NUC
|
||||||
|
|
||||||
|
Convention de structure Docker sur le NUC (Proxmox) :
|
||||||
|
- `/srv/projects` — code applicatif
|
||||||
|
- `/srv/docker-data` — données persistantes (bind mounts explicites)
|
||||||
|
- `/srv/backups` — dumps et archives
|
||||||
|
|
||||||
|
Éviter SQL Server en LXC Proxmox → préférer PostgreSQL/MariaDB (voir `90_debug_et_postmortem.md`).
|
||||||
61
CLAUDE.md
Normal file
61
CLAUDE.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Instructions globales — Lead Tech Copilote
|
||||||
|
|
||||||
|
Ce fichier est chargé automatiquement par Claude Code à chaque session.
|
||||||
|
Il pointe vers la base de connaissance commune à tous les projets.
|
||||||
|
|
||||||
|
## Rôle et posture
|
||||||
|
|
||||||
|
Tu es mon copilote principal : technicien, lead tech, coach et challenger.
|
||||||
|
Priorité absolue : justesse, robustesse, réduction du temps de debug.
|
||||||
|
Jamais de sur-ingénierie. Jamais d'invention de comportements incertains.
|
||||||
|
|
||||||
|
Langue de travail : **français**.
|
||||||
|
|
||||||
|
## Base de connaissance à consulter en priorité
|
||||||
|
|
||||||
|
Ces fichiers sont la mémoire durable inter-projets. Consulte-les avant de proposer
|
||||||
|
une solution dans leur domaine respectif.
|
||||||
|
|
||||||
|
| Fichier | Contenu |
|
||||||
|
|---|---|
|
||||||
|
| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles |
|
||||||
|
| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés |
|
||||||
|
| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend |
|
||||||
|
| `10_frontend_risques_et_vigilance.md` | Risques et anti-patterns frontend |
|
||||||
|
| `40_decisions_et_archi.md` | Décisions techniques (mini-ADR) |
|
||||||
|
| `90_debug_et_postmortem.md` | Post-mortems et bugs capitalisés |
|
||||||
|
|
||||||
|
## Règles de mise à jour
|
||||||
|
|
||||||
|
Quand tu repères qu'un pattern mérite d'être capitalisé :
|
||||||
|
|
||||||
|
```
|
||||||
|
FILE_UPDATE_PROPOSAL
|
||||||
|
Fichier : `<nom_du_fichier>`
|
||||||
|
Pourquoi : <1-2 phrases>
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis propose le contenu à ajouter dans le format du fichier cible.
|
||||||
|
|
||||||
|
## Projets actifs
|
||||||
|
|
||||||
|
| Projet | Stack | Localisation | État |
|
||||||
|
|---|---|---|---|
|
||||||
|
| app-alexandrie | NestJS + Expo (React Native) + Prisma + pnpm monorepo | `/Volumes/TeraSSD/Projets_Dev/__Mindleaf/app-alexandrie` | Epic 2 en préparation |
|
||||||
|
|
||||||
|
## Patterns clés à appliquer systématiquement
|
||||||
|
|
||||||
|
- **Contracts-First / Zod-Infer / No-DTO** : voir `10_backend_patterns_valides.md`
|
||||||
|
- **Navigation réactive useEffect** : voir `10_frontend_patterns_valides.md`
|
||||||
|
- **Guard NestJS — ordre d'enregistrement** : voir `10_backend_patterns_valides.md`
|
||||||
|
- **Format d'erreur API standardisé** : `{ error: { code, message, requestId } }`
|
||||||
|
- **Sessions avec TTL** : toujours un champ `expiresAt`, filtrer dans les queries
|
||||||
|
|
||||||
|
## Infrastructure NUC
|
||||||
|
|
||||||
|
Convention de structure Docker sur le NUC (Proxmox) :
|
||||||
|
- `/srv/projects` — code applicatif
|
||||||
|
- `/srv/docker-data` — données persistantes (bind mounts explicites)
|
||||||
|
- `/srv/backups` — dumps et archives
|
||||||
|
|
||||||
|
Éviter SQL Server en LXC Proxmox → préférer PostgreSQL/MariaDB (voir `90_debug_et_postmortem.md`).
|
||||||
Reference in New Issue
Block a user