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 +12 -0
- package/package.json +1 -1
- package/src/templates/source/api/procedures/profiles.auth.ts +4 -4
- package/src/templates/source/root/.claude/skills/veloxts/GENERATORS.md +49 -52
- package/src/templates/source/root/.claude/skills/veloxts/SKILL.md +10 -9
- package/src/templates/source/root/CLAUDE.auth.md +2 -2
- package/src/templates/source/root/CLAUDE.default.md +2 -2
- package/src/templates/source/root/CLAUDE.trpc.md +2 -2
- package/src/templates/source/rsc-auth/src/api/procedures/profiles.ts +4 -4
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
|
@@ -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: .
|
|
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
|
-
.
|
|
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: .
|
|
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
|
-
.
|
|
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
|
-
|
|
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:
|
|
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
|
|
36
|
-
├──
|
|
37
|
-
│
|
|
38
|
-
│
|
|
37
|
+
Do you need schemas + procedures for your Prisma models?
|
|
38
|
+
├── MULTIPLE MODELS → velox 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
|
-
├──
|
|
41
|
-
│
|
|
44
|
+
├── SINGLE MODEL (new) → velox make resource EntityName -i
|
|
45
|
+
│ Prompts for fields, creates everything
|
|
42
46
|
│
|
|
43
|
-
└──
|
|
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
|
-
| `
|
|
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
|
|
73
|
+
## Namespace Generator (Single Model)
|
|
69
74
|
|
|
70
|
-
Best choice
|
|
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
|
-
###
|
|
268
|
+
### Sync All Models (Recommended for New Projects)
|
|
264
269
|
|
|
265
270
|
```bash
|
|
266
|
-
# 1. Design Prisma
|
|
267
|
-
|
|
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
|
-
#
|
|
288
|
-
velox
|
|
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:
|
|
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
|
|
19
|
+
**"I have multiple Prisma models and want schemas + procedures for all of them"**
|
|
20
20
|
```bash
|
|
21
|
-
velox
|
|
21
|
+
velox sync # RECOMMENDED - interactive, all models at once
|
|
22
|
+
velox sync --force # Skip prompts, generate everything with defaults
|
|
22
23
|
```
|
|
23
|
-
|
|
24
|
+
Generates: Zod schemas + CRUD procedures + router registration for every model
|
|
24
25
|
|
|
25
|
-
**"I
|
|
26
|
+
**"I want to add a single new entity"**
|
|
26
27
|
```bash
|
|
27
|
-
velox make
|
|
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
|
|
213
|
-
pnpm velox make
|
|
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 `.
|
|
157
|
+
**When to use `.output()` vs `.expose()`:**
|
|
158
158
|
- `.output(zodSchema)` - Same fields for all users
|
|
159
|
-
-
|
|
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 `.
|
|
147
|
+
**When to use `.output()` vs `.expose()`:**
|
|
148
148
|
- `.output(zodSchema)` - Same fields for all users
|
|
149
|
-
-
|
|
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 `.
|
|
168
|
+
**When to use `.output()` vs `.expose()`:**
|
|
169
169
|
- `.output(zodSchema)` - Same fields for all users
|
|
170
|
-
-
|
|
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: .
|
|
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
|
-
.
|
|
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: .
|
|
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
|
-
.
|
|
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) {
|