kitcn 0.0.1 → 0.12.1
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/bin/intent.js +3 -0
- package/dist/aggregate/index.d.ts +388 -0
- package/dist/aggregate/index.js +37 -0
- package/dist/api-entry-BckXqaLb.js +66 -0
- package/dist/auth/client/index.d.ts +37 -0
- package/dist/auth/client/index.js +217 -0
- package/dist/auth/config/index.d.ts +45 -0
- package/dist/auth/config/index.js +24 -0
- package/dist/auth/generated/index.d.ts +2 -0
- package/dist/auth/generated/index.js +3 -0
- package/dist/auth/http/index.d.ts +64 -0
- package/dist/auth/http/index.js +461 -0
- package/dist/auth/index.d.ts +221 -0
- package/dist/auth/index.js +1398 -0
- package/dist/auth/nextjs/index.d.ts +50 -0
- package/dist/auth/nextjs/index.js +81 -0
- package/dist/auth-store-Cljlmdmi.js +197 -0
- package/dist/builder-CBdG5W6A.js +1974 -0
- package/dist/caller-factory-cTXNvYdz.js +216 -0
- package/dist/cli.mjs +13264 -0
- package/dist/codegen-lF80HSWu.mjs +3416 -0
- package/dist/context-utils-HPC5nXzx.d.ts +17 -0
- package/dist/create-schema-odyF4kCy.js +156 -0
- package/dist/create-schema-orm-DOyiNDCx.js +246 -0
- package/dist/crpc/index.d.ts +105 -0
- package/dist/crpc/index.js +169 -0
- package/dist/customFunctions-C0voKmtx.js +144 -0
- package/dist/error-BZEnI7Sq.js +41 -0
- package/dist/generated-contract-disabled-Cih4eITO.js +50 -0
- package/dist/generated-contract-disabled-D-sOFy92.d.ts +354 -0
- package/dist/http-types-DqJubRPJ.d.ts +292 -0
- package/dist/meta-utils-0Pu0Nrap.js +117 -0
- package/dist/middleware-BUybuv9n.d.ts +34 -0
- package/dist/middleware-C2qTZ3V7.js +84 -0
- package/dist/orm/index.d.ts +17 -0
- package/dist/orm/index.js +10713 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +3 -0
- package/dist/procedure-caller-DtxLmGwA.d.ts +1467 -0
- package/dist/procedure-caller-MWcxhQDv.js +349 -0
- package/dist/query-context-B8o6-8kC.js +1518 -0
- package/dist/query-context-CFZqIvD7.d.ts +42 -0
- package/dist/query-options-Dw7cOyXl.js +121 -0
- package/dist/ratelimit/index.d.ts +269 -0
- package/dist/ratelimit/index.js +856 -0
- package/dist/ratelimit/react/index.d.ts +76 -0
- package/dist/ratelimit/react/index.js +183 -0
- package/dist/react/index.d.ts +1284 -0
- package/dist/react/index.js +2526 -0
- package/dist/rsc/index.d.ts +276 -0
- package/dist/rsc/index.js +233 -0
- package/dist/runtime-CtvJPkur.js +2453 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.js +6 -0
- package/dist/solid/index.d.ts +1221 -0
- package/dist/solid/index.js +2940 -0
- package/dist/transformer-DtDhR3Lc.js +194 -0
- package/dist/types-BTb_4BaU.d.ts +42 -0
- package/dist/types-BiJE7qxR.d.ts +4 -0
- package/dist/types-DEJpkIhw.d.ts +88 -0
- package/dist/types-HhO_R6pd.d.ts +213 -0
- package/dist/validators-B7oIJCAp.js +279 -0
- package/dist/validators-vzRKjBJC.d.ts +88 -0
- package/dist/watcher.mjs +96 -0
- package/dist/where-clause-compiler-DdjN63Io.d.ts +4756 -0
- package/package.json +107 -34
- package/skills/convex/SKILL.md +486 -0
- package/skills/convex/references/features/aggregates.md +353 -0
- package/skills/convex/references/features/auth-admin.md +446 -0
- package/skills/convex/references/features/auth-organizations.md +1141 -0
- package/skills/convex/references/features/auth-polar.md +579 -0
- package/skills/convex/references/features/auth.md +470 -0
- package/skills/convex/references/features/create-plugins.md +153 -0
- package/skills/convex/references/features/http.md +676 -0
- package/skills/convex/references/features/migrations.md +162 -0
- package/skills/convex/references/features/orm.md +1166 -0
- package/skills/convex/references/features/react.md +657 -0
- package/skills/convex/references/features/scheduling.md +267 -0
- package/skills/convex/references/features/testing.md +209 -0
- package/skills/convex/references/setup/auth.md +501 -0
- package/skills/convex/references/setup/biome.md +190 -0
- package/skills/convex/references/setup/doc-guidelines.md +145 -0
- package/skills/convex/references/setup/index.md +761 -0
- package/skills/convex/references/setup/next.md +116 -0
- package/skills/convex/references/setup/react.md +175 -0
- package/skills/convex/references/setup/server.md +473 -0
- package/skills/convex/references/setup/start.md +67 -0
- package/LICENSE +0 -21
- package/README.md +0 -0
- package/dist/index.d.mts +0 -5
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -6
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,761 @@
|
|
|
1
|
+
# kitcn Setup (Canonical, Greenfield)
|
|
2
|
+
|
|
3
|
+
Use this runbook to set up a project from scratch so agents can ship features end-to-end without additional setup context.
|
|
4
|
+
|
|
5
|
+
## 1. Purpose and Scope
|
|
6
|
+
|
|
7
|
+
This document is the canonical setup reference for kitcn in `.claude`.
|
|
8
|
+
|
|
9
|
+
In scope:
|
|
10
|
+
|
|
11
|
+
- Greenfield setup from empty/new app
|
|
12
|
+
- ORM-first backend (`ctx.orm`)
|
|
13
|
+
- cRPC setup, auth setup, client setup, framework setup
|
|
14
|
+
- Optional modules and plugin setup gates
|
|
15
|
+
|
|
16
|
+
Out of scope:
|
|
17
|
+
|
|
18
|
+
- Migrations from existing Convex/Ents/legacy data-layer projects
|
|
19
|
+
|
|
20
|
+
If migration is needed, stop and use migration docs separately. Do not mix migration steps into this runbook.
|
|
21
|
+
|
|
22
|
+
## 2. Agent Decision Intake
|
|
23
|
+
|
|
24
|
+
This is the **mandatory first prompt** for agents helping users set up kitcn.
|
|
25
|
+
Ask these questions before editing files.
|
|
26
|
+
|
|
27
|
+
### 2.1 Ask These First (match `/www/content/docs/index.mdx`)
|
|
28
|
+
|
|
29
|
+
#### Required choices
|
|
30
|
+
|
|
31
|
+
| Feature | Options | Default |
|
|
32
|
+
| --------------- | --------------------------------------------------- | ------------------ |
|
|
33
|
+
| Bootstrap | CLI (`kitcn init` / `add`), Docs by section | CLI |
|
|
34
|
+
| React Framework | Next.js App Router, TanStack Start, Other | Next.js App Router |
|
|
35
|
+
| Database | ORM (`ctx.orm`) | ORM |
|
|
36
|
+
|
|
37
|
+
#### Optional features
|
|
38
|
+
|
|
39
|
+
| Feature | Options | When to include |
|
|
40
|
+
| ------------- | --------------------------------- | --------------------------------- |
|
|
41
|
+
| Auth | Better Auth, Custom, None | Most apps need auth |
|
|
42
|
+
| SSR/RSC | Yes, No | Next.js App Router apps |
|
|
43
|
+
| Triggers | Yes, No | Auto side effects on data changes |
|
|
44
|
+
| Aggregates | Yes, No | Counts, sums, leaderboards |
|
|
45
|
+
| Rate Limiting | Yes, No | API protection |
|
|
46
|
+
| Scheduling | Yes, No | Background jobs, delayed tasks |
|
|
47
|
+
| HTTP router | Yes, No | REST/webhook style endpoints |
|
|
48
|
+
| RLS | Yes, No | Runtime row-level access control |
|
|
49
|
+
| Auth plugins | admin, organizations, polar, none | Only when product requires them |
|
|
50
|
+
|
|
51
|
+
### 2.2 First Prompt Template
|
|
52
|
+
|
|
53
|
+
Use this exact structure:
|
|
54
|
+
|
|
55
|
+
1. Bootstrap: CLI (`kitcn init` / `add`) or docs by section?
|
|
56
|
+
2. Framework: Next.js App Router, TanStack Start, or other?
|
|
57
|
+
3. Database: ORM (`ctx.orm`) or other?
|
|
58
|
+
4. Auth: Better Auth, custom auth, or no auth?
|
|
59
|
+
5. Need SSR/RSC?
|
|
60
|
+
6. Enable triggers?
|
|
61
|
+
7. Enable aggregates?
|
|
62
|
+
8. Enable rate limiting?
|
|
63
|
+
9. Enable scheduling?
|
|
64
|
+
10. Need HTTP router endpoints?
|
|
65
|
+
11. Enable RLS?
|
|
66
|
+
12. Any auth plugins (admin/organizations/polar)?
|
|
67
|
+
|
|
68
|
+
### 2.3 Decision Mapping
|
|
69
|
+
|
|
70
|
+
Map answers to setup execution in this order:
|
|
71
|
+
|
|
72
|
+
1. Build base setup first (non-auth only).
|
|
73
|
+
2. Pass the non-auth baseline gate (Section 11.2) before starting auth work.
|
|
74
|
+
3. If auth is enabled: add auth core.
|
|
75
|
+
4. If auth is enabled: pass the auth sign-in gate (Section 11.3) before optional modules/plugins.
|
|
76
|
+
5. Add framework branch (Next.js or TanStack Start).
|
|
77
|
+
6. Add optional modules/plugins only when selected.
|
|
78
|
+
7. If framework is `Other`, stop this runbook and route to non-setup docs (`react`, `server/*`) instead of guessing.
|
|
79
|
+
|
|
80
|
+
## 3. Base Bootstrap
|
|
81
|
+
|
|
82
|
+
### 3.1 Preferred bootstrap path
|
|
83
|
+
|
|
84
|
+
Quickstart path:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
mkdir my-app
|
|
88
|
+
cd my-app
|
|
89
|
+
bunx kitcn init -t next --yes
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Then start the long-running backend with `bunx kitcn dev`, run the
|
|
93
|
+
framework dev server (`bun dev` for the Next starter), and open `/convex` for
|
|
94
|
+
the scaffolded messages demo. In `--yes` mode, kitcn provisions an anonymous
|
|
95
|
+
local Convex deployment when no account is linked yet, so the starter path does
|
|
96
|
+
not stop on a login prompt.
|
|
97
|
+
|
|
98
|
+
Use the CLI first:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Adopt the current supported app in place
|
|
102
|
+
bunx kitcn init --yes
|
|
103
|
+
|
|
104
|
+
# Adopt the current supported app on Concave
|
|
105
|
+
bunx kitcn --backend concave init --yes
|
|
106
|
+
|
|
107
|
+
# New Next.js app with deterministic shadcn bootstrap + first local Convex bootstrap
|
|
108
|
+
bunx kitcn init -t next --yes
|
|
109
|
+
|
|
110
|
+
# New Vite app with the React baseline + first local Convex bootstrap
|
|
111
|
+
bunx kitcn init -t vite --yes
|
|
112
|
+
|
|
113
|
+
# Nested app target
|
|
114
|
+
bunx kitcn init -t next --yes --cwd apps --name web
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Then add only the features you want:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bunx kitcn add auth
|
|
121
|
+
bunx kitcn add ratelimit
|
|
122
|
+
bunx kitcn add resend
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`kitcn init -t next --yes` owns the kitcn integration layer for:
|
|
126
|
+
|
|
127
|
+
- `app/convex/page.tsx`
|
|
128
|
+
- `package.json`
|
|
129
|
+
- `tsconfig.json`
|
|
130
|
+
- `.env.local`
|
|
131
|
+
- `components/providers.tsx`
|
|
132
|
+
- `lib/convex/*`
|
|
133
|
+
- `convex/functions/messages.ts`
|
|
134
|
+
- `convex/functions/generated/messages.runtime.ts`
|
|
135
|
+
- `convex/functions/schema.ts`
|
|
136
|
+
- `convex/functions/http.ts`
|
|
137
|
+
- `convex/functions/generated/server.ts`
|
|
138
|
+
- `convex/lib/crpc.ts`
|
|
139
|
+
- `convex/lib/get-env.ts`
|
|
140
|
+
- `convex/shared/api.ts`
|
|
141
|
+
- `kitcn.json`
|
|
142
|
+
|
|
143
|
+
Template-mode `init -t next` preserves the shadcn-owned shell (`app/layout.tsx`, `app/page.tsx`, `app/globals.css`, `components/theme-provider.tsx`, `lib/utils.ts`, `components.json`, `eslint.config.mjs`, `next.config.mjs`, `postcss.config.mjs`) and only patches:
|
|
144
|
+
|
|
145
|
+
- `app/layout.tsx` to mount `Providers`
|
|
146
|
+
- `tsconfig.json` to add `@convex/*`
|
|
147
|
+
- `components.json` when `tailwind.css` needs to follow the resolved app root
|
|
148
|
+
- `package.json` to add `kitcn codegen` as `codegen` (or `convex:codegen` when `codegen` is already taken)
|
|
149
|
+
|
|
150
|
+
`init -t` also runs the first kitcn codegen pass so `convex/lib/crpc.ts` can import `../functions/generated/server` immediately.
|
|
151
|
+
Template-mode `init -t` also seeds a live messages demo route plus starter schema and
|
|
152
|
+
procedures, so the scaffold has one working query/mutation flow out of the box.
|
|
153
|
+
Template-mode `init -t` infers `src/` vs root app layouts and writes the Next client scaffold into the matching tree. Conflicting `src` + root layouts should fail instead of guessing.
|
|
154
|
+
Backend resolves from `--backend`, then `backend` in `kitcn.json`, then `convex`.
|
|
155
|
+
|
|
156
|
+
Universal scaffold rule:
|
|
157
|
+
|
|
158
|
+
1. `init -t next` owns the stack everyone needs:
|
|
159
|
+
- typed `get-env`
|
|
160
|
+
- client core
|
|
161
|
+
- server core
|
|
162
|
+
- root + Convex tsconfig wiring
|
|
163
|
+
- `.gitignore` entries for `.convex/` and `.concave/`
|
|
164
|
+
- baseline scripts
|
|
165
|
+
- fixed `/convex` messages demo
|
|
166
|
+
2. `kitcn init` bootstraps the app in both modes: with `-t` for fresh scaffold, without `-t` for in-place adoption.
|
|
167
|
+
3. Optional capability belongs in `add`, not the base scaffold:
|
|
168
|
+
- `add auth`
|
|
169
|
+
- `add ratelimit`
|
|
170
|
+
- `add resend`
|
|
171
|
+
4. `add auth` is the minimal auth bundle. It owns auth server/client files,
|
|
172
|
+
auth-aware provider wiring, auth env fields, and auth cRPC families.
|
|
173
|
+
5. `add auth` does not own role/admin policy, orgs, or other app-policy layers.
|
|
174
|
+
|
|
175
|
+
Public template keys stay concrete:
|
|
176
|
+
|
|
177
|
+
- `next`
|
|
178
|
+
- `vite`
|
|
179
|
+
|
|
180
|
+
Internal scaffold modes stay broad:
|
|
181
|
+
|
|
182
|
+
- `next-app`
|
|
183
|
+
- `react`
|
|
184
|
+
|
|
185
|
+
Framework mapping:
|
|
186
|
+
|
|
187
|
+
- `next-app` -> `next-app`
|
|
188
|
+
- `next-pages`, `vite`, `react-router`, `tanstack-start`, `manual` -> `react`
|
|
189
|
+
|
|
190
|
+
React-mode notes:
|
|
191
|
+
|
|
192
|
+
1. `init -t vite` scaffolds the universal baseline plus the React client core.
|
|
193
|
+
2. It does not scaffold RSC helpers.
|
|
194
|
+
3. It does not scaffold the `/convex` messages demo in v1.
|
|
195
|
+
4. `add auth` on the React baseline follows the Better Auth React/Vite SPA shape and skips auth page/router UX in v1.
|
|
196
|
+
|
|
197
|
+
### 3.2 Manual app creation and baseline packages
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
bunx create-next-app@latest my-app --typescript --tailwind --eslint --app --src-dir
|
|
201
|
+
cd my-app
|
|
202
|
+
bun add convex kitcn zod @tanstack/react-query
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 3.3 Create baseline folders
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
mkdir -p convex/functions convex/lib convex/shared src/lib/convex
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
If the goal is full template-level backend parity, also scaffold:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
mkdir -p convex/functions/items convex/lib/auth convex/lib/emails convex/routers
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Recommended monolithic structure:
|
|
218
|
+
|
|
219
|
+
```text
|
|
220
|
+
src/ # app/client
|
|
221
|
+
convex/functions/ # deployed Convex functions
|
|
222
|
+
convex/lib/ # backend helpers (not deployed as API)
|
|
223
|
+
convex/shared/ # shared types/meta imported by client
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 3.4 Configure Convex functions path and static codegen
|
|
227
|
+
|
|
228
|
+
**Create:** `convex.json`
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"functions": "convex/functions",
|
|
233
|
+
"codegen": {
|
|
234
|
+
"staticApi": true,
|
|
235
|
+
"staticDataModel": true
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 3.5 Configure TypeScript aliases and strict function typing
|
|
241
|
+
|
|
242
|
+
**Edit:** `tsconfig.json`
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"compilerOptions": {
|
|
247
|
+
"strict": true,
|
|
248
|
+
"strictFunctionTypes": false,
|
|
249
|
+
"types": ["node"],
|
|
250
|
+
"paths": {
|
|
251
|
+
"@/*": ["./src/*"],
|
|
252
|
+
"@convex/*": ["./convex/shared/*"]
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Type-clean baseline notes:
|
|
259
|
+
|
|
260
|
+
1. Keep app/runtime node globals available (`types: ["node"]`) so `process.env` and server modules typecheck.
|
|
261
|
+
2. Add test-only globals (for example `vitest/globals`) in a test-specific tsconfig instead of the main app tsconfig.
|
|
262
|
+
3. If third-party declaration noise blocks setup, temporarily set `"skipLibCheck": true` and remove it once dependency versions are stabilized.
|
|
263
|
+
4. In backend Convex files, import `./_generated/*` relatively; `@convex/*` is for shared generated surface (`convex/shared/*`).
|
|
264
|
+
|
|
265
|
+
### 3.6 Enforce import boundaries (recommended)
|
|
266
|
+
|
|
267
|
+
**Edit:** `biome.jsonc`
|
|
268
|
+
|
|
269
|
+
```jsonc
|
|
270
|
+
{
|
|
271
|
+
"extends": ["ultracite/core", "ultracite/react", "ultracite/next"],
|
|
272
|
+
"overrides": [
|
|
273
|
+
{
|
|
274
|
+
"includes": ["src/**/*.ts*"],
|
|
275
|
+
"linter": {
|
|
276
|
+
"rules": {
|
|
277
|
+
"style": {
|
|
278
|
+
"noRestrictedImports": {
|
|
279
|
+
"level": "error",
|
|
280
|
+
"options": {
|
|
281
|
+
"paths": {
|
|
282
|
+
"convex/values": {
|
|
283
|
+
"importNames": ["ConvexError"],
|
|
284
|
+
"message": "Use CRPCError from 'kitcn/crpc' instead.",
|
|
285
|
+
},
|
|
286
|
+
"convex/react": "Use useCRPC from '@/lib/convex/crpc' instead.",
|
|
287
|
+
"convex/nextjs": "Use caller from '@/lib/convex/rsc' instead.",
|
|
288
|
+
},
|
|
289
|
+
"patterns": [
|
|
290
|
+
{
|
|
291
|
+
"group": ["**/../convex/**"],
|
|
292
|
+
"message": "Use @convex/* alias instead of relative convex imports.",
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"includes": ["convex/**/*.ts*"],
|
|
303
|
+
"linter": {
|
|
304
|
+
"rules": {
|
|
305
|
+
"style": {
|
|
306
|
+
"noRestrictedImports": {
|
|
307
|
+
"level": "error",
|
|
308
|
+
"options": {
|
|
309
|
+
"patterns": [
|
|
310
|
+
{
|
|
311
|
+
"group": ["@/*", "**/src/**"],
|
|
312
|
+
"message": "Convex files cannot import from src/.",
|
|
313
|
+
},
|
|
314
|
+
],
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"includes": ["convex/shared/**/*.ts*"],
|
|
323
|
+
"linter": {
|
|
324
|
+
"rules": {
|
|
325
|
+
"style": {
|
|
326
|
+
"noRestrictedImports": {
|
|
327
|
+
"level": "error",
|
|
328
|
+
"options": {
|
|
329
|
+
"patterns": [
|
|
330
|
+
{
|
|
331
|
+
"group": ["**/convex/lib/**"],
|
|
332
|
+
"message": "convex/shared cannot import from convex/lib.",
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
],
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## 4. Environment Variables
|
|
346
|
+
|
|
347
|
+
### 4.1 Local
|
|
348
|
+
|
|
349
|
+
**Create:** `.env.local`
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Convex WebSocket API
|
|
353
|
+
NEXT_PUBLIC_CONVEX_URL=http://localhost:3210
|
|
354
|
+
|
|
355
|
+
# Convex HTTP site URL
|
|
356
|
+
NEXT_PUBLIC_CONVEX_SITE_URL=http://localhost:3211
|
|
357
|
+
|
|
358
|
+
# App URL for Better Auth client
|
|
359
|
+
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 4.2 Cloud
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
# Generated by Convex
|
|
366
|
+
NEXT_PUBLIC_CONVEX_URL=https://your-project.convex.cloud
|
|
367
|
+
|
|
368
|
+
# Must be set manually
|
|
369
|
+
NEXT_PUBLIC_CONVEX_SITE_URL=https://your-project.convex.site
|
|
370
|
+
|
|
371
|
+
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Rule: real-time URL uses `.cloud`; HTTP/router/caller URL uses `.site`.
|
|
375
|
+
|
|
376
|
+
### 4.3 Typed env helper (recommended for full backend parity)
|
|
377
|
+
|
|
378
|
+
When multiple Convex functions and libs share env values (auth, billing, dev guards), create one typed helper:
|
|
379
|
+
|
|
380
|
+
**Create:** `convex/lib/get-env.ts`
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
import { createEnv } from "kitcn/server";
|
|
384
|
+
import { z } from "zod";
|
|
385
|
+
|
|
386
|
+
export const getEnv = createEnv({
|
|
387
|
+
schema: z.object({
|
|
388
|
+
DEPLOY_ENV: z.string().default("production"),
|
|
389
|
+
SITE_URL: z.string().default("http://localhost:3000"),
|
|
390
|
+
BETTER_AUTH_SECRET: z.string(),
|
|
391
|
+
JWKS: z.string().optional(),
|
|
392
|
+
ADMIN: z
|
|
393
|
+
.string()
|
|
394
|
+
.default("")
|
|
395
|
+
.transform((s) => (s ? s.split(",") : []))
|
|
396
|
+
.pipe(z.array(z.string())),
|
|
397
|
+
RESEND_API_KEY: z.string().optional(),
|
|
398
|
+
POLAR_ACCESS_TOKEN: z.string().optional(),
|
|
399
|
+
POLAR_SERVER: z.enum(["production", "sandbox"]).default("sandbox"),
|
|
400
|
+
POLAR_PRODUCT_PREMIUM: z.string().optional(),
|
|
401
|
+
POLAR_WEBHOOK_SECRET: z.string().optional(),
|
|
402
|
+
}),
|
|
403
|
+
});
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Then prefer `getEnv()` in Convex code instead of scattered `process.env`.
|
|
407
|
+
|
|
408
|
+
## 11. Dev Scripts and CLI Workflow
|
|
409
|
+
|
|
410
|
+
### 11.0 Plugin scaffold inspection
|
|
411
|
+
|
|
412
|
+
Use the plugin CLI as a plan engine, not a blind writer:
|
|
413
|
+
|
|
414
|
+
1. `bunx kitcn add <plugin> --dry-run` → compact full-plan summary.
|
|
415
|
+
2. `bunx kitcn add <plugin> --diff [path]` → unified diffs for planned file changes.
|
|
416
|
+
3. `bunx kitcn add <plugin> --view [path]` → rendered planned file contents.
|
|
417
|
+
4. `bunx kitcn view <plugin>` → inspect resolved preset, selection source, docs link, files, operations.
|
|
418
|
+
5. `bunx kitcn info --json` → project paths, versions, installed plugins, schema/lockfile mismatch, missing deps, scaffold drift.
|
|
419
|
+
6. `bunx kitcn docs <topic...>` → local/public docs links for `cli`, `plugins`, `auth`, `orm`, `migrations`, `resend`, `ratelimit`.
|
|
420
|
+
|
|
421
|
+
Rules:
|
|
422
|
+
|
|
423
|
+
1. `kitcn add <plugin>` bootstraps baseline files first when they are missing.
|
|
424
|
+
2. `--diff [path]` / `--view [path]` match workspace-relative output path by exact match first, substring fallback.
|
|
425
|
+
3. Preview scope includes scaffold files, env bootstrap, `kitcn.json`, schema registration, lockfile write, dependency install status, codegen/hooks, env reminders.
|
|
426
|
+
|
|
427
|
+
### 11.1 Dev bootstrap functions (example parity mode)
|
|
428
|
+
|
|
429
|
+
If you want the same operational model as the scaffolded baseline, use these canonical snippets.
|
|
430
|
+
|
|
431
|
+
**Create:** `convex/functions/init.ts`
|
|
432
|
+
|
|
433
|
+
```ts
|
|
434
|
+
import { z } from "zod";
|
|
435
|
+
|
|
436
|
+
import { createUser } from "../lib/auth/auth-helpers";
|
|
437
|
+
import { privateMutation } from "../lib/crpc";
|
|
438
|
+
import { getEnv } from "../lib/get-env";
|
|
439
|
+
import { createSeedHandler } from "./generated/seed.runtime";
|
|
440
|
+
|
|
441
|
+
export default privateMutation
|
|
442
|
+
.meta({ dev: true })
|
|
443
|
+
|
|
444
|
+
.mutation(async ({ ctx }) => {
|
|
445
|
+
const env = getEnv();
|
|
446
|
+
const adminEmails = env.ADMIN;
|
|
447
|
+
|
|
448
|
+
if (!adminEmails || adminEmails.length === 0) {
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
let isFirstInit = true;
|
|
453
|
+
|
|
454
|
+
for (const adminEmail of adminEmails) {
|
|
455
|
+
const existingUser = await ctx.orm.query.user.findFirst({
|
|
456
|
+
where: { email: adminEmail },
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
if (existingUser) {
|
|
460
|
+
isFirstInit = false;
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
await createUser(ctx, {
|
|
465
|
+
email: adminEmail,
|
|
466
|
+
name: "Admin",
|
|
467
|
+
role: "admin",
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (isFirstInit && getEnv().DEPLOY_ENV === "development") {
|
|
472
|
+
const handler = createSeedHandler(ctx);
|
|
473
|
+
await handler.seed({});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return null;
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**Create:** `convex/functions/reset.ts`
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
/** biome-ignore-all lint/suspicious/noExplicitAny: dev */
|
|
484
|
+
import { eq } from "kitcn/orm";
|
|
485
|
+
import { CRPCError } from "kitcn/server";
|
|
486
|
+
import { z } from "zod";
|
|
487
|
+
|
|
488
|
+
import { privateAction, privateMutation } from "../lib/crpc";
|
|
489
|
+
import { getEnv } from "../lib/get-env";
|
|
490
|
+
import type { TableNames } from "./_generated/dataModel";
|
|
491
|
+
import { createResetCaller } from "./generated/reset.runtime";
|
|
492
|
+
import schema, { tables } from "./schema";
|
|
493
|
+
|
|
494
|
+
const DELETE_BATCH_SIZE = 64;
|
|
495
|
+
const excludedTables = new Set<TableNames>();
|
|
496
|
+
|
|
497
|
+
const assertDevOnly = () => {
|
|
498
|
+
if (getEnv().DEPLOY_ENV === "production") {
|
|
499
|
+
throw new CRPCError({
|
|
500
|
+
code: "FORBIDDEN",
|
|
501
|
+
message: "This function is only available in development",
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
export const reset = privateAction.action(async ({ ctx }) => {
|
|
507
|
+
assertDevOnly();
|
|
508
|
+
const caller = createResetCaller(ctx);
|
|
509
|
+
|
|
510
|
+
for (const tableName of Object.keys(schema.tables)) {
|
|
511
|
+
if (excludedTables.has(tableName as TableNames)) {
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
await caller.schedule.now.deletePage({
|
|
516
|
+
cursor: null,
|
|
517
|
+
tableName,
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return null;
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
export const deletePage = privateMutation
|
|
525
|
+
.input(
|
|
526
|
+
z.object({
|
|
527
|
+
cursor: z.union([z.string(), z.null()]),
|
|
528
|
+
tableName: z.string(),
|
|
529
|
+
}),
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
.mutation(async ({ ctx, input }) => {
|
|
533
|
+
assertDevOnly();
|
|
534
|
+
const caller = createResetCaller(ctx);
|
|
535
|
+
|
|
536
|
+
const table = (tables as Record<string, any>)[input.tableName];
|
|
537
|
+
if (!table) {
|
|
538
|
+
throw new CRPCError({
|
|
539
|
+
code: "BAD_REQUEST",
|
|
540
|
+
message: `Unknown table: ${input.tableName}`,
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const query = (ctx.orm.query as Record<string, any>)[input.tableName];
|
|
545
|
+
if (!query || typeof query.findMany !== "function") {
|
|
546
|
+
throw new CRPCError({
|
|
547
|
+
code: "BAD_REQUEST",
|
|
548
|
+
message: `Unknown query table: ${input.tableName}`,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
const results = await query.findMany({
|
|
553
|
+
cursor: input.cursor,
|
|
554
|
+
limit: DELETE_BATCH_SIZE,
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
for (const row of results.page) {
|
|
558
|
+
try {
|
|
559
|
+
await ctx.orm.delete(table).where(eq(table.id, (row as any).id));
|
|
560
|
+
} catch {
|
|
561
|
+
// Can already be deleted by trigger or concurrent process.
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (!results.isDone) {
|
|
566
|
+
await caller.schedule.now.deletePage({
|
|
567
|
+
cursor: results.continueCursor,
|
|
568
|
+
tableName: input.tableName,
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return null;
|
|
573
|
+
});
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
`convex/functions/seed.ts` stays project-specific, but should expose a `privateMutation` entrypoint used by `init.ts`.
|
|
577
|
+
|
|
578
|
+
Recommended scripts:
|
|
579
|
+
|
|
580
|
+
```json
|
|
581
|
+
{
|
|
582
|
+
"scripts": {
|
|
583
|
+
"convex:dev": "kitcn dev",
|
|
584
|
+
"verify": "kitcn verify",
|
|
585
|
+
"reset": "kitcn reset --yes --after init",
|
|
586
|
+
"seed": "convex run seed:seed",
|
|
587
|
+
"env:push": "kitcn env push",
|
|
588
|
+
"env:push:rotate": "kitcn env push --rotate"
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
Set `dev.preRun = "init"` in `kitcn.json` when the
|
|
594
|
+
app owns an `init.ts` preflight.
|
|
595
|
+
|
|
596
|
+
CLI commands:
|
|
597
|
+
|
|
598
|
+
```bash
|
|
599
|
+
bunx kitcn dev
|
|
600
|
+
# deterministic one-shot local runtime proof:
|
|
601
|
+
bunx kitcn verify
|
|
602
|
+
# optional fallback only if dev cannot run and backend is already active:
|
|
603
|
+
bunx kitcn codegen
|
|
604
|
+
bunx kitcn env push
|
|
605
|
+
bunx kitcn env push --prod
|
|
606
|
+
bunx kitcn env push --rotate
|
|
607
|
+
# deploy with automatic aggregate backfill:
|
|
608
|
+
bunx kitcn deploy --prod
|
|
609
|
+
# aggregate index management:
|
|
610
|
+
bunx kitcn aggregate rebuild --prod
|
|
611
|
+
bunx kitcn aggregate backfill --prod
|
|
612
|
+
# bundle analysis:
|
|
613
|
+
bunx kitcn analyze
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
On backend `convex`, `kitcn dev` watches `convex/.env` during a local
|
|
617
|
+
dev session and auto-pushes later edits. Keep `env push` for `--prod`,
|
|
618
|
+
`--rotate`, or explicit repair against an already active deployment.
|
|
619
|
+
|
|
620
|
+
### 11.2 Phase A gate: non-auth baseline (required before auth work)
|
|
621
|
+
|
|
622
|
+
Run these after base setup (Sections 3-5) and before starting Section 6:
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
bunx kitcn verify
|
|
626
|
+
bunx convex run internal.seed.seed
|
|
627
|
+
bunx convex run internal.init.default
|
|
628
|
+
# run project checks after bootstrap smoke:
|
|
629
|
+
bun run typecheck || bunx tsc --noEmit
|
|
630
|
+
bun test
|
|
631
|
+
bun run build
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
Then sanity-check runtime paths (non-auth only):
|
|
635
|
+
|
|
636
|
+
1. Run one public query endpoint.
|
|
637
|
+
2. Run one public mutation endpoint.
|
|
638
|
+
3. Run one public HTTP route endpoint.
|
|
639
|
+
4. Do not proceed to Section 6 until this gate is green.
|
|
640
|
+
|
|
641
|
+
### 11.3 Phase B gate: auth sign-in working (required before optional modules/plugins)
|
|
642
|
+
|
|
643
|
+
Run this after Section 6 and before Sections 7-10:
|
|
644
|
+
|
|
645
|
+
```bash
|
|
646
|
+
bunx kitcn verify
|
|
647
|
+
bun run typecheck || bunx tsc --noEmit
|
|
648
|
+
bun test
|
|
649
|
+
bun run build
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Then sanity-check auth runtime paths:
|
|
653
|
+
|
|
654
|
+
1. Sign in successfully from `/auth` in headed browser.
|
|
655
|
+
2. Run one protected query/mutation in signed-in context and confirm success.
|
|
656
|
+
3. Run one protected endpoint in signed-out context and confirm `UNAUTHORIZED`.
|
|
657
|
+
4. Do not proceed to optional modules/plugins until this gate is green.
|
|
658
|
+
|
|
659
|
+
## 12. Final From-Scratch Execution Checklist
|
|
660
|
+
|
|
661
|
+
1. `convex.json` configured with `functions: convex/functions` and static codegen enabled.
|
|
662
|
+
2. `tsconfig.json` has `strictFunctionTypes: false` and `@convex/*` alias.
|
|
663
|
+
3. `.env.local` has `NEXT_PUBLIC_CONVEX_URL` and `NEXT_PUBLIC_CONVEX_SITE_URL`.
|
|
664
|
+
4. `schema.ts` + `relations` + generated `initCRPC` wiring are in place.
|
|
665
|
+
5. `crpc.ts` builders exported and app procedures use `ctx.orm`.
|
|
666
|
+
6. `kitcn dev` runs and generates `_generated` + `api.ts`.
|
|
667
|
+
7. If auth enabled: `auth.config.ts`, `auth.ts`, `http.ts`, and env bootstrap
|
|
668
|
+
are complete.
|
|
669
|
+
8. Client `CRPCProvider` + QueryClient + Convex provider are mounted.
|
|
670
|
+
9. Framework branch is complete (Next.js or TanStack Start).
|
|
671
|
+
10. If using typed envs: `convex/lib/get-env.ts` exists and Convex code reads through `getEnv()`.
|
|
672
|
+
11. Optional modules/plugins added only if selected.
|
|
673
|
+
12. If multiple components enabled: `convex/functions/convex.config.ts` composes all `app.use(...)` calls in one file.
|
|
674
|
+
13. If organizations + invite mail enabled: `email.tsx` + invite template + resend component are wired.
|
|
675
|
+
14. If dev bootstrap mode enabled: `init.ts`, `seed.ts`, `reset.ts` exist and scripts call them.
|
|
676
|
+
15. If `Aggregates: No`, no aggregate helper/import/config references remain.
|
|
677
|
+
16. Phase A gate (Section 11.2) passes before any auth implementation.
|
|
678
|
+
17. If auth enabled: Phase B auth sign-in gate (Section 11.3) passes before optional modules/plugins.
|
|
679
|
+
18. No legacy Ents patterns in setup code.
|
|
680
|
+
19. NEVER use `@ts-nocheck` in app/convex source files.
|
|
681
|
+
|
|
682
|
+
## 13. Troubleshooting
|
|
683
|
+
|
|
684
|
+
See the [Troubleshooting Reference](#troubleshooting-reference) at the bottom of this document for the full symptom/cause/fix matrix.
|
|
685
|
+
|
|
686
|
+
## Coverage Matrix
|
|
687
|
+
|
|
688
|
+
Source coverage mapping used to build this runbook:
|
|
689
|
+
|
|
690
|
+
| Source | Mapped In Setup |
|
|
691
|
+
| ------------------------------------------------- | -------------------- |
|
|
692
|
+
| `www/content/docs/cli/registry.mdx` | Sections 3, 11 |
|
|
693
|
+
| `www/content/docs/quickstart.mdx` | Sections 3, 4, 11, 12 |
|
|
694
|
+
| `www/content/docs/server/setup.mdx` | Section 5.3 |
|
|
695
|
+
| `www/content/docs/auth/server.mdx` | Sections 6.1 - 6.10 |
|
|
696
|
+
| `www/content/docs/auth/client.mdx` | Section 7.1 |
|
|
697
|
+
| `www/content/docs/auth/server.mdx#triggers` | Section 6.3, 9.2 |
|
|
698
|
+
| `www/content/docs/react/index.mdx` | Sections 7.2 - 7.4 |
|
|
699
|
+
| `www/content/docs/nextjs/index.mdx` | Section 8.A |
|
|
700
|
+
| `www/content/docs/tanstack-start.mdx` | Section 8.B |
|
|
701
|
+
| `www/content/docs/server/http.mdx` | Sections 6.6, 9.6 |
|
|
702
|
+
| `www/content/docs/server/server-side-calls.mdx` | Section 8.A.1, 8.B.3 |
|
|
703
|
+
| `www/content/docs/plugins/ratelimit.mdx` | Section 9.4 |
|
|
704
|
+
| `www/content/docs/orm/queries/aggregates.mdx` | Section 9.3 |
|
|
705
|
+
| `www/content/docs/server/scheduling.mdx` | Section 9.5 |
|
|
706
|
+
| `www/content/docs/orm/queries/index.mdx` | Sections 5, 12 |
|
|
707
|
+
| `www/content/docs/orm/mutations/index.mdx` | Sections 5, 12 |
|
|
708
|
+
| `www/content/docs/orm/triggers.mdx` | Sections 9.2, 9.3 |
|
|
709
|
+
| `www/content/docs/orm/rls.mdx` | Section 9.1 |
|
|
710
|
+
| `www/content/docs/auth/plugins/admin.mdx` | Section 10.1 |
|
|
711
|
+
| `www/content/docs/auth/plugins/organizations.mdx` | Section 10.2 |
|
|
712
|
+
| `www/content/docs/auth/plugins/polar.mdx` | Section 10.3 |
|
|
713
|
+
| `www/content/docs/cli/backend.mdx` | Section 11 |
|
|
714
|
+
|
|
715
|
+
### Template Coverage (Recreation Target)
|
|
716
|
+
|
|
717
|
+
This runbook + references map to the canonical template shape as follows:
|
|
718
|
+
|
|
719
|
+
| Example Group | Primary Setup Section | Additional Reference |
|
|
720
|
+
| --------------------------------------------------------------------------------------------------------- | ------------------------------- | ---------------------------------------- |
|
|
721
|
+
| Core infra (`schema.ts`, `functions/generated/`, `crpc.ts`, `http.ts`) | Sections 5, 6.6, 9.6 | `orm.md`, `http.md` |
|
|
722
|
+
| Shared contracts (`shared/api.ts`, `shared/auth-shared.ts`, `shared/polar-shared.ts`) | Sections 5.4, 6.3.2, 10.2, 10.3 | `auth-organizations.md` |
|
|
723
|
+
| Auth core (`auth.config.ts`, `auth.ts`) | Section 6 | `auth.md` |
|
|
724
|
+
| Auth plugins (`admin.ts`, `organization.ts`, `polar*`) | Section 10 | `auth-admin.md`, `auth-organizations.md` |
|
|
725
|
+
| Feature modules (`user.ts`, `projects.ts`, `tags.ts`, `todoComments.ts`, `public.ts`, `items/queries.ts`) | Sections 5, 6.3.1, 9 | core `SKILL.md`, `orm.md` |
|
|
726
|
+
| HTTP routers (`routers/health.ts`, `routers/todos.ts`, `routers/examples.ts`) | Section 9.6 | `http.md` |
|
|
727
|
+
| Aggregates + rate limits (`aggregates.ts`, `lib/plugins/ratelimit/plugin.ts`) | Sections 9.3, 9.4 | `aggregates.md`, `orm.md` |
|
|
728
|
+
| Scheduling + internals (`todoInternal.ts`, delayed jobs) | Sections 9.5, 11.1 | `scheduling.md` |
|
|
729
|
+
| Email + Resend (`functions/plugins/email.tsx`, `lib/plugins/resend/*`) | Section 9.7 | `auth-organizations.md` |
|
|
730
|
+
| Dev bootstrap (`init.ts`, `seed.ts`, `reset.ts`) | Section 11.1 | `testing.md` (for verification) |
|
|
731
|
+
| Generated outputs (`functions/_generated/*`, `functions/generated/`, `shared/api.ts`) | Section 5.5 | n/a (generated by CLI) |
|
|
732
|
+
|
|
733
|
+
## Troubleshooting Reference
|
|
734
|
+
|
|
735
|
+
| Symptom | Likely Cause | Fix |
|
|
736
|
+
| ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
737
|
+
| `@convex/api` not found | `kitcn dev` not run | Run `bunx kitcn dev` and regenerate API metadata |
|
|
738
|
+
| `Cannot prompt for input in non-interactive terminals` during bootstrap | Convex deployment selection still needs a local choice | Use `bunx kitcn verify` for local proof, or pass `--env-file` / deployment-target args so Convex can resolve the deployment without prompting |
|
|
739
|
+
| Can't find new local backend files under `~/.convex` | Convex now stores new local deployment state per project | Check `.convex/local/default/` in the current project root; treat `~/.convex/**` as legacy storage |
|
|
740
|
+
| `kitcn env push` fails to set auth vars | Target deployment is not active or not initialized | For local proof, run `bunx kitcn verify`. For remote targets, resolve deployment targeting, then rerun `bunx kitcn env push` |
|
|
741
|
+
| `Failed to analyze auth.js` with `Unexpected token` / `map is not a function` on JWKS | Static `JWKS` value is malformed JSON | Unset/fix `JWKS`; use `getAuthConfigProvider()` fallback or repush with `bunx kitcn env push` |
|
|
742
|
+
| `Local backend isn't running` during manual `kitcn codegen` | Convex local deployment not active | Prefer `bunx kitcn dev` (it already codegens); use manual `codegen` only as fallback with active backend |
|
|
743
|
+
| HTTP calls fail but queries work | `.site` URL missing or wrong | Set `NEXT_PUBLIC_CONVEX_SITE_URL` correctly |
|
|
744
|
+
| Auth works locally but fails in prod | JWKS not pushed | Run `bunx kitcn env push --prod` |
|
|
745
|
+
| Sign-in fails on `/auth` (loop, no session, or immediate sign-out) | Auth route/env/provider wiring mismatch | Recheck Sections 6.5-6.7 (`authMiddleware`, route registration, env push), verify provider credentials/URLs, then rerun Section 11.3 |
|
|
746
|
+
| `UNAUTHORIZED` on protected procedures | auth middleware not attaching `userId` | Ensure `getAuth(ctx)` + `getHeaders(ctx)` session lookup is in middleware |
|
|
747
|
+
| `ctx.orm` missing in handlers | Generated `initCRPC` not used | Use `initCRPC` from `../functions/generated/server` — ORM context is pre-wired |
|
|
748
|
+
| `Property 'insert'/'update' does not exist on type 'OrmReader'` | Using query context for mutations | Ensure mutation handlers use `publicMutation` / `protectedMutation` builders |
|
|
749
|
+
| `useCRPC must be used within CRPCProvider` | Provider chain not mounted around route tree | Wrap app with `AppConvexProvider` and verify `CRPCProvider` is inside QueryClientProvider (Section 7.4 / 8.A.4) |
|
|
750
|
+
| Route auth cookies not set | Missing CORS auth headers | Add `Better-Auth-Cookie` allow/expose headers + credentials |
|
|
751
|
+
| TanStack Start auth helper import errors | Using `kitcn/auth/nextjs` in Start app | Use TanStack Start exception with `@convex-dev/better-auth/*` helpers |
|
|
752
|
+
| `Returned promise will never resolve` from internal function | Trigger path is recursively querying/updating related rows or stale component wiring still runs | Isolate failing write with logs, disable/move trigger-side sync into explicit mutation helper, rerun `bunx kitcn verify`, then retry the runtime proof |
|
|
753
|
+
| Better Auth secret mismatch/warnings in setup flows | `BETTER_AUTH_SECRET` manually set inconsistently or low entropy | Let `bunx kitcn dev` manage local bootstrap, or regenerate/push via `bunx kitcn env push` for active non-local targets |
|
|
754
|
+
| `Invalid orderBy value. Use a column or asc()/desc()` | Wrong `orderBy` shape (`[{ field, direction }]`) | Use object form only, e.g. `orderBy: { updatedAt: "desc" }` |
|
|
755
|
+
| `Invalid argument id for db.get` while testing `NOT_FOUND` | Fabricated Convex document ID | Use real inserted IDs or non-ID lookup keys (slug/name/email) for not-found tests |
|
|
756
|
+
| Trigger side effects too slow | Heavy sync work inside trigger | Move heavy work to scheduled actions via `ctx.scheduler` |
|
|
757
|
+
| Rate limiter throws missing-table/setup guidance | local ratelimit scaffold missing or not registered | Run `bunx kitcn add ratelimit`, then ensure `convex/functions/schema.ts` imports `../lib/plugins/ratelimit/schema` |
|
|
758
|
+
| fallback `kitcn codegen` fails after disabling aggregates | Aggregate helper/import references still exist | Remove `app.use(aggregate...)`, `defineTriggers` aggregate handlers, and aggregate helper modules in the same change; prefer rerunning `kitcn verify` |
|
|
759
|
+
| Aggregate counts drift | trigger not registered in `defineTriggers` | Register `aggregate.trigger` in `defineTriggers` `change:` handler |
|
|
760
|
+
| Invite emails never send | Resend schema scaffold missing or not registered | Run `bunx kitcn add resend`, ensure `convex/functions/schema.ts` imports `../lib/plugins/resend/schema`, and wire `internal.plugins.email.sendTemplatedEmail` |
|
|
761
|
+
| Dev reset/seed commands do nothing | `init.ts`/`seed.ts`/`reset.ts` missing or not wired | Add dev bootstrap functions and scripts from Section 11.1 |
|