nexu-app 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1192 -0
- package/package.json +43 -0
- package/templates/default/.changeset/config.json +11 -0
- package/templates/default/.eslintignore +16 -0
- package/templates/default/.eslintrc.js +67 -0
- package/templates/default/.github/actions/build/action.yml +35 -0
- package/templates/default/.github/actions/quality/action.yml +53 -0
- package/templates/default/.github/dependabot.yml +51 -0
- package/templates/default/.github/workflows/deploy-dev.yml +83 -0
- package/templates/default/.github/workflows/deploy-prod.yml +83 -0
- package/templates/default/.github/workflows/deploy-rec.yml +83 -0
- package/templates/default/.husky/commit-msg +1 -0
- package/templates/default/.husky/pre-commit +1 -0
- package/templates/default/.nexu-version +1 -0
- package/templates/default/.prettierignore +7 -0
- package/templates/default/.prettierrc +19 -0
- package/templates/default/.vscode/extensions.json +14 -0
- package/templates/default/.vscode/settings.json +36 -0
- package/templates/default/apps/gitkeep +0 -0
- package/templates/default/commitlint.config.js +26 -0
- package/templates/default/docker/docker-compose.dev.yml +49 -0
- package/templates/default/docker/docker-compose.prod.yml +64 -0
- package/templates/default/docker/docker-compose.yml +6 -0
- package/templates/default/docs/architecture.md +452 -0
- package/templates/default/docs/cli.md +330 -0
- package/templates/default/docs/contributing.md +462 -0
- package/templates/default/docs/scripts.md +460 -0
- package/templates/default/gitignore +44 -0
- package/templates/default/lintstagedrc.cjs +4 -0
- package/templates/default/package.json +51 -0
- package/templates/default/packages/auth/package.json +61 -0
- package/templates/default/packages/auth/src/components/ProtectedRoute.tsx +75 -0
- package/templates/default/packages/auth/src/components/SignInForm.tsx +153 -0
- package/templates/default/packages/auth/src/components/SignUpForm.tsx +179 -0
- package/templates/default/packages/auth/src/components/SocialButtons.tsx +147 -0
- package/templates/default/packages/auth/src/components/index.ts +4 -0
- package/templates/default/packages/auth/src/hooks/index.ts +4 -0
- package/templates/default/packages/auth/src/hooks/useAuth.ts +51 -0
- package/templates/default/packages/auth/src/hooks/useRequireAuth.ts +54 -0
- package/templates/default/packages/auth/src/hooks/useSession.ts +48 -0
- package/templates/default/packages/auth/src/hooks/useUser.ts +48 -0
- package/templates/default/packages/auth/src/index.ts +45 -0
- package/templates/default/packages/auth/src/next/index.ts +18 -0
- package/templates/default/packages/auth/src/next/middleware.ts +183 -0
- package/templates/default/packages/auth/src/next/server.ts +219 -0
- package/templates/default/packages/auth/src/providers/AuthContext.tsx +435 -0
- package/templates/default/packages/auth/src/providers/index.ts +1 -0
- package/templates/default/packages/auth/src/types/index.ts +284 -0
- package/templates/default/packages/auth/src/utils/api.ts +228 -0
- package/templates/default/packages/auth/src/utils/index.ts +3 -0
- package/templates/default/packages/auth/src/utils/oauth.ts +230 -0
- package/templates/default/packages/auth/src/utils/token.ts +204 -0
- package/templates/default/packages/auth/tsconfig.json +14 -0
- package/templates/default/packages/auth/tsup.config.ts +18 -0
- package/templates/default/packages/cache/package.json +26 -0
- package/templates/default/packages/cache/src/index.ts +137 -0
- package/templates/default/packages/cache/tsconfig.json +9 -0
- package/templates/default/packages/cache/tsup.config.ts +9 -0
- package/templates/default/packages/config/eslint/index.js +20 -0
- package/templates/default/packages/config/package.json +9 -0
- package/templates/default/packages/config/typescript/base.json +26 -0
- package/templates/default/packages/constants/package.json +26 -0
- package/templates/default/packages/constants/src/index.ts +121 -0
- package/templates/default/packages/constants/tsconfig.json +9 -0
- package/templates/default/packages/constants/tsup.config.ts +9 -0
- package/templates/default/packages/logger/package.json +27 -0
- package/templates/default/packages/logger/src/index.ts +197 -0
- package/templates/default/packages/logger/tsconfig.json +11 -0
- package/templates/default/packages/logger/tsup.config.ts +9 -0
- package/templates/default/packages/result/package.json +26 -0
- package/templates/default/packages/result/src/index.ts +142 -0
- package/templates/default/packages/result/tsconfig.json +9 -0
- package/templates/default/packages/result/tsup.config.ts +9 -0
- package/templates/default/packages/types/package.json +26 -0
- package/templates/default/packages/types/src/index.ts +78 -0
- package/templates/default/packages/types/tsconfig.json +9 -0
- package/templates/default/packages/types/tsup.config.ts +10 -0
- package/templates/default/packages/ui/package.json +38 -0
- package/templates/default/packages/ui/src/components/Button.tsx +58 -0
- package/templates/default/packages/ui/src/components/Card.tsx +85 -0
- package/templates/default/packages/ui/src/components/Input.tsx +45 -0
- package/templates/default/packages/ui/src/index.ts +15 -0
- package/templates/default/packages/ui/tsconfig.json +11 -0
- package/templates/default/packages/ui/tsup.config.ts +11 -0
- package/templates/default/packages/utils/package.json +30 -0
- package/templates/default/packages/utils/src/index.test.ts +130 -0
- package/templates/default/packages/utils/src/index.ts +154 -0
- package/templates/default/packages/utils/tsconfig.json +10 -0
- package/templates/default/packages/utils/tsup.config.ts +10 -0
- package/templates/default/pnpm-workspace.yaml +3 -0
- package/templates/default/scripts/audit.mjs +700 -0
- package/templates/default/scripts/deploy.mjs +40 -0
- package/templates/default/scripts/generate-app.mjs +808 -0
- package/templates/default/scripts/lib/package-manager.mjs +186 -0
- package/templates/default/scripts/setup.mjs +102 -0
- package/templates/default/services/.env.example +16 -0
- package/templates/default/services/docker-compose.yml +207 -0
- package/templates/default/services/grafana/provisioning/dashboards/dashboards.yml +11 -0
- package/templates/default/services/grafana/provisioning/datasources/datasources.yml +9 -0
- package/templates/default/services/postgres/init/gitkeep +2 -0
- package/templates/default/services/prometheus/prometheus.yml +13 -0
- package/templates/default/tsconfig.json +27 -0
- package/templates/default/turbo.json +40 -0
- package/templates/default/vitest.config.ts +15 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
version: '3.9'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
web:
|
|
5
|
+
build:
|
|
6
|
+
context: ..
|
|
7
|
+
dockerfile: apps/web/Dockerfile
|
|
8
|
+
target: development
|
|
9
|
+
volumes:
|
|
10
|
+
- ../apps/web:/app/apps/web
|
|
11
|
+
- ../packages:/app/packages
|
|
12
|
+
- /app/node_modules
|
|
13
|
+
- /app/apps/web/node_modules
|
|
14
|
+
ports:
|
|
15
|
+
- '3000:3000'
|
|
16
|
+
environment:
|
|
17
|
+
- NODE_ENV=development
|
|
18
|
+
- WATCHPACK_POLLING=true
|
|
19
|
+
command: pnpm dev
|
|
20
|
+
|
|
21
|
+
api:
|
|
22
|
+
build:
|
|
23
|
+
context: ..
|
|
24
|
+
dockerfile: apps/api/Dockerfile
|
|
25
|
+
target: development
|
|
26
|
+
volumes:
|
|
27
|
+
- ../apps/api:/app/apps/api
|
|
28
|
+
- ../packages:/app/packages
|
|
29
|
+
- /app/node_modules
|
|
30
|
+
- /app/apps/api/node_modules
|
|
31
|
+
ports:
|
|
32
|
+
- '4000:4000'
|
|
33
|
+
environment:
|
|
34
|
+
- NODE_ENV=development
|
|
35
|
+
command: pnpm dev
|
|
36
|
+
|
|
37
|
+
db:
|
|
38
|
+
image: postgres:16-alpine
|
|
39
|
+
environment:
|
|
40
|
+
POSTGRES_USER: postgres
|
|
41
|
+
POSTGRES_PASSWORD: postgres
|
|
42
|
+
POSTGRES_DB: nexu_dev
|
|
43
|
+
ports:
|
|
44
|
+
- '5432:5432'
|
|
45
|
+
volumes:
|
|
46
|
+
- postgres_dev_data:/var/lib/postgresql/data
|
|
47
|
+
|
|
48
|
+
volumes:
|
|
49
|
+
postgres_dev_data:
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
version: '3.9'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
web:
|
|
5
|
+
build:
|
|
6
|
+
context: ..
|
|
7
|
+
dockerfile: apps/web/Dockerfile
|
|
8
|
+
target: production
|
|
9
|
+
ports:
|
|
10
|
+
- '3000:3000'
|
|
11
|
+
environment:
|
|
12
|
+
- NODE_ENV=production
|
|
13
|
+
- NEXT_PUBLIC_API_URL=http://api:4000
|
|
14
|
+
depends_on:
|
|
15
|
+
- api
|
|
16
|
+
restart: unless-stopped
|
|
17
|
+
networks:
|
|
18
|
+
- app-network
|
|
19
|
+
|
|
20
|
+
api:
|
|
21
|
+
build:
|
|
22
|
+
context: ..
|
|
23
|
+
dockerfile: apps/api/Dockerfile
|
|
24
|
+
target: production
|
|
25
|
+
ports:
|
|
26
|
+
- '4000:4000'
|
|
27
|
+
environment:
|
|
28
|
+
- NODE_ENV=production
|
|
29
|
+
- DATABASE_URL=${DATABASE_URL}
|
|
30
|
+
- PORT=4000
|
|
31
|
+
depends_on:
|
|
32
|
+
- db
|
|
33
|
+
- redis
|
|
34
|
+
restart: unless-stopped
|
|
35
|
+
networks:
|
|
36
|
+
- app-network
|
|
37
|
+
|
|
38
|
+
db:
|
|
39
|
+
image: postgres:16-alpine
|
|
40
|
+
environment:
|
|
41
|
+
POSTGRES_USER: ${DB_USER:-postgres}
|
|
42
|
+
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
43
|
+
POSTGRES_DB: ${DB_NAME:-nexu}
|
|
44
|
+
volumes:
|
|
45
|
+
- postgres_data:/var/lib/postgresql/data
|
|
46
|
+
restart: unless-stopped
|
|
47
|
+
networks:
|
|
48
|
+
- app-network
|
|
49
|
+
|
|
50
|
+
redis:
|
|
51
|
+
image: redis:7-alpine
|
|
52
|
+
volumes:
|
|
53
|
+
- redis_data:/data
|
|
54
|
+
restart: unless-stopped
|
|
55
|
+
networks:
|
|
56
|
+
- app-network
|
|
57
|
+
|
|
58
|
+
networks:
|
|
59
|
+
app-network:
|
|
60
|
+
driver: bridge
|
|
61
|
+
|
|
62
|
+
volumes:
|
|
63
|
+
postgres_data:
|
|
64
|
+
redis_data:
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Ce document décrit l'architecture du monorepo Nexu.
|
|
4
|
+
|
|
5
|
+
## Vue d'ensemble
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
nexu/
|
|
9
|
+
├── apps/ # Applications
|
|
10
|
+
├── packages/ # Packages partagés
|
|
11
|
+
├── services/ # Services Docker externes
|
|
12
|
+
├── nexu-app/ # CLI
|
|
13
|
+
├── scripts/ # Scripts de build/automation
|
|
14
|
+
├── docker/ # Configuration Docker principale
|
|
15
|
+
└── .github/ # GitHub Actions workflows
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Composants principaux
|
|
19
|
+
|
|
20
|
+
### Apps (`apps/`)
|
|
21
|
+
|
|
22
|
+
Les applications sont des projets indépendants qui utilisent les packages partagés.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
apps/
|
|
26
|
+
├── web/ # Frontend (Next.js, Vite, etc.)
|
|
27
|
+
│ ├── src/
|
|
28
|
+
│ ├── docker/
|
|
29
|
+
│ │ └── Dockerfile
|
|
30
|
+
│ ├── docker-compose.yml
|
|
31
|
+
│ ├── docker-compose.prod.yml
|
|
32
|
+
│ └── package.json
|
|
33
|
+
└── api/ # Backend (Express, Fastify, etc.)
|
|
34
|
+
├── src/
|
|
35
|
+
├── docker/
|
|
36
|
+
│ └── Dockerfile
|
|
37
|
+
├── docker-compose.yml
|
|
38
|
+
├── docker-compose.prod.yml
|
|
39
|
+
└── package.json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Conventions:**
|
|
43
|
+
|
|
44
|
+
- Nom du package: `@repo/<app-name>`
|
|
45
|
+
- Chaque app a son propre Dockerfile
|
|
46
|
+
- Les apps sont indépendantes et peuvent être déployées séparément
|
|
47
|
+
|
|
48
|
+
### Packages (`packages/`)
|
|
49
|
+
|
|
50
|
+
Les packages partagés sont des bibliothèques réutilisables.
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
packages/
|
|
54
|
+
├── cache/ # Cache in-memory avec TTL
|
|
55
|
+
├── config/ # Configurations ESLint/TypeScript
|
|
56
|
+
│ ├── eslint-config/
|
|
57
|
+
│ └── typescript-config/
|
|
58
|
+
├── constants/ # Constantes partagées
|
|
59
|
+
├── logger/ # Logger structuré
|
|
60
|
+
├── result/ # Try/catch fonctionnel
|
|
61
|
+
├── types/ # Types TypeScript partagés
|
|
62
|
+
├── ui/ # Composants React
|
|
63
|
+
└── utils/ # Fonctions utilitaires
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Conventions:**
|
|
67
|
+
|
|
68
|
+
- Nom du package: `@repo/<package-name>`
|
|
69
|
+
- Chaque package expose un point d'entrée dans `src/index.ts`
|
|
70
|
+
- Les packages sont buildés avec `tsup`
|
|
71
|
+
|
|
72
|
+
### Services (`services/`)
|
|
73
|
+
|
|
74
|
+
Services Docker externes (bases de données, monitoring, etc.).
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
services/
|
|
78
|
+
├── docker-compose.yml # Configuration avec profiles
|
|
79
|
+
├── postgres/
|
|
80
|
+
│ └── init/
|
|
81
|
+
├── prometheus/
|
|
82
|
+
│ └── prometheus.yml
|
|
83
|
+
└── grafana/
|
|
84
|
+
└── dashboards/
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Profiles Docker:**
|
|
88
|
+
|
|
89
|
+
- `database`: PostgreSQL, Redis
|
|
90
|
+
- `messaging`: RabbitMQ, Kafka
|
|
91
|
+
- `monitoring`: Prometheus, Grafana
|
|
92
|
+
- `storage`: MinIO
|
|
93
|
+
- `search`: Elasticsearch
|
|
94
|
+
- `all`: Tous les services
|
|
95
|
+
|
|
96
|
+
### CLI (`nexu-app/`)
|
|
97
|
+
|
|
98
|
+
Outil CLI pour créer et gérer des projets Nexu.
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
nexu-app/
|
|
102
|
+
├── src/
|
|
103
|
+
│ ├── index.ts # Point d'entrée
|
|
104
|
+
│ ├── commands/
|
|
105
|
+
│ │ ├── init.ts # Création de projet
|
|
106
|
+
│ │ ├── update.ts # Mise à jour
|
|
107
|
+
│ │ └── add.ts # Ajout de composants
|
|
108
|
+
│ └── utils/
|
|
109
|
+
│ └── helpers.ts
|
|
110
|
+
├── templates/
|
|
111
|
+
│ └── default/ # Template par défaut
|
|
112
|
+
└── package.json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Dépendances entre packages
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
┌─────────────────────────────────────────────────────┐
|
|
119
|
+
│ APPS │
|
|
120
|
+
│ ┌─────────┐ ┌─────────┐ ┌─────────────────────┐ │
|
|
121
|
+
│ │ web │ │ api │ │ ...autres apps │ │
|
|
122
|
+
│ └────┬────┘ └────┬────┘ └──────────┬──────────┘ │
|
|
123
|
+
│ │ │ │ │
|
|
124
|
+
└───────┼────────────┼───────────────────┼────────────┘
|
|
125
|
+
│ │ │
|
|
126
|
+
▼ ▼ ▼
|
|
127
|
+
┌─────────────────────────────────────────────────────┐
|
|
128
|
+
│ PACKAGES │
|
|
129
|
+
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ │
|
|
130
|
+
│ │ types │ │ utils │ │ logger │ │ cache │ │
|
|
131
|
+
│ └─────────┘ └─────────┘ └─────────┘ └────────┘ │
|
|
132
|
+
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────┐ │
|
|
133
|
+
│ │ ui │ │constants│ │ result │ │ config │ │
|
|
134
|
+
│ └─────────┘ └─────────┘ └─────────┘ └────────┘ │
|
|
135
|
+
└─────────────────────────────────────────────────────┘
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Règles de dépendances:**
|
|
139
|
+
|
|
140
|
+
1. Les apps peuvent dépendre de n'importe quel package
|
|
141
|
+
2. Les packages ne dépendent pas des apps
|
|
142
|
+
3. Les packages peuvent dépendre d'autres packages
|
|
143
|
+
4. `config` (eslint, typescript) sont des dépendances de dev
|
|
144
|
+
|
|
145
|
+
## Configuration
|
|
146
|
+
|
|
147
|
+
### Turborepo (`turbo.json`)
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"tasks": {
|
|
152
|
+
"build": {
|
|
153
|
+
"dependsOn": ["^build"],
|
|
154
|
+
"outputs": ["dist/**", ".next/**"]
|
|
155
|
+
},
|
|
156
|
+
"dev": {
|
|
157
|
+
"cache": false,
|
|
158
|
+
"persistent": true
|
|
159
|
+
},
|
|
160
|
+
"lint": {
|
|
161
|
+
"dependsOn": ["^build"]
|
|
162
|
+
},
|
|
163
|
+
"test": {
|
|
164
|
+
"dependsOn": ["build"]
|
|
165
|
+
},
|
|
166
|
+
"typecheck": {
|
|
167
|
+
"dependsOn": ["^build"]
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Explications:**
|
|
174
|
+
|
|
175
|
+
- `^build`: Build les dépendances d'abord
|
|
176
|
+
- `outputs`: Fichiers à mettre en cache
|
|
177
|
+
- `persistent`: Pour les processus long-running (dev servers)
|
|
178
|
+
|
|
179
|
+
### Workspaces (`pnpm-workspace.yaml`)
|
|
180
|
+
|
|
181
|
+
```yaml
|
|
182
|
+
packages:
|
|
183
|
+
- 'apps/*'
|
|
184
|
+
- 'packages/*'
|
|
185
|
+
- 'nexu-app'
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### TypeScript
|
|
189
|
+
|
|
190
|
+
Chaque package hérite d'une config de base:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
// packages/*/tsconfig.json
|
|
194
|
+
{
|
|
195
|
+
"extends": "@repo/typescript-config/base.json",
|
|
196
|
+
"compilerOptions": {
|
|
197
|
+
"outDir": "dist",
|
|
198
|
+
"rootDir": "src"
|
|
199
|
+
},
|
|
200
|
+
"include": ["src/**/*"]
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Configs disponibles:
|
|
205
|
+
|
|
206
|
+
- `@repo/typescript-config/base.json` - Configuration de base
|
|
207
|
+
- `@repo/typescript-config/node.json` - Pour Node.js
|
|
208
|
+
- `@repo/typescript-config/react.json` - Pour React/Next.js
|
|
209
|
+
|
|
210
|
+
### ESLint
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
// packages/*/.eslintrc.js
|
|
214
|
+
module.exports = {
|
|
215
|
+
extends: ['@repo/eslint-config/base'],
|
|
216
|
+
// ...
|
|
217
|
+
};
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Configs disponibles:
|
|
221
|
+
|
|
222
|
+
- `@repo/eslint-config/base` - Configuration de base
|
|
223
|
+
- `@repo/eslint-config/react` - Pour React
|
|
224
|
+
|
|
225
|
+
## Docker
|
|
226
|
+
|
|
227
|
+
### Architecture Docker
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
231
|
+
│ docker-compose.yml │
|
|
232
|
+
│ (docker/docker-compose.yml) │
|
|
233
|
+
│ │
|
|
234
|
+
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
|
235
|
+
│ │ apps/web/ │ │ apps/api/ │ │
|
|
236
|
+
│ │ docker-compose.yml │ │ docker-compose.yml │ │
|
|
237
|
+
│ └──────────────────────┘ └──────────────────────┘ │
|
|
238
|
+
└─────────────────────────────────────────────────────────────┘
|
|
239
|
+
│
|
|
240
|
+
▼
|
|
241
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
242
|
+
│ services/ │
|
|
243
|
+
│ docker-compose.yml │
|
|
244
|
+
│ │
|
|
245
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
246
|
+
│ │ postgres │ │ redis │ │ rabbitmq │ │ grafana │ │
|
|
247
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
248
|
+
└─────────────────────────────────────────────────────────────┘
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Dockerfile multi-stage
|
|
252
|
+
|
|
253
|
+
```dockerfile
|
|
254
|
+
# Base
|
|
255
|
+
FROM node:20-alpine AS base
|
|
256
|
+
RUN corepack enable && corepack prepare pnpm@9 --activate
|
|
257
|
+
WORKDIR /app
|
|
258
|
+
|
|
259
|
+
# Dependencies
|
|
260
|
+
FROM base AS deps
|
|
261
|
+
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
|
|
262
|
+
COPY apps/<app>/package.json ./apps/<app>/
|
|
263
|
+
COPY packages/*/package.json ./packages/
|
|
264
|
+
RUN pnpm install --frozen-lockfile
|
|
265
|
+
|
|
266
|
+
# Development
|
|
267
|
+
FROM base AS development
|
|
268
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
269
|
+
COPY . .
|
|
270
|
+
WORKDIR /app/apps/<app>
|
|
271
|
+
CMD ["pnpm", "dev"]
|
|
272
|
+
|
|
273
|
+
# Builder
|
|
274
|
+
FROM base AS builder
|
|
275
|
+
COPY --from=deps /app/node_modules ./node_modules
|
|
276
|
+
COPY . .
|
|
277
|
+
RUN pnpm turbo build --filter=@repo/<app>
|
|
278
|
+
|
|
279
|
+
# Production
|
|
280
|
+
FROM node:20-alpine AS production
|
|
281
|
+
WORKDIR /app
|
|
282
|
+
COPY --from=builder /app/apps/<app>/dist ./dist
|
|
283
|
+
CMD ["node", "dist/index.js"]
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## CI/CD
|
|
287
|
+
|
|
288
|
+
### Workflow GitHub Actions
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
.github/
|
|
292
|
+
└── workflows/
|
|
293
|
+
├── ci.yml # Lint, test, build
|
|
294
|
+
├── deploy-dev.yml # Déploiement dev
|
|
295
|
+
├── deploy-rec.yml # Déploiement recette
|
|
296
|
+
└── deploy-prod.yml # Déploiement production
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Pipeline CI
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
|
|
303
|
+
│ Lint │ -> │ Test │ -> │ Build │ -> │ Push │
|
|
304
|
+
└─────────┘ └─────────┘ └─────────┘ └─────────┘
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Branches et environnements
|
|
308
|
+
|
|
309
|
+
| Branche | Environnement | Trigger |
|
|
310
|
+
| ------- | ------------- | ------- |
|
|
311
|
+
| `dev` | development | Push |
|
|
312
|
+
| `rec` | recette | Push |
|
|
313
|
+
| `main` | production | Push |
|
|
314
|
+
|
|
315
|
+
## Cache et performances
|
|
316
|
+
|
|
317
|
+
### Turborepo Remote Cache
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Configuration
|
|
321
|
+
npx turbo login
|
|
322
|
+
npx turbo link
|
|
323
|
+
|
|
324
|
+
# Variables d'environnement
|
|
325
|
+
TURBO_TOKEN=xxx
|
|
326
|
+
TURBO_TEAM=xxx
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Cache local
|
|
330
|
+
|
|
331
|
+
Les outputs sont cachés localement dans:
|
|
332
|
+
|
|
333
|
+
- `.turbo/` - Cache Turborepo
|
|
334
|
+
- `node_modules/.cache/` - Cache des outils
|
|
335
|
+
|
|
336
|
+
### Optimisations
|
|
337
|
+
|
|
338
|
+
1. **Parallel builds** - Turborepo exécute les tâches en parallèle
|
|
339
|
+
2. **Incremental builds** - Seuls les packages modifiés sont rebuild
|
|
340
|
+
3. **Remote caching** - Partage du cache entre CI et développeurs
|
|
341
|
+
4. **Hoisting** - pnpm hoist les dépendances communes
|
|
342
|
+
|
|
343
|
+
## Patterns de code
|
|
344
|
+
|
|
345
|
+
### Packages partagés
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
// packages/utils/src/index.ts
|
|
349
|
+
export * from './string';
|
|
350
|
+
export * from './array';
|
|
351
|
+
export * from './object';
|
|
352
|
+
|
|
353
|
+
// packages/utils/src/string.ts
|
|
354
|
+
export function capitalize(str: string): string {
|
|
355
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Utilisation dans les apps
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
// apps/web/src/utils.ts
|
|
363
|
+
import { capitalize } from '@repo/utils';
|
|
364
|
+
import type { User } from '@repo/types';
|
|
365
|
+
import { logger } from '@repo/logger';
|
|
366
|
+
|
|
367
|
+
export function formatUser(user: User): string {
|
|
368
|
+
logger.debug('Formatting user', { userId: user.id });
|
|
369
|
+
return capitalize(user.name);
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Error handling avec Result
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import { tryCatchAsync, match } from '@repo/result';
|
|
377
|
+
|
|
378
|
+
const result = await tryCatchAsync(() => fetchUser(id));
|
|
379
|
+
|
|
380
|
+
return match(result, {
|
|
381
|
+
ok: user => ({ status: 200, body: user }),
|
|
382
|
+
err: error => ({ status: 500, body: { error: error.message } }),
|
|
383
|
+
});
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## Sécurité
|
|
387
|
+
|
|
388
|
+
### Bonnes pratiques
|
|
389
|
+
|
|
390
|
+
1. **Secrets** - Jamais de secrets hardcodés, utiliser les variables d'environnement
|
|
391
|
+
2. **Dependencies** - Audit régulier avec `pnpm audit`
|
|
392
|
+
3. **Types** - TypeScript strict mode activé
|
|
393
|
+
4. **Validation** - Validation des entrées avec zod ou similaire
|
|
394
|
+
|
|
395
|
+
### Audit automatique
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
# Audit complet
|
|
399
|
+
pnpm audit
|
|
400
|
+
|
|
401
|
+
# Vérification en CI
|
|
402
|
+
pnpm audit:security
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Gestion des secrets
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
# .env.local (non commité)
|
|
409
|
+
DATABASE_URL=postgres://...
|
|
410
|
+
API_KEY=xxx
|
|
411
|
+
|
|
412
|
+
# .env.example (commité)
|
|
413
|
+
DATABASE_URL=postgres://user:pass@localhost:5432/db
|
|
414
|
+
API_KEY=your-api-key
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## Monitoring
|
|
418
|
+
|
|
419
|
+
### Logs structurés
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
import { logger } from '@repo/logger';
|
|
423
|
+
|
|
424
|
+
logger.info('Request received', {
|
|
425
|
+
method: req.method,
|
|
426
|
+
path: req.path,
|
|
427
|
+
userId: user?.id,
|
|
428
|
+
});
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Métriques
|
|
432
|
+
|
|
433
|
+
Prometheus et Grafana sont préconfigurés dans `services/`.
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
# Démarrer le monitoring
|
|
437
|
+
docker compose -f services/docker-compose.yml --profile monitoring up -d
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Health checks
|
|
441
|
+
|
|
442
|
+
Chaque app devrait exposer un endpoint `/health`:
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
app.get('/health', (req, res) => {
|
|
446
|
+
res.json({
|
|
447
|
+
status: 'ok',
|
|
448
|
+
timestamp: new Date().toISOString(),
|
|
449
|
+
uptime: process.uptime(),
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
```
|