mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-06-28 01:53:40 +02:00
chore(sanitization): nettoyage repo post-capitalisation
- Suppression de 3 fichiers *.tmp versionnés (résidus install BMAD 6.0.4, vides)
- Ajout de *.tmp au .gitignore
- Déduplication: entrée "Prisma init au chargement = casse build Next.js"
était dupliquée à l'identique dans risques/prisma.md ET risques/nextjs.md
→ conservée dans nextjs.md (risque Next.js), retirée de prisma.md
- Déduplication: pattern "Tests de styles RN sans renderer JSX" dupliqué dans
patterns/tests.md ET patterns/design-tokens.md → conservé dans tests.md
- Correction README backend/risques : retrait des entrées fantômes de la ligne
prisma.md ("init module build" déplacé vers nextjs ; "suppression champ .map()"
qui vit en réalité dans general.md)
Audit complet de la base : aucun doublon d'ancre restant, liens non cassés,
README synchronisés, format risques/patterns constant. Branches obsolètes
mcp_test et mcp_v1 supprimées (mergées dans main).
This commit is contained in:
@@ -17,3 +17,6 @@ dist/
|
|||||||
|
|
||||||
# Leadtech MCP — secrets du déploiement central (le .env.example reste versionné)
|
# Leadtech MCP — secrets du déploiement central (le .env.example reste versionné)
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# Fichiers temporaires
|
||||||
|
*.tmp
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Avant toute proposition backend, identifie le fichier dont le nom et la descript
|
|||||||
|---------|---------|--------------|
|
|---------|---------|--------------|
|
||||||
| `auth.md` | Auth, sessions, guards, accès | AuthN/AuthZ dispersée, guard global manquant, null-check request.user, AdminRoleGuard sans @RequireAdminRole, GET sans contrôle accès, cookie après révocation, mock session sans expiresAt, buildApp partagé e2e, champ absent JWT, email login vs contact, disclosure comptes soft-deleted dans login(), guard d'abonnement global vs droits acquis permanents, validité du jeton d'octroi ≠ durée de l'accès, cohérence des filtres d'authz entre chemins, rotation refresh token IdP en BFF (cookie non réécrit) |
|
| `auth.md` | Auth, sessions, guards, accès | AuthN/AuthZ dispersée, guard global manquant, null-check request.user, AdminRoleGuard sans @RequireAdminRole, GET sans contrôle accès, cookie après révocation, mock session sans expiresAt, buildApp partagé e2e, champ absent JWT, email login vs contact, disclosure comptes soft-deleted dans login(), guard d'abonnement global vs droits acquis permanents, validité du jeton d'octroi ≠ durée de l'accès, cohérence des filtres d'authz entre chemins, rotation refresh token IdP en BFF (cookie non réécrit) |
|
||||||
| `contracts.md` | Contrats, validation, codes erreur | Contrats implicites, erreurs non standardisées, duplication constantes, schema orphelin, code erreur générique 409, ForbiddenException pour validation, process.env direct, statut métier non propagé, AC d'affichage vert mais champ absent du contract, schéma par audience pas par entité |
|
| `contracts.md` | Contrats, validation, codes erreur | Contrats implicites, erreurs non standardisées, duplication constantes, schema orphelin, code erreur générique 409, ForbiddenException pour validation, process.env direct, statut métier non propagé, AC d'affichage vert mais champ absent du contract, schéma par audience pas par entité |
|
||||||
| `prisma.md` | Prisma, DB, transactions, migrations | @unique nullable, TOCTOU transaction, OR tenantId null, nextOrder race condition, tenantId sans FK (relation des deux côtés), schema divergence spec, getter manquant, init module build, clearAllMocks imbriqué, cursor non validé (champs typés), enum-like String, migration manuelle hors git, relation 1:1 sans unique, index partial soft-delete (perf), index partiels littéraux text bloquent ALTER enum, colonnes Prisma jamais écrites, read-then-write/transition one-shot race, @@unique + @@index redondant, suppression champ DB invisible via .map(), DELETE row en transaction d'anonymisation, slug User.id (id auto-généré + validation Zod), template DB de test à droper après migration |
|
| `prisma.md` | Prisma, DB, transactions, migrations | @unique nullable, TOCTOU transaction, OR tenantId null, nextOrder race condition, tenantId sans FK (relation des deux côtés), schema divergence spec, getter manquant, clearAllMocks imbriqué, cursor non validé (champs typés), enum-like String, migration manuelle hors git, relation 1:1 sans unique, index partial soft-delete (perf), index partiels littéraux text bloquent ALTER enum, colonnes Prisma jamais écrites, read-then-write/transition one-shot race, @@unique + @@index redondant, DELETE row en transaction d'anonymisation, slug User.id (id auto-généré + validation Zod), template DB de test à droper après migration |
|
||||||
| `stripe.md` | Stripe, paiements, webhooks, subscriptions | billing_cycle_anchor vs current_period_end (+ SDK v20 par item), list() sans has_more, concurrence trial→payant, non-idempotence, 200 pendant processing, remboursement lié à la transaction (PaymentIntent), refund éligibilité mesurée sur visionnage réel |
|
| `stripe.md` | Stripe, paiements, webhooks, subscriptions | billing_cycle_anchor vs current_period_end (+ SDK v20 par item), list() sans has_more, concurrence trial→payant, non-idempotence, 200 pendant processing, remboursement lié à la transaction (PaymentIntent), refund éligibilité mesurée sur visionnage réel |
|
||||||
| `nestjs.md` | NestJS, controllers, providers | TooManyRequestsException NestJS 11, controller corrompu insertions, repository dead layer, interface provider incomplète, guard multi-statut READ_METHODS, bootstrap OK mais injection cassée (tsx watch → fix swc/.swcrc), guard écriture mode dégradé bloque le support |
|
| `nestjs.md` | NestJS, controllers, providers | TooManyRequestsException NestJS 11, controller corrompu insertions, repository dead layer, interface provider incomplète, guard multi-statut READ_METHODS, bootstrap OK mais injection cassée (tsx watch → fix swc/.swcrc), guard écriture mode dégradé bloque le support |
|
||||||
| `redis.md` | Redis, cache, quotas, TTL | Thrash connexion sous charge, entitlements TTL > SLA, compteurs in-memory, TTL heure locale ±12h, compensation incrBy non-atomique (quota fantôme + échec transaction DB), rate-limit à compteur partagé entre endpoints jumeaux |
|
| `redis.md` | Redis, cache, quotas, TTL | Thrash connexion sous charge, entitlements TTL > SLA, compteurs in-memory, TTL heure locale ±12h, compensation incrBy non-atomique (quota fantôme + échec transaction DB), rate-limit à compteur partagé entre endpoints jumeaux |
|
||||||
|
|||||||
@@ -262,28 +262,6 @@ get forum() {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<a id="risque-prisma-init-module-build"></a>
|
|
||||||
## Prisma initialisé au chargement de module — casse le build Next.js
|
|
||||||
|
|
||||||
### Risques
|
|
||||||
|
|
||||||
- Un import global qui initialise Prisma immédiatement peut faire échouer la collecte de pages/routes au build si `DATABASE_URL` n'est pas disponible dans l'environnement de build
|
|
||||||
|
|
||||||
### Symptômes
|
|
||||||
|
|
||||||
- `PrismaClientInitializationError` ou `Error: Environment variable not found: DATABASE_URL` au `next build`
|
|
||||||
- L'app tourne en dev mais le build CI échoue
|
|
||||||
|
|
||||||
### Bonnes pratiques / mitigations
|
|
||||||
|
|
||||||
- Préférer une initialisation lazy-safe : retarder l'accès DB au moment de l'appel métier
|
|
||||||
- Retourner un proxy qui lève une erreur claire uniquement lors du premier accès réel à la DB
|
|
||||||
- Ne jamais instancier `new PrismaClient()` au top-level d'un module importé par Next.js
|
|
||||||
|
|
||||||
- Contexte technique : Next.js App Router / Prisma — app-template-resto 16-03-2026
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<a id="risque-jest-clearallmocks-imbrique"></a>
|
<a id="risque-jest-clearallmocks-imbrique"></a>
|
||||||
## `jest.clearAllMocks()` dans des `beforeEach` imbriqués avec mocks Prisma
|
## `jest.clearAllMocks()` dans des `beforeEach` imbriqués avec mocks Prisma
|
||||||
|
|
||||||
|
|||||||
@@ -137,56 +137,6 @@ import { buttonStyles } from '@/components/ui/Button';
|
|||||||
<TouchableOpacity style={[buttonStyles.base, styles.facebookButton]} />
|
<TouchableOpacity style={[buttonStyles.base, styles.facebookButton]} />
|
||||||
```
|
```
|
||||||
|
|
||||||
<a id="pattern-tests-styles-sans-renderer"></a>
|
|
||||||
## Pattern : Tests de styles React Native sans renderer JSX
|
|
||||||
|
|
||||||
### Synthèse
|
|
||||||
|
|
||||||
- **Objectif** : tester les tokens et styles de composants React Native dans un environnement Jest `testEnvironment: node` sans renderer JSX.
|
|
||||||
- **Contexte** : config Jest avec `transform: { '^.+\\.ts$': 'ts-jest' }` — les `.tsx` ne sont pas transformés.
|
|
||||||
- **Quand l'utiliser** : tokens de thème, logique pure, valeurs de style exportées.
|
|
||||||
- **Quand l'éviter** : rendu conditionnel (styles dynamiques inline) — nécessite `@testing-library/react-native`.
|
|
||||||
|
|
||||||
### Analyse
|
|
||||||
|
|
||||||
- **Avantages** :
|
|
||||||
- teste que le composant utilise les bons tokens, pas seulement que les tokens ont des valeurs
|
|
||||||
- détecte les régressions de style sans renderer
|
|
||||||
- rapide, aucune config Jest supplémentaire
|
|
||||||
- **Limites / vigilance** :
|
|
||||||
- ne teste pas le style calculé au runtime (style conditionnel dynamique)
|
|
||||||
|
|
||||||
### Validation
|
|
||||||
|
|
||||||
- Validé le : 19-03-2026
|
|
||||||
- Contexte technique : React Native / Jest / ts-jest — app-alexandrie story 0.2
|
|
||||||
|
|
||||||
### Implémentation
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// Button.tsx — exporter le StyleSheet avec un nom préfixé
|
|
||||||
export const buttonStyles = StyleSheet.create({
|
|
||||||
base: { borderRadius: 20, height: 57 },
|
|
||||||
primary: { backgroundColor: colors.primary },
|
|
||||||
});
|
|
||||||
export function Button(...) { ... }
|
|
||||||
|
|
||||||
// ui-components.spec.ts — importer et vérifier les tokens
|
|
||||||
import { buttonStyles } from './Button';
|
|
||||||
import { colors } from '@/theme';
|
|
||||||
|
|
||||||
it('variante primary utilise colors.primary', () => {
|
|
||||||
expect(buttonStyles.primary.backgroundColor).toBe(colors.primary);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Deux niveaux de tests UI recommandés
|
|
||||||
|
|
||||||
1. `.spec.ts` (node) : tokens, valeurs, logique pure
|
|
||||||
2. `.spec.tsx` (config séparée avec renderer) : rendu visuel, interactions
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<a id="pattern-palette-light-dark-md3-usethemedcolors"></a>
|
<a id="pattern-palette-light-dark-md3-usethemedcolors"></a>
|
||||||
## Pattern : Palette light/dark MD3 + hook `useThemedColors` + dual export
|
## Pattern : Palette light/dark MD3 + hook `useThemedColors` + dual export
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user