project-mcp-server 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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/dist/config.d.ts +15 -0
  4. package/dist/config.js +38 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +28 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/scanner/actions.d.ts +9 -0
  10. package/dist/scanner/actions.js +77 -0
  11. package/dist/scanner/actions.js.map +1 -0
  12. package/dist/scanner/cache.d.ts +4 -0
  13. package/dist/scanner/cache.js +34 -0
  14. package/dist/scanner/cache.js.map +1 -0
  15. package/dist/scanner/components.d.ts +17 -0
  16. package/dist/scanner/components.js +74 -0
  17. package/dist/scanner/components.js.map +1 -0
  18. package/dist/scanner/prisma.d.ts +17 -0
  19. package/dist/scanner/prisma.js +75 -0
  20. package/dist/scanner/prisma.js.map +1 -0
  21. package/dist/scanner/routes.d.ts +11 -0
  22. package/dist/scanner/routes.js +98 -0
  23. package/dist/scanner/routes.js.map +1 -0
  24. package/dist/setup.d.ts +10 -0
  25. package/dist/setup.js +289 -0
  26. package/dist/setup.js.map +1 -0
  27. package/dist/tools/env/index.d.ts +2 -0
  28. package/dist/tools/env/index.js +152 -0
  29. package/dist/tools/env/index.js.map +1 -0
  30. package/dist/tools/generate/index.d.ts +2 -0
  31. package/dist/tools/generate/index.js +320 -0
  32. package/dist/tools/generate/index.js.map +1 -0
  33. package/dist/tools/project/index.d.ts +2 -0
  34. package/dist/tools/project/index.js +193 -0
  35. package/dist/tools/project/index.js.map +1 -0
  36. package/package.json +35 -0
  37. package/skills/commit.md +109 -0
  38. package/skills/infra.md +218 -0
  39. package/skills/nextauth.md +256 -0
  40. package/skills/nextjs.md +262 -0
  41. package/skills/prisma.md +281 -0
  42. package/skills/project-intelligence.SKILL.md +141 -0
  43. package/skills/security.md +353 -0
  44. package/skills/shadcn.md +299 -0
  45. package/skills/testing.md +188 -0
  46. package/skills/zod.md +253 -0
@@ -0,0 +1,193 @@
1
+ import { z } from "zod";
2
+ import { scanRoutes } from "../../scanner/routes.js";
3
+ import { scanActions } from "../../scanner/actions.js";
4
+ import { scanPrismaSchemas } from "../../scanner/prisma.js";
5
+ import { scanComponents } from "../../scanner/components.js";
6
+ import { invalidate } from "../../scanner/cache.js";
7
+ import { config } from "../../config.js";
8
+ export function registerProjectTools(server) {
9
+ // ─── project_scan ──────────────────────────────────────────────────────────
10
+ server.registerTool("project_scan", {
11
+ title: "Escanear proyecto completo",
12
+ description: `Escanea el proyecto y devuelve un resumen de rutas, Server Actions,
13
+ schemas de Prisma y componentes instalados. Útil al inicio de una sesión
14
+ para tener el mapa completo del proyecto.
15
+
16
+ Returns: resumen con conteos y listado de entidades por categoría.`,
17
+ inputSchema: z.object({
18
+ force_refresh: z.boolean().default(false)
19
+ .describe("Forzar re-escaneo ignorando el cache")
20
+ }).strict(),
21
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: false }
22
+ }, async ({ force_refresh }) => {
23
+ if (force_refresh)
24
+ invalidate();
25
+ const [routes, actions, models, components] = await Promise.all([
26
+ scanRoutes(),
27
+ scanActions(),
28
+ scanPrismaSchemas(),
29
+ scanComponents()
30
+ ]);
31
+ const summary = {
32
+ projectRoot: config.projectRoot,
33
+ routes: {
34
+ total: routes.length,
35
+ pages: routes.filter(r => r.type === "page").length,
36
+ apiHandlers: routes.filter(r => r.type === "route-handler").length,
37
+ dynamic: routes.filter(r => r.dynamicParams.length > 0).length,
38
+ clientComponents: routes.filter(r => r.rendering === "client").length
39
+ },
40
+ actions: {
41
+ total: actions.length,
42
+ withAuth: actions.filter(a => a.hasAuth).length,
43
+ withZod: actions.filter(a => a.zodSchema).length
44
+ },
45
+ prisma: {
46
+ totalModels: models.length,
47
+ bySchema: Object.fromEntries([...new Set(models.map(m => m.schema))].map(s => [
48
+ s, models.filter(m => m.schema === s).length
49
+ ]))
50
+ },
51
+ components: {
52
+ shadcnInstalled: components.ui.length,
53
+ custom: components.custom.length,
54
+ byFeature: Object.fromEntries([...new Set(components.custom.map(c => c.feature))].map(f => [
55
+ f, components.custom.filter(c => c.feature === f).length
56
+ ]))
57
+ }
58
+ };
59
+ const text = [
60
+ `## Proyecto: ${config.projectRoot.split("/").pop()}`,
61
+ ``,
62
+ `### Rutas (${summary.routes.total})`,
63
+ `- Páginas: ${summary.routes.pages} · API handlers: ${summary.routes.apiHandlers}`,
64
+ `- Rutas dinámicas: ${summary.routes.dynamic} · Client components: ${summary.routes.clientComponents}`,
65
+ ``,
66
+ `### Server Actions (${summary.actions.total})`,
67
+ `- Con autenticación: ${summary.actions.withAuth} · Con validación Zod: ${summary.actions.withZod}`,
68
+ ``,
69
+ `### Prisma (${summary.prisma.totalModels} modelos)`,
70
+ ...Object.entries(summary.prisma.bySchema).map(([s, n]) => `- Schema ${s}: ${n} modelos`),
71
+ ``,
72
+ `### Componentes`,
73
+ `- shadcn/ui instalados: ${summary.components.shadcnInstalled}`,
74
+ `- Componentes propios: ${summary.components.custom}`,
75
+ ].join("\n");
76
+ return { content: [{ type: "text", text }], structuredContent: summary };
77
+ });
78
+ // ─── project_routes ────────────────────────────────────────────────────────
79
+ server.registerTool("project_routes", {
80
+ title: "Listar rutas del proyecto",
81
+ description: `Lista todas las rutas del App Router con sus propiedades.
82
+ Útil para entender la estructura de navegación antes de crear una página nueva
83
+ o agregar un route handler.
84
+
85
+ Args:
86
+ - filter: filtrar por "pages", "api", o "all" (default)
87
+ - dynamic_only: mostrar solo rutas con parámetros dinámicos
88
+
89
+ Returns: array de rutas con path, tipo, rendering, params dinámicos.`,
90
+ inputSchema: z.object({
91
+ filter: z.enum(["all", "pages", "api"]).default("all"),
92
+ dynamic_only: z.boolean().default(false)
93
+ }).strict(),
94
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: false }
95
+ }, async ({ filter, dynamic_only }) => {
96
+ let routes = await scanRoutes();
97
+ if (filter === "pages")
98
+ routes = routes.filter(r => r.type === "page");
99
+ if (filter === "api")
100
+ routes = routes.filter(r => r.type === "route-handler");
101
+ if (dynamic_only)
102
+ routes = routes.filter(r => r.dynamicParams.length > 0);
103
+ const text = routes.map(r => {
104
+ const flags = [
105
+ r.rendering === "client" ? "client" : "rsc",
106
+ r.dynamicParams.length > 0 ? `[${r.dynamicParams.join(", ")}]` : null,
107
+ r.methods ? r.methods.join("|") : null,
108
+ r.hasLoading ? "loading" : null,
109
+ r.hasError ? "error" : null,
110
+ ].filter(Boolean).join(" · ");
111
+ return `${r.path} ${flags}`;
112
+ }).join("\n");
113
+ return {
114
+ content: [{ type: "text", text: routes.length > 0 ? text : "No se encontraron rutas." }],
115
+ structuredContent: { routes, total: routes.length }
116
+ };
117
+ });
118
+ // ─── project_actions ───────────────────────────────────────────────────────
119
+ server.registerTool("project_actions", {
120
+ title: "Listar Server Actions",
121
+ description: `Lista todas las Server Actions del proyecto con sus schemas de validación.
122
+ Útil antes de crear una nueva action para ver los patrones existentes
123
+ y evitar duplicaciones.
124
+
125
+ Returns: array de actions con nombre, archivo, schema Zod, parámetros y flags.`,
126
+ inputSchema: z.object({
127
+ feature: z.string().optional()
128
+ .describe("Filtrar por feature (ej: 'users', 'posts')")
129
+ }).strict(),
130
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: false }
131
+ }, async ({ feature }) => {
132
+ let actions = await scanActions();
133
+ if (feature) {
134
+ actions = actions.filter(a => a.file.toLowerCase().includes(feature.toLowerCase()));
135
+ }
136
+ const text = actions.map(a => {
137
+ const flags = [
138
+ a.hasAuth ? "auth" : "no-auth",
139
+ a.zodSchema ? `zod:${a.zodSchema}` : "no-zod",
140
+ a.hasRevalidate ? "revalidates" : null
141
+ ].filter(Boolean).join(" · ");
142
+ return `${a.name} (${a.file}) ${flags}`;
143
+ }).join("\n");
144
+ return {
145
+ content: [{ type: "text", text: actions.length > 0 ? text : "No se encontraron Server Actions." }],
146
+ structuredContent: { actions, total: actions.length }
147
+ };
148
+ });
149
+ // ─── project_models ────────────────────────────────────────────────────────
150
+ server.registerTool("project_models", {
151
+ title: "Listar modelos de Prisma",
152
+ description: `Lista todos los modelos de Prisma con sus campos y schema.
153
+ Útil antes de crear una relación, migration, o Server Action
154
+ para conocer la estructura exacta de los datos.
155
+
156
+ Args:
157
+ - schema: filtrar por schema (auth | rbac | audit | base)
158
+ - model_name: buscar un modelo específico por nombre
159
+
160
+ Returns: modelos con campos, tipos, relaciones y atributos.`,
161
+ inputSchema: z.object({
162
+ schema: z.enum(["auth", "rbac", "audit", "base"]).optional(),
163
+ model_name: z.string().optional()
164
+ }).strict(),
165
+ annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
166
+ }, async ({ schema, model_name }) => {
167
+ let models = await scanPrismaSchemas();
168
+ if (schema)
169
+ models = models.filter(m => m.schema === schema);
170
+ if (model_name)
171
+ models = models.filter(m => m.name.toLowerCase().includes(model_name.toLowerCase()));
172
+ const text = models.map(m => {
173
+ const fields = m.fields
174
+ .filter(f => !f.isRelation)
175
+ .map(f => ` ${f.name}: ${f.type}${f.isOptional ? "?" : ""}${f.isArray ? "[]" : ""}`)
176
+ .join("\n");
177
+ const relations = m.fields
178
+ .filter(f => f.isRelation)
179
+ .map(f => ` ${f.name} → ${f.type}`)
180
+ .join("\n");
181
+ return [
182
+ `### ${m.name} (@schema: ${m.schema})`,
183
+ fields,
184
+ relations ? ` --- relaciones ---\n${relations}` : ""
185
+ ].filter(Boolean).join("\n");
186
+ }).join("\n\n");
187
+ return {
188
+ content: [{ type: "text", text: models.length > 0 ? text : "No se encontraron modelos." }],
189
+ structuredContent: { models, total: models.length }
190
+ };
191
+ });
192
+ }
193
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/project/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "project-mcp-server",
3
+ "version": "2.0.0",
4
+ "description": "MCP server con inteligencia de proyecto, control de entorno y generación de código para Next.js + Prisma",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "project-mcp": "dist/index.js",
9
+ "project-mcp-setup": "dist/setup.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "start": "node dist/index.js",
15
+ "setup": "node dist/setup.js",
16
+ "inspect": "npx @modelcontextprotocol/inspector node dist/index.js"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/fernandosecchi/project-mcp-server.git"
21
+ },
22
+ "keywords": ["mcp", "claude-code", "nextjs", "prisma", "ai-tools"],
23
+ "author": "Fernando Secchi",
24
+ "license": "MIT",
25
+ "files": ["dist", "skills", "README.md", "LICENSE"],
26
+ "engines": { "node": ">=20" },
27
+ "dependencies": {
28
+ "@modelcontextprotocol/sdk": "^1.12.0",
29
+ "zod": "^3.24.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "typescript": "^5.9.0"
34
+ }
35
+ }
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: commit
3
+ description: "Activar cuando se hace un commit, se abre un Pull Request o se prepara un release"
4
+ license: MIT
5
+ metadata:
6
+ version: "1.0.0"
7
+ ---
8
+
9
+ # Skill: Commits, PRs y releases
10
+
11
+ ## Cuándo cargar esta skill
12
+ - Hacer un commit
13
+ - Abrir o cerrar un Pull Request
14
+ - Crear una release
15
+ - Revisar el estado del repo
16
+
17
+ ---
18
+
19
+ ## Conventional Commits
20
+
21
+ Formato: `tipo(scope): descripción en minúsculas`
22
+
23
+ | Tipo | Cuándo usarlo |
24
+ |---|---|
25
+ | `feat` | Nueva feature visible para el usuario |
26
+ | `fix` | Bugfix |
27
+ | `refactor` | Cambio de código sin cambio de comportamiento |
28
+ | `chore` | Configuración, deps, tooling |
29
+ | `docs` | Solo documentación |
30
+ | `test` | Solo tests |
31
+ | `perf` | Mejora de performance |
32
+ | `ci` | Cambios en CI/CD |
33
+
34
+ ```bash
35
+ # Ejemplos correctos
36
+ git commit -m "feat(auth): agregar login con credentials"
37
+ git commit -m "fix(prisma): corregir query de roles en schema rbac"
38
+ git commit -m "chore(deps): actualizar next a 16.1.0"
39
+ git commit -m "refactor(users): extraer helper de permisos a lib/auth"
40
+
41
+ # Breaking change
42
+ git commit -m "feat(api)!: cambiar estructura de respuesta de /api/users"
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Flujo de trabajo con ramas
48
+
49
+ ```bash
50
+ # Nueva feature
51
+ git checkout -b feat/nombre-descriptivo
52
+
53
+ # Bugfix
54
+ git checkout -b fix/descripcion-del-bug
55
+
56
+ # Chore / refactor
57
+ git checkout -b chore/descripcion
58
+
59
+ # Ver estado antes de commitear
60
+ git status
61
+ git diff
62
+
63
+ # Commitear
64
+ git add .
65
+ git commit -m "feat(scope): descripción"
66
+
67
+ # Push
68
+ git push origin feat/nombre-descriptivo
69
+ ```
70
+
71
+ ---
72
+
73
+ ## Antes de cada commit — checklist
74
+
75
+ ```bash
76
+ # 1. Tipos correctos
77
+ pnpm type-check
78
+
79
+ # 2. Linting
80
+ pnpm lint
81
+
82
+ # 3. Si hay tests
83
+ pnpm test
84
+
85
+ # 4. Build (en PRs importantes)
86
+ pnpm build
87
+ ```
88
+
89
+ ---
90
+
91
+ ## PR — descripción mínima esperada
92
+
93
+ ```markdown
94
+ ## ¿Qué hace este PR?
95
+ Breve descripción del cambio.
96
+
97
+ ## Tipo de cambio
98
+ - [ ] Nueva feature
99
+ - [ ] Bugfix
100
+ - [ ] Refactor
101
+ - [ ] Chore
102
+
103
+ ## Checklist
104
+ - [ ] `pnpm type-check` pasa
105
+ - [ ] `pnpm lint` pasa
106
+ - [ ] Tests actualizados (si aplica)
107
+ - [ ] Migrations incluidas (si aplica)
108
+ - [ ] Variables de entorno documentadas en .env.example (si aplica)
109
+ ```
@@ -0,0 +1,218 @@
1
+ ---
2
+ name: infra
3
+ description: "Activar cuando se trabaja con Docker, variables de entorno, setup de base de datos o configuracion del entorno de desarrollo"
4
+ license: MIT
5
+ metadata:
6
+ version: "1.0.0"
7
+ ---
8
+
9
+ # Skill: Infra — Docker, variables de entorno, base de datos local
10
+
11
+ ## Cuándo cargar esta skill
12
+ - Levantar o modificar servicios de Docker
13
+ - Trabajar con variables de entorno
14
+ - Setup inicial del proyecto
15
+ - Troubleshooting de conexiones a DB
16
+
17
+ ---
18
+
19
+ ## Docker Compose — servicios locales
20
+
21
+ ```yaml
22
+ # docker-compose.yml
23
+ services:
24
+ postgres:
25
+ image: postgres:16-alpine
26
+ container_name: app_postgres
27
+ environment:
28
+ POSTGRES_USER: ${POSTGRES_USER:-appuser}
29
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-apppassword}
30
+ POSTGRES_DB: ${POSTGRES_DB:-appdb}
31
+ ports:
32
+ - "5432:5432"
33
+ volumes:
34
+ - postgres_data:/var/lib/postgresql/data
35
+ healthcheck:
36
+ test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-appuser}"]
37
+ interval: 5s
38
+ timeout: 5s
39
+ retries: 5
40
+
41
+ mysql:
42
+ image: mysql:5.7
43
+ container_name: app_mysql
44
+ environment:
45
+ MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
46
+ MYSQL_DATABASE: ${MYSQL_DB:-legacydb}
47
+ MYSQL_USER: ${MYSQL_USER:-appuser}
48
+ MYSQL_PASSWORD: ${MYSQL_PASSWORD:-apppassword}
49
+ ports:
50
+ - "3306:3306"
51
+ volumes:
52
+ - mysql_data:/var/lib/mysql
53
+ healthcheck:
54
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
55
+ interval: 5s
56
+ timeout: 5s
57
+ retries: 10
58
+
59
+ volumes:
60
+ postgres_data:
61
+ mysql_data:
62
+ ```
63
+
64
+ ### Comandos Docker frecuentes
65
+
66
+ ```bash
67
+ # Levantar todo en background
68
+ docker compose up -d
69
+
70
+ # Ver logs en vivo
71
+ docker compose logs -f postgres
72
+ docker compose logs -f mysql
73
+
74
+ # Reiniciar un servicio
75
+ docker compose restart postgres
76
+
77
+ # Bajar todo (conserva volúmenes)
78
+ docker compose down
79
+
80
+ # Bajar y eliminar volúmenes (reset total de datos)
81
+ docker compose down -v
82
+
83
+ # Ver estado de los servicios
84
+ docker compose ps
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Variables de entorno
90
+
91
+ ```bash
92
+ # .env.local (desarrollo local — no commitear)
93
+ # .env.example (template — sí commitear, sin valores reales)
94
+
95
+ # Base de datos PostgreSQL
96
+ DATABASE_URL="postgresql://appuser:apppassword@localhost:5432/appdb"
97
+
98
+ # Base de datos MySQL
99
+ MYSQL_DATABASE_URL="mysql://appuser:apppassword@localhost:3306/legacydb"
100
+
101
+ # NextAuth
102
+ NEXTAUTH_SECRET="genera-con: openssl rand -base64 32"
103
+ NEXTAUTH_URL="http://localhost:3000"
104
+
105
+ # App
106
+ NEXT_PUBLIC_APP_URL="http://localhost:3000"
107
+ NODE_ENV="development"
108
+ ```
109
+
110
+ ### Generar NEXTAUTH_SECRET
111
+
112
+ ```bash
113
+ openssl rand -base64 32
114
+ # Pegar el resultado en NEXTAUTH_SECRET
115
+ ```
116
+
117
+ ### Validar variables de entorno al iniciar
118
+
119
+ ```typescript
120
+ // lib/env.ts — validación con Zod al startup
121
+ import { z } from "zod"
122
+
123
+ const EnvSchema = z.object({
124
+ DATABASE_URL: z.string().url(),
125
+ MYSQL_DATABASE_URL: z.string().url(),
126
+ NEXTAUTH_SECRET: z.string().min(32),
127
+ NEXTAUTH_URL: z.string().url(),
128
+ NODE_ENV: z.enum(["development", "test", "production"]).default("development")
129
+ })
130
+
131
+ export const env = EnvSchema.parse(process.env)
132
+
133
+ // Importar en lib/db/postgres.ts, lib/auth/config.ts, etc.
134
+ // Si falta una variable, el error explota al iniciar → fail fast
135
+ ```
136
+
137
+ ---
138
+
139
+ ## Setup inicial completo
140
+
141
+ ```bash
142
+ # 1. Instalar dependencias
143
+ pnpm install
144
+
145
+ # 2. Copiar variables de entorno
146
+ cp .env.example .env.local
147
+ # Editar .env.local con los valores correctos
148
+
149
+ # 3. Levantar bases de datos
150
+ docker compose up -d
151
+
152
+ # Esperar a que estén ready (healthcheck)
153
+ docker compose ps # status debe ser "healthy"
154
+
155
+ # 4. Correr migrations de Prisma
156
+ pnpm prisma migrate dev
157
+
158
+ # 5. Generar cliente Prisma
159
+ pnpm prisma generate
160
+
161
+ # 6. Correr seeds
162
+ pnpm tsx prisma/seeds/roles.ts
163
+ pnpm tsx prisma/seeds/admin-user.ts
164
+
165
+ # 7. Iniciar dev server
166
+ pnpm dev
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Troubleshooting de conexiones
172
+
173
+ ```bash
174
+ # PostgreSQL — verificar que acepta conexiones
175
+ docker compose exec postgres pg_isready -U appuser
176
+
177
+ # Conectarse con psql
178
+ docker compose exec postgres psql -U appuser -d appdb
179
+
180
+ # MySQL — verificar conexión
181
+ docker compose exec mysql mysqladmin ping -h localhost -u appuser -p
182
+
183
+ # Conectarse con mysql CLI
184
+ docker compose exec mysql mysql -u appuser -p legacydb
185
+
186
+ # Ver logs de error de conexión
187
+ docker compose logs postgres | grep -i error
188
+ docker compose logs mysql | grep -i error
189
+
190
+ # Si Prisma no conecta — verificar DATABASE_URL
191
+ pnpm prisma db pull # Si conecta, lista las tablas existentes
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Scripts útiles en package.json
197
+
198
+ ```json
199
+ {
200
+ "scripts": {
201
+ "dev": "next dev --turbo",
202
+ "build": "next build",
203
+ "start": "next start",
204
+ "lint": "next lint",
205
+ "type-check": "tsc --noEmit",
206
+ "db:up": "docker compose up -d",
207
+ "db:down": "docker compose down",
208
+ "db:reset": "docker compose down -v && docker compose up -d",
209
+ "db:migrate": "prisma migrate dev",
210
+ "db:generate": "prisma generate",
211
+ "db:studio": "prisma studio",
212
+ "db:seed": "tsx prisma/seeds/index.ts",
213
+ "setup": "pnpm install && pnpm db:up && pnpm db:migrate && pnpm db:seed"
214
+ }
215
+ }
216
+ ```
217
+
218
+ Con `pnpm setup` un desarrollador nuevo levanta todo el entorno en un comando.