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,281 @@
1
+ ---
2
+ name: prisma
3
+ description: "Activar cuando se modifican schemas de Prisma, se escriben queries de base de datos o se trabaja con migraciones"
4
+ license: MIT
5
+ metadata:
6
+ version: "1.0.0"
7
+ ---
8
+
9
+ # Skill: Prisma 7 — multi-schema
10
+
11
+ ## Cuándo cargar esta skill
12
+ - Modificar o crear schemas de Prisma
13
+ - Escribir queries de base de datos
14
+ - Crear o correr migrations
15
+ - Escribir seeds
16
+ - Trabajar con el cliente PostgreSQL o MySQL
17
+
18
+ ---
19
+
20
+ ## Arquitectura de clientes
21
+
22
+ Este proyecto tiene **dos conexiones** separadas:
23
+
24
+ ```typescript
25
+ // lib/db/postgres.ts — cliente principal (auth, rbac, audit, base)
26
+ import { PrismaClient } from "@prisma/client"
27
+ import { PrismaPg } from "@prisma/adapter-pg"
28
+ import { Pool } from "pg"
29
+
30
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL })
31
+ const adapter = new PrismaPg(pool)
32
+
33
+ export const prismaPostgres = new PrismaClient({ adapter })
34
+
35
+ // lib/db/mysql.ts — cliente secundario
36
+ import { PrismaClient } from "@prisma/mysql-client" // cliente generado para mysql
37
+ import { createPool } from "mysql2/promise"
38
+ import { PrismaMysql } from "@prisma/adapter-mysql" // si aplica
39
+
40
+ export const prismaMySQL = new PrismaClient(...)
41
+ ```
42
+
43
+ **Regla**: siempre importar el cliente correcto según el dominio de la entidad.
44
+
45
+ ---
46
+
47
+ ## Estructura de schemas multi-schema
48
+
49
+ ```prisma
50
+ // prisma/schema/auth.prisma
51
+ generator client {
52
+ provider = "prisma-client-js"
53
+ previewFeatures = ["multiSchema"]
54
+ }
55
+
56
+ datasource db {
57
+ provider = "postgresql"
58
+ url = env("DATABASE_URL")
59
+ schemas = ["auth", "rbac", "audit", "base"]
60
+ }
61
+
62
+ model User {
63
+ id String @id @default(cuid())
64
+ email String @unique
65
+ password String
66
+ createdAt DateTime @default(now())
67
+ updatedAt DateTime @updatedAt
68
+
69
+ @@schema("auth")
70
+ }
71
+
72
+ model Session {
73
+ id String @id @default(cuid())
74
+ sessionToken String @unique
75
+ userId String
76
+ expires DateTime
77
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
78
+
79
+ @@schema("auth")
80
+ }
81
+ ```
82
+
83
+ ```prisma
84
+ // prisma/schema/rbac.prisma
85
+ model Role {
86
+ id String @id @default(cuid())
87
+ name String @unique
88
+ permissions Permission[]
89
+ users UserRole[]
90
+
91
+ @@schema("rbac")
92
+ }
93
+
94
+ model Permission {
95
+ id String @id @default(cuid())
96
+ action String // ej: "users:create", "posts:delete"
97
+ roleId String
98
+ role Role @relation(fields: [roleId], references: [id])
99
+
100
+ @@schema("rbac")
101
+ }
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Queries con Prisma 7
107
+
108
+ ### Patrones correctos de selección
109
+ ```typescript
110
+ // ✓ Siempre select explícito — nunca traer campos sensibles por defecto
111
+ const user = await prismaPostgres.user.findUnique({
112
+ where: { id },
113
+ select: {
114
+ id: true,
115
+ email: true,
116
+ name: true,
117
+ // nunca incluir 'password' salvo en contexto de auth
118
+ }
119
+ })
120
+
121
+ // ✓ Include para relaciones — solo lo que se usa en la UI
122
+ const userWithRoles = await prismaPostgres.user.findUnique({
123
+ where: { id },
124
+ include: {
125
+ roles: {
126
+ include: { permissions: true }
127
+ }
128
+ }
129
+ })
130
+ ```
131
+
132
+ ### Queries cross-schema (dentro del mismo cliente PostgreSQL)
133
+ ```typescript
134
+ // Las relaciones entre schemas se manejan en el schema de Prisma
135
+ // En queries, se accede igual que cualquier relación
136
+ const auditLogs = await prismaPostgres.auditLog.findMany({
137
+ where: { userId: user.id },
138
+ orderBy: { createdAt: "desc" },
139
+ take: 50
140
+ })
141
+ ```
142
+
143
+ ### Transactions
144
+ ```typescript
145
+ // Para operaciones atómicas entre tablas
146
+ const result = await prismaPostgres.$transaction(async (tx) => {
147
+ const user = await tx.user.create({ data: userData })
148
+ await tx.userRole.create({ data: { userId: user.id, roleId: defaultRoleId } })
149
+ await tx.auditLog.create({ data: { action: "user.created", userId: user.id } })
150
+ return user
151
+ })
152
+ ```
153
+
154
+ ### Queries en MySQL (cliente secundario)
155
+ ```typescript
156
+ import { prismaMySQL } from "@/lib/db/mysql"
157
+
158
+ const records = await prismaMySQL.legacyRecord.findMany({
159
+ where: { status: "active" }
160
+ })
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Migrations
166
+
167
+ ```bash
168
+ # Crear migration después de cambiar un schema
169
+ pnpm prisma migrate dev --name nombre-descriptivo-en-snake-case
170
+
171
+ # Ejemplos de nombres:
172
+ # add-user-roles-table
173
+ # add-email-verified-to-user
174
+ # create-audit-schema
175
+ # add-permissions-index
176
+
177
+ # Aplicar en producción (no crea archivos, solo aplica pending)
178
+ pnpm prisma migrate deploy
179
+
180
+ # Reset completo (solo en dev)
181
+ pnpm prisma migrate reset
182
+
183
+ # Ver estado de migrations
184
+ pnpm prisma migrate status
185
+ ```
186
+
187
+ **Importante**: nunca editar archivos de migration ya aplicados. Si hay un error,
188
+ crear una nueva migration que lo corrija.
189
+
190
+ ---
191
+
192
+ ## Seeds con tsx
193
+
194
+ ```typescript
195
+ // prisma/seeds/roles.ts
196
+ import { prismaPostgres } from "@/lib/db/postgres"
197
+
198
+ const ROLES = [
199
+ {
200
+ name: "admin",
201
+ permissions: ["users:create", "users:delete", "users:read", "posts:*"]
202
+ },
203
+ {
204
+ name: "editor",
205
+ permissions: ["posts:create", "posts:update", "posts:read"]
206
+ },
207
+ {
208
+ name: "viewer",
209
+ permissions: ["posts:read", "users:read"]
210
+ }
211
+ ]
212
+
213
+ async function seedRoles() {
214
+ console.log("Seeding roles...")
215
+
216
+ for (const roleData of ROLES) {
217
+ const role = await prismaPostgres.role.upsert({
218
+ where: { name: roleData.name },
219
+ update: {},
220
+ create: { name: roleData.name }
221
+ })
222
+
223
+ for (const action of roleData.permissions) {
224
+ await prismaPostgres.permission.upsert({
225
+ where: { roleId_action: { roleId: role.id, action } },
226
+ update: {},
227
+ create: { roleId: role.id, action }
228
+ })
229
+ }
230
+ }
231
+
232
+ console.log("✓ Roles seeded")
233
+ }
234
+
235
+ seedRoles()
236
+ .catch(console.error)
237
+ .finally(() => prismaPostgres.$disconnect())
238
+ ```
239
+
240
+ ```bash
241
+ # Correr seed
242
+ pnpm tsx prisma/seeds/roles.ts
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Prisma Studio y herramientas
248
+
249
+ ```bash
250
+ pnpm prisma studio # UI visual para explorar datos (localhost:5555)
251
+ pnpm prisma generate # Regenerar cliente después de cambiar schema
252
+ pnpm prisma db push # Sync schema → DB sin migration (solo en dev)
253
+ pnpm prisma validate # Validar syntax del schema
254
+ pnpm prisma format # Formatear archivos .prisma
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Anti-patrones a evitar
260
+
261
+ ```typescript
262
+ // ❌ No hacer queries sin select — expone datos sensibles
263
+ const user = await prismaPostgres.user.findUnique({ where: { id } })
264
+ // Devuelve password hasheado y otros campos sensibles
265
+
266
+ // ❌ No mezclar clientes — MySQL con entidades de PostgreSQL
267
+ import { prismaMySQL } from "@/lib/db/mysql"
268
+ const user = await prismaMySQL.user.findUnique(...) // El modelo User es de PostgreSQL
269
+
270
+ // ❌ No hardcodear IDs de roles o permisos — usar queries o constantes
271
+ const adminRole = await prismaPostgres.role.findUnique({ where: { name: "admin" } })
272
+
273
+ // ❌ No hacer N+1 queries — usar include o select con relaciones
274
+ const users = await prismaPostgres.user.findMany()
275
+ for (const user of users) {
276
+ // ❌ Query por cada usuario
277
+ const roles = await prismaPostgres.userRole.findMany({ where: { userId: user.id } })
278
+ }
279
+ // ✓ Un solo query con include
280
+ const users = await prismaPostgres.user.findMany({ include: { roles: true } })
281
+ ```
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: project-intelligence
3
+ description: "Activar cuando se trabaja con SDD en un proyecto Next.js que tiene project-mcp-server configurado como MCP"
4
+ license: MIT
5
+ metadata:
6
+ version: "1.0.0"
7
+ author: "Fernando Secchi"
8
+ ---
9
+
10
+ # Project Intelligence para SDD
11
+
12
+ Integra el MCP `project-mcp-server` con el flujo SDD. Este MCP expone 10 tools que dan inteligencia real del proyecto: escaneo de rutas, Server Actions, modelos Prisma, componentes, y generación de código basada en el schema real.
13
+
14
+ ---
15
+
16
+ ## Cuándo cargar esta skill
17
+
18
+ - Cuando se inicia un flujo SDD en un proyecto Next.js con Prisma
19
+ - Cuando se necesita explorar la estructura real del proyecto antes de proponer cambios
20
+ - Cuando se va a generar código que debe respetar convenciones existentes
21
+ - Cuando se necesita verificar que los cambios no rompieron el build
22
+
23
+ ---
24
+
25
+ ## Fase: sdd-init / sdd-explore
26
+
27
+ Usar `project_scan` para obtener el mapa completo del proyecto antes de proponer cambios:
28
+
29
+ ```
30
+ project_scan({ force_refresh: true })
31
+ ```
32
+
33
+ Esto devuelve:
34
+ - Rutas del App Router (páginas, layouts, route handlers)
35
+ - Server Actions existentes con sus schemas Zod
36
+ - Modelos de Prisma con campos y relaciones
37
+ - Componentes UI instalados (shadcn) y custom
38
+
39
+ Con esta información el agente puede identificar seams sin tener que explorar el filesystem manualmente.
40
+
41
+ ---
42
+
43
+ ## Fase: sdd-spec / sdd-design
44
+
45
+ Usar herramientas granulares para detallar el diseño:
46
+
47
+ **Entender la capa de datos:**
48
+ ```
49
+ project_models({ schema: "base" })
50
+ ```
51
+ Devuelve modelos de Prisma con campos, tipos, relaciones y atributos. Usar para saber qué entidades existen y cómo se relacionan.
52
+
53
+ **Mapear rutas existentes:**
54
+ ```
55
+ project_routes({ filter: "all" })
56
+ ```
57
+ Devuelve rutas del App Router con: rendering mode (RSC/client), params dinámicos, métodos HTTP (para route handlers), y si tienen loading/error boundaries.
58
+
59
+ **Ver Server Actions existentes:**
60
+ ```
61
+ project_actions({ feature: "users" })
62
+ ```
63
+ Devuelve actions con: schema Zod asociado, parámetros, flags de auth y revalidación. Usar como referencia de patrones antes de crear nuevas actions.
64
+
65
+ ---
66
+
67
+ ## Fase: sdd-apply
68
+
69
+ Usar generadores que respetan las convenciones del proyecto:
70
+
71
+ **Server Action con Zod + auth + revalidación:**
72
+ ```
73
+ generate_action({
74
+ entity: "user",
75
+ operation: "create",
76
+ with_auth: true,
77
+ prisma_schema: "base"
78
+ })
79
+ ```
80
+ Genera código basado en el schema de Prisma real del proyecto, no templates genéricos.
81
+
82
+ **Página RSC con metadata y estructura correcta:**
83
+ ```
84
+ generate_page({
85
+ path: "/dashboard/users/[id]",
86
+ type: "detail",
87
+ with_auth: true,
88
+ with_metadata: true
89
+ })
90
+ ```
91
+
92
+ **Componente con cn(), tipado explícito y directiva correcta:**
93
+ ```
94
+ generate_component({
95
+ name: "UserCard",
96
+ feature: "users",
97
+ type: "display",
98
+ is_client: false
99
+ })
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Fase: sdd-verify
105
+
106
+ Usar `env_run_check` para validar que los cambios no rompieron nada:
107
+
108
+ ```
109
+ env_run_check({ check: "typecheck" }) → verificar tipos
110
+ env_run_check({ check: "lint" }) → verificar lint
111
+ env_run_check({ check: "test" }) → correr tests
112
+ env_run_check({ check: "build" }) → verificar build completo
113
+ ```
114
+
115
+ También verificar estado de migraciones si hubo cambios en Prisma:
116
+ ```
117
+ env_prisma_status()
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Fase: sdd-archive
123
+
124
+ Usar `env_status()` para confirmar que el entorno quedó sano después de los cambios. Los resultados se pueden guardar en Engram como observación de tipo `context`.
125
+
126
+ ---
127
+
128
+ ## Tools disponibles (referencia rápida)
129
+
130
+ | Tool | Fase SDD | Descripción |
131
+ |------|----------|-------------|
132
+ | `project_scan` | explore | Mapa completo del proyecto |
133
+ | `project_routes` | spec/design | Rutas del App Router |
134
+ | `project_actions` | spec/design | Server Actions con schemas |
135
+ | `project_models` | spec/design | Modelos Prisma con campos |
136
+ | `env_status` | init/archive | Estado del entorno |
137
+ | `env_run_check` | verify | Typecheck, lint, test, build |
138
+ | `env_prisma_status` | verify | Estado de migraciones |
139
+ | `generate_action` | apply | Generar Server Action |
140
+ | `generate_page` | apply | Generar página RSC |
141
+ | `generate_component` | apply | Generar componente React |