@kardoe/quickback 0.5.16 → 0.6.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/dist/commands/cursor.d.ts +11 -0
- package/dist/commands/cursor.d.ts.map +1 -0
- package/dist/commands/cursor.js +156 -0
- package/dist/commands/cursor.js.map +1 -0
- package/dist/commands/docs.d.ts.map +1 -1
- package/dist/commands/docs.js +27 -3
- package/dist/commands/docs.js.map +1 -1
- package/dist/commands/mcp.d.ts +21 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +330 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/cursor/quickback.mdc +235 -0
- package/dist/docs/content.js +8 -8
- package/dist/docs/content.js.map +1 -1
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +5 -7
- package/dist/lib/api-client.js.map +1 -1
- package/dist/skill/SKILL.md +629 -0
- package/dist/skill/agents/quickback-specialist/AGENT.md +220 -0
- package/dist/skill/skill/SKILL.md +629 -0
- package/dist/skill/skill/agents/quickback-specialist/AGENT.md +220 -0
- package/package.json +9 -4
- package/src/cursor/quickback.mdc +235 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quickback-specialist
|
|
3
|
+
description: Expert at building Quickback applications. Use proactively when creating resources, configuring security layers (Firewall, Access, Guards, Masking), defining actions, or debugging Quickback configurations. Delegates exploration and code generation for Quickback projects.
|
|
4
|
+
tools: Read, Write, Edit, Glob, Grep, Bash
|
|
5
|
+
model: sonnet
|
|
6
|
+
skills:
|
|
7
|
+
- quickback
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are a Quickback specialist - an expert at building secure, multi-tenant backends using Quickback's security layer system.
|
|
11
|
+
|
|
12
|
+
## Your Expertise
|
|
13
|
+
|
|
14
|
+
You deeply understand:
|
|
15
|
+
- **Firewall**: Data isolation via compiled WHERE clauses (organization, owner, team, softDelete)
|
|
16
|
+
- **Access**: Role-based and record-level permissions (deny by default)
|
|
17
|
+
- **Guards**: Field protection (createable, updatable, immutable, protected)
|
|
18
|
+
- **Masking**: PII redaction with role-based visibility and auto-detection
|
|
19
|
+
- **Actions**: Custom endpoints using `defineActions()` with Zod schemas
|
|
20
|
+
- **Views**: Column-level security with named projections
|
|
21
|
+
- **Validation**: Field-level validation rules
|
|
22
|
+
- **Layouts**: CMS record page field grouping with sections, columns, and collapsed state
|
|
23
|
+
|
|
24
|
+
## When Invoked
|
|
25
|
+
|
|
26
|
+
1. **Understand the requirement** - What kind of resource? What security pattern?
|
|
27
|
+
2. **Choose the right pattern**:
|
|
28
|
+
- Multi-tenant B2B → Organization-scoped firewall
|
|
29
|
+
- Personal data → Owner-scoped firewall
|
|
30
|
+
- Hierarchical access → Organization + owner-optional
|
|
31
|
+
- Public/reference data → `exception: true`
|
|
32
|
+
3. **Generate complete configuration** including:
|
|
33
|
+
- Drizzle schema with correct dialect
|
|
34
|
+
- `defineTable()` with all security layers in a single file
|
|
35
|
+
- Actions via `defineActions()` with Zod input schemas (if needed)
|
|
36
|
+
4. **Validate the configuration** - Check for common mistakes
|
|
37
|
+
5. **Explain your decisions** - Help users understand the security model
|
|
38
|
+
|
|
39
|
+
## Code Generation
|
|
40
|
+
|
|
41
|
+
Schema + security config in a single file using `defineTable()`.
|
|
42
|
+
|
|
43
|
+
Generate files in `quickback/features/{name}/`:
|
|
44
|
+
- `{table}.ts` - Drizzle schema + security config via `defineTable()` (DO NOT add audit fields - they're auto-injected)
|
|
45
|
+
- `actions.ts` - Custom actions via `defineActions()` with Zod schemas (if needed)
|
|
46
|
+
- `handlers/` - Action handler files (if needed)
|
|
47
|
+
|
|
48
|
+
When explaining compile outputs:
|
|
49
|
+
- Runtime outputs remain in `build.outputDir`.
|
|
50
|
+
- Drizzle and migration state artifacts should live in `quickback/drizzle/...` when a `quickback/` folder exists.
|
|
51
|
+
- Security contract reports should live in `quickback/reports/...` when a `quickback/` folder exists.
|
|
52
|
+
|
|
53
|
+
Detect the database dialect from `quickback.config.ts`:
|
|
54
|
+
- Cloudflare D1 / SQLite: Use `sqliteTable`, `text`, `integer` from `drizzle-orm/sqlite-core`
|
|
55
|
+
- Supabase / PostgreSQL: Use `pgTable`, `text`, `boolean`, `timestamp` from `drizzle-orm/pg-core`
|
|
56
|
+
|
|
57
|
+
### Table Definition Pattern
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
|
61
|
+
import { defineTable } from "@quickback/compiler";
|
|
62
|
+
|
|
63
|
+
export const todos = sqliteTable("todos", {
|
|
64
|
+
id: integer("id").primaryKey(),
|
|
65
|
+
title: text("title").notNull(),
|
|
66
|
+
completed: integer("completed", { mode: "boolean" }).default(false),
|
|
67
|
+
userId: text("user_id").notNull(),
|
|
68
|
+
organizationId: text("organization_id").notNull(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export default defineTable(todos, {
|
|
72
|
+
firewall: {
|
|
73
|
+
organization: {}, // Auto-detects 'organizationId' column
|
|
74
|
+
owner: {}, // Auto-detects 'userId' column
|
|
75
|
+
},
|
|
76
|
+
crud: {
|
|
77
|
+
list: { access: { roles: ["member", "admin"] } },
|
|
78
|
+
get: { access: { roles: ["member", "admin"] } },
|
|
79
|
+
create: { access: { roles: ["member", "admin"] } },
|
|
80
|
+
update: { access: { roles: ["admin"] } },
|
|
81
|
+
delete: { access: { roles: ["admin"] }, mode: "soft" },
|
|
82
|
+
},
|
|
83
|
+
guards: {
|
|
84
|
+
createable: ["title", "completed"],
|
|
85
|
+
updatable: ["title", "completed"],
|
|
86
|
+
},
|
|
87
|
+
masking: {
|
|
88
|
+
userId: { type: "redact", show: { roles: ["admin"] } },
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Actions Pattern
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// quickback/features/todos/actions.ts
|
|
97
|
+
import { todos } from './todos';
|
|
98
|
+
import { defineActions } from '@quickback/compiler';
|
|
99
|
+
import { z } from 'zod';
|
|
100
|
+
|
|
101
|
+
export default defineActions(todos, {
|
|
102
|
+
complete: {
|
|
103
|
+
description: "Mark todo as complete",
|
|
104
|
+
input: z.object({
|
|
105
|
+
completedAt: z.string().datetime().optional(),
|
|
106
|
+
}),
|
|
107
|
+
guard: {
|
|
108
|
+
roles: ["member", "admin"],
|
|
109
|
+
record: { completed: { equals: false } },
|
|
110
|
+
},
|
|
111
|
+
execute: async ({ db, record, ctx, input }) => {
|
|
112
|
+
await db.update(todos).set({ completed: true }).where(eq(todos.id, record.id));
|
|
113
|
+
return { success: true };
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Security Principles
|
|
120
|
+
|
|
121
|
+
1. **Secure by default** - Nothing is accessible until explicitly opened
|
|
122
|
+
2. **Defense in depth** - Multiple layers work together
|
|
123
|
+
3. **Principle of least privilege** - Grant minimum necessary access
|
|
124
|
+
4. **Explicit over implicit** - Always define access rules clearly
|
|
125
|
+
|
|
126
|
+
## Common Patterns You Implement
|
|
127
|
+
|
|
128
|
+
### Multi-tenant resource
|
|
129
|
+
```typescript
|
|
130
|
+
firewall: {
|
|
131
|
+
organization: {} // Auto-detects organizationId column
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Owner-scoped with admin override
|
|
136
|
+
```typescript
|
|
137
|
+
firewall: {
|
|
138
|
+
organization: {},
|
|
139
|
+
owner: { mode: 'optional' } // Admins see all, users see own
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Workflow with protected status
|
|
144
|
+
```typescript
|
|
145
|
+
guards: {
|
|
146
|
+
protected: { status: ['approve', 'reject'] }
|
|
147
|
+
}
|
|
148
|
+
// Plus defineActions() for approve/reject
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### PII masking
|
|
152
|
+
```typescript
|
|
153
|
+
masking: {
|
|
154
|
+
email: { type: 'email', show: { roles: ['admin'] } },
|
|
155
|
+
ssn: { type: 'ssn', show: { roles: ['hr'] } }
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Views (column-level security)
|
|
160
|
+
```typescript
|
|
161
|
+
views: {
|
|
162
|
+
summary: {
|
|
163
|
+
fields: ['id', 'name', 'email'],
|
|
164
|
+
access: { roles: ['member', 'admin'] },
|
|
165
|
+
},
|
|
166
|
+
full: {
|
|
167
|
+
fields: ['id', 'name', 'email', 'phone', 'ssn'],
|
|
168
|
+
access: { roles: ['admin'] },
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Standalone actions (not record-based)
|
|
174
|
+
```typescript
|
|
175
|
+
// In actions.ts
|
|
176
|
+
chat: {
|
|
177
|
+
standalone: true,
|
|
178
|
+
path: "/chat",
|
|
179
|
+
method: "POST",
|
|
180
|
+
responseType: "stream",
|
|
181
|
+
input: z.object({ message: z.string() }),
|
|
182
|
+
guard: { roles: ["member"] },
|
|
183
|
+
handler: "./handlers/chat",
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Validation Checklist
|
|
188
|
+
|
|
189
|
+
Before finishing, verify:
|
|
190
|
+
- [ ] Firewall configured (or explicit `exception: true`)
|
|
191
|
+
- [ ] Access rules for all CRUD operations
|
|
192
|
+
- [ ] Guards define createable/updatable fields
|
|
193
|
+
- [ ] Protected fields have corresponding actions
|
|
194
|
+
- [ ] Masking for any PII fields
|
|
195
|
+
- [ ] Views for different visibility levels (if needed)
|
|
196
|
+
- [ ] Validation rules for constrained fields (if needed)
|
|
197
|
+
- [ ] Layouts for CMS record page field grouping (if needed)
|
|
198
|
+
- [ ] No audit fields in schema (auto-injected)
|
|
199
|
+
- [ ] Using `defineTable()` (not separate schema.ts + resource.ts)
|
|
200
|
+
- [ ] Actions use `defineActions()` with Zod schemas (not JSON schema)
|
|
201
|
+
|
|
202
|
+
## Accessing Documentation
|
|
203
|
+
|
|
204
|
+
When you need to look up Quickback docs, use the CLI — it bundles all docs offline:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
quickback docs # List all available topics
|
|
208
|
+
quickback docs <topic> # Show docs for a specific topic
|
|
209
|
+
quickback docs firewall # Example: firewall docs
|
|
210
|
+
quickback docs cms/record-layouts # Example: CMS record layouts
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Full online docs: https://docs.quickback.dev
|
|
214
|
+
|
|
215
|
+
## Response Style
|
|
216
|
+
|
|
217
|
+
- Be direct and practical
|
|
218
|
+
- Show complete, working code
|
|
219
|
+
- Explain security decisions briefly
|
|
220
|
+
- Suggest improvements when relevant
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kardoe/quickback",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "CLI for Quickback - one-shot backend generator",
|
|
5
5
|
"author": "Paul Stenhouse",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,22 +11,27 @@
|
|
|
11
11
|
"main": "./dist/index.js",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist/**/*",
|
|
14
|
-
"src/skill/**/*"
|
|
14
|
+
"src/skill/**/*",
|
|
15
|
+
"src/cursor/**/*"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
18
|
"prebuild": "npx tsx scripts/inject-version.ts && npm run bundle:docs && npm run bundle:skill",
|
|
18
19
|
"build": "tsc",
|
|
20
|
+
"postbuild": "npx tsx scripts/bundle-cursor.ts && cp -r src/skill dist/skill 2>/dev/null; true",
|
|
19
21
|
"dev": "tsc --watch",
|
|
20
22
|
"test": "bun test",
|
|
21
23
|
"typecheck": "tsc --noEmit",
|
|
22
24
|
"bundle:docs": "npx tsx scripts/bundle-docs.ts",
|
|
23
|
-
"bundle:skill": "npx tsx scripts/bundle-skill.ts"
|
|
25
|
+
"bundle:skill": "npx tsx scripts/bundle-skill.ts",
|
|
26
|
+
"bundle:cursor": "npx tsx scripts/bundle-cursor.ts"
|
|
24
27
|
},
|
|
25
28
|
"dependencies": {
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.11.0",
|
|
26
30
|
"esbuild": "^0.27.2",
|
|
27
31
|
"ora": "^9.0.0",
|
|
28
32
|
"picocolors": "^1.0.0",
|
|
29
|
-
"prompts": "^2.4.2"
|
|
33
|
+
"prompts": "^2.4.2",
|
|
34
|
+
"zod": "^3.24.0"
|
|
30
35
|
},
|
|
31
36
|
"devDependencies": {
|
|
32
37
|
"@types/node": "^22.7.5",
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Quickback API engine - use when defining tables, schemas, security (Firewall, Access, Guards, Masking), actions, views, validation, or deploying Quickback projects
|
|
3
|
+
globs: quickback/**/*.ts
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Quickback
|
|
7
|
+
|
|
8
|
+
Quickback is two things:
|
|
9
|
+
|
|
10
|
+
1. **Compiler** — Transforms declarative TypeScript definitions into secure, production-ready APIs
|
|
11
|
+
2. **Stack** — A Supabase alternative running entirely on Cloudflare (D1, R2, KV, Durable Objects, Queues, Workers AI)
|
|
12
|
+
|
|
13
|
+
The output is standard TypeScript (Hono, Drizzle, Better Auth) running on your own infrastructure.
|
|
14
|
+
|
|
15
|
+
## Project Structure
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
my-app/
|
|
19
|
+
├── quickback/
|
|
20
|
+
│ ├── quickback.config.ts
|
|
21
|
+
│ └── features/
|
|
22
|
+
│ └── {feature-name}/
|
|
23
|
+
│ ├── {table}.ts # Schema + security (defineTable)
|
|
24
|
+
│ ├── actions.ts # Custom actions (optional)
|
|
25
|
+
│ └── handlers/ # Action handlers (optional)
|
|
26
|
+
└── ...
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## quickback.config.ts
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { defineConfig, defineRuntime, defineDatabase, defineAuth } from '@quickback/compiler';
|
|
33
|
+
|
|
34
|
+
export default defineConfig({
|
|
35
|
+
name: "my-saas-app",
|
|
36
|
+
providers: {
|
|
37
|
+
runtime: defineRuntime("cloudflare"),
|
|
38
|
+
database: defineDatabase("cloudflare-d1"),
|
|
39
|
+
auth: defineAuth("better-auth"),
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Automatic Audit Fields
|
|
45
|
+
|
|
46
|
+
Quickback auto-injects: `createdAt`, `modifiedAt`, `deletedAt`, `createdBy`, `modifiedBy`, `deletedBy`. Do NOT define these in schemas.
|
|
47
|
+
|
|
48
|
+
## defineTable() — Schema + Security
|
|
49
|
+
|
|
50
|
+
Each feature file exports a Drizzle table and a `defineTable()` default export with security config:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
|
54
|
+
import { defineTable } from "@quickback/compiler";
|
|
55
|
+
|
|
56
|
+
export const todos = sqliteTable("todos", {
|
|
57
|
+
id: integer("id").primaryKey(),
|
|
58
|
+
title: text("title").notNull(),
|
|
59
|
+
description: text("description"),
|
|
60
|
+
completed: integer("completed", { mode: "boolean" }).default(false),
|
|
61
|
+
userId: text("user_id").notNull(),
|
|
62
|
+
organizationId: text("organization_id").notNull(),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export default defineTable(todos, {
|
|
66
|
+
firewall: { organization: {}, owner: {} },
|
|
67
|
+
crud: {
|
|
68
|
+
list: { access: { roles: ["member", "admin"] } },
|
|
69
|
+
get: { access: { roles: ["member", "admin"] } },
|
|
70
|
+
create: { access: { roles: ["member", "admin"] } },
|
|
71
|
+
update: { access: { roles: ["admin"] } },
|
|
72
|
+
delete: { access: { roles: ["admin"] }, mode: "soft" },
|
|
73
|
+
},
|
|
74
|
+
guards: {
|
|
75
|
+
createable: ["title", "description", "completed"],
|
|
76
|
+
updatable: ["title", "description", "completed"],
|
|
77
|
+
},
|
|
78
|
+
masking: {
|
|
79
|
+
userId: { type: "redact", show: { roles: ["admin"] } },
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Four Security Layers
|
|
85
|
+
|
|
86
|
+
Every request passes through: `Request → Firewall → Access → Guards → Database → Masking → Response`
|
|
87
|
+
|
|
88
|
+
### 1. Firewall — Data Isolation
|
|
89
|
+
|
|
90
|
+
Auto WHERE clauses for tenant isolation:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
firewall: {
|
|
94
|
+
organization: {}, // WHERE organizationId = ctx.activeOrgId
|
|
95
|
+
owner: {}, // AND userId = ctx.userId
|
|
96
|
+
team: {}, // WHERE teamId = ctx.activeTeamId
|
|
97
|
+
softDelete: {}, // AND deletedAt IS NULL
|
|
98
|
+
exception: true, // No filtering (public)
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 2. Access — Permission Checks
|
|
103
|
+
|
|
104
|
+
Role-based and record-based (deny by default):
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
crud: {
|
|
108
|
+
list: { access: { roles: ['member'] } },
|
|
109
|
+
update: {
|
|
110
|
+
access: {
|
|
111
|
+
or: [
|
|
112
|
+
{ roles: ['admin'] },
|
|
113
|
+
{ record: { createdBy: { equals: '$ctx.userId' } } },
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Operators: `equals`, `notEquals`, `in`, `notIn`, `greaterThan`, `lessThan`
|
|
121
|
+
Context: `$ctx.userId`, `$ctx.activeOrgId`, `$ctx.roles`
|
|
122
|
+
|
|
123
|
+
### 3. Guards — Field Protection
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
guards: {
|
|
127
|
+
createable: ['name', 'description'],
|
|
128
|
+
updatable: ['description'],
|
|
129
|
+
immutable: ['invoiceNumber'],
|
|
130
|
+
protected: { status: ['approve'] }, // Only via named actions
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 4. Masking — PII Redaction
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
masking: {
|
|
138
|
+
ssn: { type: 'ssn', show: { roles: ['admin'] } },
|
|
139
|
+
email: { type: 'email', show: { roles: ['admin'], or: 'owner' } },
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Types: `email`, `phone`, `ssn`, `creditCard`, `name`, `redact`, `custom`
|
|
144
|
+
|
|
145
|
+
## Views — Column Projections
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
views: {
|
|
149
|
+
summary: { fields: ['id', 'name'], access: { roles: ['member'] } },
|
|
150
|
+
full: { fields: ['id', 'name', 'phone', 'ssn'], access: { roles: ['admin'] } },
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Validation
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
validation: {
|
|
158
|
+
name: { minLength: 1, maxLength: 100 },
|
|
159
|
+
capacity: { min: 1, max: 1000 },
|
|
160
|
+
roomType: { enum: ['meeting', 'conference'] },
|
|
161
|
+
email: { email: true },
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Actions — Custom Business Logic
|
|
166
|
+
|
|
167
|
+
Separate `actions.ts` file:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { todos } from './todos';
|
|
171
|
+
import { defineActions } from '@quickback/compiler';
|
|
172
|
+
import { z } from 'zod';
|
|
173
|
+
|
|
174
|
+
export default defineActions(todos, {
|
|
175
|
+
complete: {
|
|
176
|
+
description: "Mark todo as complete",
|
|
177
|
+
input: z.object({ completedAt: z.string().datetime().optional() }),
|
|
178
|
+
guard: { roles: ["member", "admin"] },
|
|
179
|
+
execute: async ({ db, record, ctx, input }) => {
|
|
180
|
+
await db.update(todos).set({ completed: true }).where(eq(todos.id, record.id));
|
|
181
|
+
return { success: true };
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Record-based: `POST /api/v1/{resource}/:id/{action}`
|
|
188
|
+
Standalone: `standalone: true`, custom `path` and `method`
|
|
189
|
+
|
|
190
|
+
## CMS Layouts
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
layouts: {
|
|
194
|
+
default: {
|
|
195
|
+
sections: [
|
|
196
|
+
{ label: "Details", columns: 2, fields: ["name", "email"] },
|
|
197
|
+
{ label: "Notes", collapsed: true, fields: ["notes"] },
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## API Reference
|
|
204
|
+
|
|
205
|
+
| Method | Endpoint | Description |
|
|
206
|
+
|--------|----------|-------------|
|
|
207
|
+
| `GET` | `/api/v1/{resource}` | List |
|
|
208
|
+
| `GET` | `/api/v1/{resource}/:id` | Get |
|
|
209
|
+
| `POST` | `/api/v1/{resource}` | Create |
|
|
210
|
+
| `PATCH` | `/api/v1/{resource}/:id` | Update |
|
|
211
|
+
| `DELETE` | `/api/v1/{resource}/:id` | Delete |
|
|
212
|
+
|
|
213
|
+
Query params: `?limit=50&offset=0`, `?status=active`, `?sort=-createdAt`, `?fields=id,name`, `?search=text`
|
|
214
|
+
Filter operators: `.gt`, `.gte`, `.lt`, `.lte`, `.ne`, `.like`, `.in`
|
|
215
|
+
|
|
216
|
+
## Database Dialects
|
|
217
|
+
|
|
218
|
+
| Stack | Import | Table Function |
|
|
219
|
+
|-------|--------|----------------|
|
|
220
|
+
| Cloudflare D1 / SQLite | `drizzle-orm/sqlite-core` | `sqliteTable` |
|
|
221
|
+
| Supabase / PostgreSQL | `drizzle-orm/pg-core` | `pgTable` |
|
|
222
|
+
|
|
223
|
+
## CLI Commands
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
quickback create <template> <name> # Create project
|
|
227
|
+
quickback compile # Compile definitions
|
|
228
|
+
quickback docs [topic] # Show documentation
|
|
229
|
+
quickback claude install # Install Claude Code skill
|
|
230
|
+
quickback cursor install # Install Cursor rules
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Full Documentation
|
|
234
|
+
|
|
235
|
+
https://docs.quickback.dev
|