create-velox-app 0.7.4 → 0.7.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # create-velox-app
2
2
 
3
+ ## 0.7.6
4
+
5
+ ### Patch Changes
6
+
7
+ - feat(router): custom access levels for the Resource API + advanced Architectural Patterns
8
+
9
+ ## 0.7.5
10
+
11
+ ### Patch Changes
12
+
13
+ - fix(cli): address sync command review findings
14
+
3
15
  ## 0.7.4
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-velox-app",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Project scaffolder for VeloxTS framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -5,7 +5,7 @@
5
5
  * - Public: GET /api/profiles/:id → { id, name }
6
6
  * Uses handler-level projection: resource(data, Schema.public)
7
7
  * - Authenticated: GET /api/profiles/:id/full → { id, name, email }
8
- * Uses procedure-level auto-projection: .resource(Schema.authenticated)
8
+ * Uses procedure-level auto-projection: .expose(Schema.authenticated)
9
9
  */
10
10
 
11
11
  import {
@@ -37,7 +37,7 @@ export const profileProcedures = procedures('profiles', {
37
37
  // Handler-level projection: resource(data, Schema.public) returns projected data directly
38
38
  getProfile: procedure()
39
39
  .input(z.object({ id: z.string().uuid() }))
40
- .resource(UserProfileSchema.public)
40
+ .expose(UserProfileSchema.public)
41
41
  .query(async ({ input, ctx }) => {
42
42
  const user = await ctx.db.user.findUnique({ where: { id: input.id } });
43
43
  if (!user) throw new NotFoundError(`User '${input.id}' not found`);
@@ -45,12 +45,12 @@ export const profileProcedures = procedures('profiles', {
45
45
  }),
46
46
 
47
47
  // Authenticated: GET /api/profiles/:id/full → { id, name, email }
48
- // Procedure-level auto-projection: .resource(Schema.authenticated) auto-projects the return value
48
+ // Procedure-level auto-projection: .expose(Schema.authenticated) auto-projects the return value
49
49
  getFullProfile: procedure()
50
50
  .rest({ method: 'GET', path: '/profiles/:id/full' })
51
51
  .guardNarrow(authenticatedNarrow)
52
52
  .input(z.object({ id: z.string().uuid() }))
53
- .resource(UserProfileSchema.authenticated)
53
+ .expose(UserProfileSchema.authenticated)
54
54
  .query(async ({ input, ctx }) => {
55
55
  const user = await ctx.db.user.findUnique({ where: { id: input.id } });
56
56
  if (!user) throw new NotFoundError(`User '${input.id}' not found`);
@@ -2,45 +2,49 @@
2
2
 
3
3
  ## AI Agent Recommended Workflow
4
4
 
5
- When creating new entities, the **recommended approach** is:
5
+ ### Multiple Models: `velox sync` (Recommended)
6
+
7
+ When you have several Prisma models and want schemas + procedures for all of them:
8
+
9
+ 1. **Design all Prisma models** in `prisma/schema.prisma`
10
+ 2. **Run `velox sync`** to generate everything interactively
11
+
12
+ ```bash
13
+ # Push schema to database, then sync all models
14
+ pnpm db:push
15
+ velox sync # Interactive: choose output strategy + CRUD per model
16
+ velox sync --force # Non-interactive: generate all with defaults
17
+ velox sync --dry-run # Preview what would be generated
18
+ ```
19
+
20
+ This generates Zod schemas, CRUD procedures, and router registrations for every model in one shot.
21
+
22
+ ### Single Model: `velox make namespace`
23
+
24
+ When adding a single new model to an existing project:
6
25
 
7
26
  1. **Design and add the Prisma model** directly to `prisma/schema.prisma`
8
27
  2. **Run `velox make namespace EntityName`** to generate procedures
9
28
 
10
- This ensures complete, production-ready code because the AI can design the full schema based on requirements.
11
-
12
29
  ```bash
13
- # Example: Creating a Post entity
14
-
15
- # Step 1: AI adds model to prisma/schema.prisma
16
- model Post {
17
- id String @id @default(uuid())
18
- title String
19
- content String
20
- published Boolean @default(false)
21
- authorId String
22
- author User @relation(fields: [authorId], references: [id])
23
- createdAt DateTime @default(now())
24
- updatedAt DateTime @updatedAt
25
- @@map("posts")
26
- }
27
-
28
- # Step 2: Generate procedures for the existing model
30
+ # Example: Adding a Post entity to an existing project
29
31
  velox make namespace Post --example
30
32
  ```
31
33
 
32
34
  ## Decision Tree: Which Generator?
33
35
 
34
36
  ```
35
- Do you need a new database entity?
36
- ├── YES (AI workflow) 1. Design Prisma model in schema.prisma
37
- 2. velox make namespace EntityName --example
38
- Creates: Schema + Procedures for existing model
37
+ Do you need schemas + procedures for your Prisma models?
38
+ ├── MULTIPLE MODELSvelox sync
39
+ Generates all models interactively (or --force for defaults)
40
+
41
+ ├── SINGLE MODEL (existing) → velox make namespace EntityName --example
42
+ │ Creates: Schema + Procedures for one model
39
43
 
40
- ├── YES (Interactive) → velox make resource EntityName -i
41
- Prompts for fields, creates everything
44
+ ├── SINGLE MODEL (new) → velox make resource EntityName -i
45
+ Prompts for fields, creates everything
42
46
 
43
- └── NO → What do you need?
47
+ └── NOT A MODEL → What do you need?
44
48
  ├── Single API endpoint → velox make procedure
45
49
  ├── Validation schema only → velox make schema
46
50
  ├── Database model only → velox make model
@@ -58,16 +62,17 @@ Do you need a new database entity?
58
62
 
59
63
  | Generator | Creates | Use When |
60
64
  |-----------|---------|----------|
61
- | `namespace` | Schema + Procedures + Tests | **AI agents** or existing Prisma model |
65
+ | `sync` | Schema + Procedures for **all** models | **Recommended** for multi-model projects |
66
+ | `namespace` | Schema + Procedures + Tests | Single existing Prisma model |
62
67
  | `resource -i` | Prisma + Schema + Procedures + Tests | **Human interactive** field definition |
63
68
  | `resource` | Scaffolds with TODOs | Quick start (fields needed manually) |
64
69
  | `procedure` | Procedures (inline schemas) | Single endpoint, quick prototype |
65
70
  | `schema` | Zod schema file | Standalone validation |
66
71
  | `model` | Prisma model | Database-only change |
67
72
 
68
- ## Namespace Generator [AI RECOMMENDED]
73
+ ## Namespace Generator (Single Model)
69
74
 
70
- Best choice for AI agents. Works with models you've already defined.
75
+ Best choice when adding a single model to an existing project. Works with models you've already defined.
71
76
 
72
77
  ```bash
73
78
  # After adding model to schema.prisma:
@@ -260,35 +265,27 @@ velox make task SendDailyDigest --cron="0 9 * * *"
260
265
 
261
266
  ## Common Workflows
262
267
 
263
- ### New Feature: Blog Posts (AI Agent)
268
+ ### Sync All Models (Recommended for New Projects)
264
269
 
265
270
  ```bash
266
- # 1. Design Prisma model directly in schema.prisma
267
- model Post {
268
- id String @id @default(uuid())
269
- title String
270
- slug String @unique
271
- content String
272
- excerpt String?
273
- published Boolean @default(false)
274
- authorId String
275
- author User @relation(fields: [authorId], references: [id])
276
- createdAt DateTime @default(now())
277
- updatedAt DateTime @updatedAt
278
- @@map("posts")
279
- }
280
-
281
- # 2. Generate procedures for the model
282
- velox make namespace Post --example
283
-
284
- # 3. Push database changes
271
+ # 1. Design all Prisma models in schema.prisma
272
+ # 2. Push schema to database
285
273
  pnpm db:push
286
274
 
287
- # 4. (Optional) Seed sample data
288
- velox make seeder PostSeeder
275
+ # 3. Generate schemas + procedures for all models
276
+ velox sync
277
+ ```
278
+
279
+ ### New Feature: Single Model (AI Agent)
280
+
281
+ ```bash
282
+ # 1. Design Prisma model directly in schema.prisma
283
+ # 2. Push schema and generate for that one model
284
+ pnpm db:push
285
+ velox make namespace Post --example
289
286
  ```
290
287
 
291
- ### New Feature: Blog Posts (Human Interactive)
288
+ ### New Feature: Single Model (Human Interactive)
292
289
 
293
290
  ```bash
294
291
  # 1. Interactive field definition
@@ -16,23 +16,23 @@ I help you build type-safe full-stack applications with VeloxTS. Ask me about:
16
16
 
17
17
  ## Quick Decision: Which Generator?
18
18
 
19
- **"I want to create a new database entity"**
19
+ **"I have multiple Prisma models and want schemas + procedures for all of them"**
20
20
  ```bash
21
- velox make resource Post # RECOMMENDED - creates everything
21
+ velox sync # RECOMMENDED - interactive, all models at once
22
+ velox sync --force # Skip prompts, generate everything with defaults
22
23
  ```
23
- Creates: Prisma model + Zod schema + Procedures + Tests + Auto-registers
24
+ Generates: Zod schemas + CRUD procedures + router registration for every model
24
25
 
25
- **"I have an existing Prisma model"**
26
+ **"I want to add a single new entity"**
26
27
  ```bash
27
- velox make namespace Order # For existing models
28
+ velox make resource Post # Creates everything from scratch
29
+ velox make namespace Order # For existing Prisma models only
28
30
  ```
29
- Creates: Zod schema + Procedures (no Prisma injection)
30
31
 
31
32
  **"I need a single endpoint"**
32
33
  ```bash
33
34
  velox make procedure health # Quick single procedure
34
35
  ```
35
- Creates: Procedure file with inline schemas
36
36
 
37
37
  See [GENERATORS.md](GENERATORS.md) for detailed guidance.
38
38
 
@@ -209,8 +209,9 @@ pnpm db:studio # Open Prisma Studio
209
209
  pnpm velox migrate status # Check migration status
210
210
 
211
211
  # Code Generation
212
- pnpm velox make resource Post --crud # Full resource
213
- pnpm velox make namespace Order # Namespace + schema
212
+ pnpm velox sync # All models at once (recommended)
213
+ pnpm velox make resource Post --crud # Full resource (single model)
214
+ pnpm velox make namespace Order # Existing model (single)
214
215
  pnpm velox make procedure health # Single procedure
215
216
 
216
217
  # Seeding
@@ -154,9 +154,9 @@ export const userProcedures = procedures('users', {
154
154
  });
155
155
  ```
156
156
 
157
- **When to use `.output()` vs `.resource()`:**
157
+ **When to use `.output()` vs `.expose()`:**
158
158
  - `.output(zodSchema)` - Same fields for all users
159
- - `resourceSchema()` + `resource()` - Different fields per role
159
+ - `.expose(resourceSchema)` - Different fields per role (resource projection)
160
160
 
161
161
  ## Prisma 7 Configuration
162
162
 
@@ -144,9 +144,9 @@ export const userProcedures = procedures('users', {
144
144
  });
145
145
  ```
146
146
 
147
- **When to use `.output()` vs `.resource()`:**
147
+ **When to use `.output()` vs `.expose()`:**
148
148
  - `.output(zodSchema)` - Same fields for all users
149
- - `resourceSchema()` + `resource()` - Different fields per role
149
+ - `.expose(resourceSchema)` - Different fields per role (resource projection)
150
150
 
151
151
  ## Prisma 7 Configuration
152
152
 
@@ -165,9 +165,9 @@ export const userProcedures = procedures('users', {
165
165
  });
166
166
  ```
167
167
 
168
- **When to use `.output()` vs `.resource()`:**
168
+ **When to use `.output()` vs `.expose()`:**
169
169
  - `.output(zodSchema)` - Same fields for all users
170
- - `resourceSchema()` + `resource()` - Different fields per role
170
+ - `.expose(resourceSchema)` - Different fields per role (resource projection)
171
171
 
172
172
  ## Prisma 7 Configuration
173
173
 
@@ -5,7 +5,7 @@
5
5
  * - Public: GET /api/profiles/:id → { id, name }
6
6
  * Uses handler-level projection: resource(data, Schema.public)
7
7
  * - Authenticated: GET /api/profiles/:id/full → { id, name, email }
8
- * Uses procedure-level auto-projection: .resource(Schema.authenticated)
8
+ * Uses procedure-level auto-projection: .expose(Schema.authenticated)
9
9
  */
10
10
 
11
11
  import { authenticatedNarrow } from '@veloxts/auth';
@@ -33,7 +33,7 @@ export const profileProcedures = procedures('profiles', {
33
33
  // Handler-level projection: resource(data, Schema.public) returns projected data directly
34
34
  getProfile: procedure()
35
35
  .input(z.object({ id: z.string().uuid() }))
36
- .resource(UserProfileSchema.public)
36
+ .expose(UserProfileSchema.public)
37
37
  .query(async ({ input }) => {
38
38
  const user = await db.user.findUnique({ where: { id: input.id } });
39
39
  if (!user) {
@@ -43,12 +43,12 @@ export const profileProcedures = procedures('profiles', {
43
43
  }),
44
44
 
45
45
  // Authenticated: GET /api/profiles/:id/full → { id, name, email }
46
- // Procedure-level auto-projection: .resource(Schema.authenticated) auto-projects the return value
46
+ // Procedure-level auto-projection: .expose(Schema.authenticated) auto-projects the return value
47
47
  getFullProfile: procedure()
48
48
  .rest({ method: 'GET', path: '/profiles/:id/full' })
49
49
  .guardNarrow(authenticatedNarrow)
50
50
  .input(z.object({ id: z.string().uuid() }))
51
- .resource(UserProfileSchema.authenticated)
51
+ .expose(UserProfileSchema.authenticated)
52
52
  .query(async ({ input }) => {
53
53
  const user = await db.user.findUnique({ where: { id: input.id } });
54
54
  if (!user) {