create-kuckit-app 0.3.4 → 0.4.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/bin.js +1 -1
- package/dist/{create-project-CP-h4Ygi.js → create-project-geQBZ0Ru.js} +5 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/templates/base/.claude/skills/kuckit/SKILL.md +22 -2
- package/templates/base/.claude/skills/kuckit/references/MODULE-DEVELOPMENT.md +39 -28
- package/templates/base/.claude/skills/kuckit/references/PACKAGES.md +94 -74
- package/templates/base/AGENTS.md +86 -15
- package/templates/base/apps/server/AGENTS.md +35 -10
- package/templates/base/apps/server/package.json +7 -7
- package/templates/base/apps/server/src/auth.ts +1 -1
- package/templates/base/apps/server/src/config/modules.ts +7 -8
- package/templates/base/apps/server/src/container.ts +3 -1
- package/templates/base/apps/server/src/module-rest-routes.ts +47 -0
- package/templates/base/apps/server/src/rest-router-registry.ts +32 -0
- package/templates/base/apps/server/src/rpc.ts +1 -1
- package/templates/base/apps/server/src/server.ts +2 -0
- package/templates/base/apps/server/tsdown.config.ts +8 -0
- package/templates/base/apps/web/package.json +9 -9
- package/templates/base/apps/web/src/services/auth-client.ts +1 -1
- package/templates/base/{packages/db/src/migrations → drizzle}/0000_init.sql +35 -30
- package/templates/base/{packages/db/src/migrations → drizzle}/meta/_journal.json +1 -1
- package/templates/base/drizzle.config.ts +38 -0
- package/templates/base/package.json +14 -9
- package/templates/base/packages/items-module/package.json +7 -7
- package/templates/base/packages/items-module/src/api/items.router.ts +1 -1
- package/templates/base/packages/api/AGENTS.md +0 -66
- package/templates/base/packages/api/package.json +0 -35
- package/templates/base/packages/api/src/context.ts +0 -48
- package/templates/base/packages/api/src/index.ts +0 -22
- package/templates/base/packages/api/tsconfig.json +0 -8
- package/templates/base/packages/auth/AGENTS.md +0 -61
- package/templates/base/packages/auth/package.json +0 -27
- package/templates/base/packages/auth/src/index.ts +0 -22
- package/templates/base/packages/auth/tsconfig.json +0 -8
- package/templates/base/packages/db/AGENTS.md +0 -74
- package/templates/base/packages/db/drizzle.config.ts +0 -19
- package/templates/base/packages/db/package.json +0 -36
- package/templates/base/packages/db/src/connection.ts +0 -40
- package/templates/base/packages/db/src/index.ts +0 -4
- package/templates/base/packages/db/src/schema/auth.ts +0 -51
- package/templates/base/packages/db/tsconfig.json +0 -8
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as createProject } from "./create-project-
|
|
2
|
+
import { t as createProject } from "./create-project-geQBZ0Ru.js";
|
|
3
3
|
import { program } from "commander";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -73,6 +73,11 @@ Next steps:
|
|
|
73
73
|
bun run db:migrate # Run database migrations
|
|
74
74
|
bun run dev # Start development server
|
|
75
75
|
|
|
76
|
+
Deploy to GCP:
|
|
77
|
+
|
|
78
|
+
bun add -D @kuckit/infra-gcp
|
|
79
|
+
bunx kuckit infra up # One-command deploy
|
|
80
|
+
|
|
76
81
|
Inside that directory, you can run:
|
|
77
82
|
|
|
78
83
|
bun run dev Start the development server
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -193,14 +193,34 @@ export const kuckitClientModule = defineKuckitClientModule({
|
|
|
193
193
|
|
|
194
194
|
### Module package.json Metadata
|
|
195
195
|
|
|
196
|
+
Modules depend on `@kuckit/*` npm packages:
|
|
197
|
+
|
|
196
198
|
```json
|
|
197
199
|
{
|
|
198
200
|
"name": "@acme/billing-module",
|
|
201
|
+
"version": "0.1.0",
|
|
202
|
+
"type": "module",
|
|
203
|
+
"exports": {
|
|
204
|
+
".": "./src/index.ts",
|
|
205
|
+
"./client": "./src/client-module.ts"
|
|
206
|
+
},
|
|
207
|
+
"peerDependencies": {
|
|
208
|
+
"@kuckit/sdk": "^1.0.0",
|
|
209
|
+
"@kuckit/sdk-react": "^1.0.0",
|
|
210
|
+
"typescript": "^5"
|
|
211
|
+
},
|
|
212
|
+
"dependencies": {
|
|
213
|
+
"@kuckit/api": "^1.0.0",
|
|
214
|
+
"@orpc/server": "^1.10.0",
|
|
215
|
+
"@orpc/zod": "^1.10.0",
|
|
216
|
+
"drizzle-orm": "^0.44.0",
|
|
217
|
+
"zod": "^3.23.0",
|
|
218
|
+
"react": "^19.0.0"
|
|
219
|
+
},
|
|
199
220
|
"kuckit": {
|
|
200
221
|
"id": "acme.billing",
|
|
201
222
|
"server": "./dist/module.js",
|
|
202
|
-
"client": "./dist/client
|
|
203
|
-
"schema": "./src/server/schema/index.ts"
|
|
223
|
+
"client": "./dist/client-module.js"
|
|
204
224
|
}
|
|
205
225
|
}
|
|
206
226
|
```
|
|
@@ -6,50 +6,61 @@ Complete guide for developing Kuckit modules.
|
|
|
6
6
|
|
|
7
7
|
### Generated Module Layout
|
|
8
8
|
|
|
9
|
+
Modules follow Clean Architecture internally with all layers self-contained:
|
|
10
|
+
|
|
9
11
|
```
|
|
10
12
|
packages/billing-module/
|
|
11
13
|
├── src/
|
|
12
|
-
│ ├──
|
|
13
|
-
│
|
|
14
|
-
│ ├──
|
|
15
|
-
│ │
|
|
16
|
-
│
|
|
17
|
-
│ └──
|
|
18
|
-
│
|
|
19
|
-
│
|
|
20
|
-
│
|
|
21
|
-
│
|
|
22
|
-
│
|
|
23
|
-
│
|
|
24
|
-
|
|
14
|
+
│ ├── domain/
|
|
15
|
+
│ │ └── billing.entity.ts # Zod schema for entity
|
|
16
|
+
│ ├── ports/
|
|
17
|
+
│ │ └── billing.repository.ts # Repository interface
|
|
18
|
+
│ ├── adapters/
|
|
19
|
+
│ │ └── billing.drizzle.ts # Drizzle implementation
|
|
20
|
+
│ ├── usecases/
|
|
21
|
+
│ │ ├── list-billings.ts
|
|
22
|
+
│ │ ├── get-billing.ts
|
|
23
|
+
│ │ ├── create-billing.ts
|
|
24
|
+
│ │ └── delete-billing.ts
|
|
25
|
+
│ ├── api/
|
|
26
|
+
│ │ └── billings.router.ts # oRPC router
|
|
27
|
+
│ ├── ui/
|
|
28
|
+
│ │ └── BillingsPage.tsx # React component
|
|
29
|
+
│ ├── module.ts # Server module
|
|
30
|
+
│ ├── client-module.ts # Client module
|
|
31
|
+
│ └── index.ts
|
|
32
|
+
├── package.json # Uses @kuckit/* from npm
|
|
25
33
|
└── tsconfig.json
|
|
26
34
|
```
|
|
27
35
|
|
|
28
36
|
### package.json Metadata
|
|
29
37
|
|
|
38
|
+
Modules depend on `@kuckit/*` npm packages:
|
|
39
|
+
|
|
30
40
|
```json
|
|
31
41
|
{
|
|
32
42
|
"name": "@acme/billing-module",
|
|
33
43
|
"version": "1.0.0",
|
|
34
44
|
"type": "module",
|
|
35
|
-
"kuckit": {
|
|
36
|
-
"id": "acme.billing",
|
|
37
|
-
"server": "./dist/module.js",
|
|
38
|
-
"client": "./dist/client/module.js",
|
|
39
|
-
"schema": "./src/server/schema/index.ts"
|
|
40
|
-
},
|
|
41
45
|
"exports": {
|
|
42
|
-
".":
|
|
43
|
-
|
|
44
|
-
"types": "./dist/index.d.ts"
|
|
45
|
-
},
|
|
46
|
-
"./client": {
|
|
47
|
-
"import": "./dist/client/index.js",
|
|
48
|
-
"types": "./dist/client/index.d.ts"
|
|
49
|
-
}
|
|
46
|
+
".": "./src/index.ts",
|
|
47
|
+
"./client": "./src/client-module.ts"
|
|
50
48
|
},
|
|
51
49
|
"peerDependencies": {
|
|
52
|
-
"@kuckit/sdk": "
|
|
50
|
+
"@kuckit/sdk": "^1.0.0",
|
|
51
|
+
"@kuckit/sdk-react": "^1.0.0",
|
|
52
|
+
"typescript": "^5"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@kuckit/api": "^1.0.0",
|
|
56
|
+
"@orpc/server": "^1.10.0",
|
|
57
|
+
"drizzle-orm": "^0.44.0",
|
|
58
|
+
"zod": "^3.23.0"
|
|
59
|
+
},
|
|
60
|
+
"kuckit": {
|
|
61
|
+
"id": "acme.billing",
|
|
62
|
+
"server": "./dist/module.js",
|
|
63
|
+
"client": "./dist/client-module.js"
|
|
53
64
|
}
|
|
54
65
|
}
|
|
55
66
|
```
|
|
@@ -1,67 +1,82 @@
|
|
|
1
1
|
# Kuckit Package Reference
|
|
2
2
|
|
|
3
|
-
Quick reference for all packages
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
3
|
+
Quick reference for all `@kuckit/*` packages from npm.
|
|
4
|
+
|
|
5
|
+
## Framework Packages
|
|
6
|
+
|
|
7
|
+
These are installed from npm as dependencies, not copied into your project:
|
|
8
|
+
|
|
9
|
+
| Package | Description |
|
|
10
|
+
| ------------------- | ------------------------------------------------------ |
|
|
11
|
+
| `@kuckit/sdk` | Server-side module system, DI container, core services |
|
|
12
|
+
| `@kuckit/sdk-react` | Client-side module system, hooks, providers |
|
|
13
|
+
| `@kuckit/api` | oRPC procedures (publicProcedure, protectedProcedure) |
|
|
14
|
+
| `@kuckit/db` | Drizzle ORM utilities and connection |
|
|
15
|
+
| `@kuckit/auth` | Better-Auth configuration |
|
|
16
|
+
| `@kuckit/domain` | Base types, Logger, Clock interfaces |
|
|
17
|
+
| `@kuckit/contracts` | Shared DTOs and Zod schemas |
|
|
18
|
+
|
|
19
|
+
## Your Project Structure
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
your-app/
|
|
23
|
+
├── apps/
|
|
24
|
+
│ ├── server/ # Express bootstrap (imports @kuckit/* from npm)
|
|
25
|
+
│ └── web/ # React bootstrap (imports @kuckit/* from npm)
|
|
26
|
+
├── packages/
|
|
27
|
+
│ └── your-module/ # Your modules with Clean Architecture
|
|
28
|
+
├── node_modules/
|
|
29
|
+
│ └── @kuckit/ # Framework packages from npm
|
|
30
|
+
├── package.json # Lists @kuckit/* deps
|
|
31
|
+
└── drizzle.config.ts # Points to @kuckit/db + module schemas
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Key Files Per Framework Package
|
|
26
35
|
|
|
27
36
|
### @kuckit/sdk
|
|
28
37
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `src/config/loader.ts` | Configuration loading |
|
|
38
|
-
| `src/schema/registry.ts` | Schema registry |
|
|
39
|
-
|
|
40
|
-
### @kuckit/cli
|
|
41
|
-
|
|
42
|
-
| File | Purpose |
|
|
43
|
-
| --------------------------------- | ------------------------------ |
|
|
44
|
-
| `src/bin.ts` | CLI entry point (Commander.js) |
|
|
45
|
-
| `src/commands/generate-module.ts` | Module scaffolding |
|
|
46
|
-
| `src/commands/add-module.ts` | Module installation |
|
|
47
|
-
| `src/commands/discover-module.ts` | Module discovery |
|
|
48
|
-
| `src/commands/doctor.ts` | Project validation |
|
|
49
|
-
| `src/commands/auth.ts` | Authentication commands |
|
|
50
|
-
| `src/commands/db.ts` | Database commands |
|
|
51
|
-
| `src/commands/infra/*.ts` | Infrastructure commands |
|
|
52
|
-
| `src/lib/credentials.ts` | Token storage |
|
|
53
|
-
| `src/lib/sdk-loader.ts` | Dynamic SDK loading |
|
|
38
|
+
| Export | Purpose |
|
|
39
|
+
| ----------------------- | ------------------------ |
|
|
40
|
+
| `createKuckitContainer` | DI container creation |
|
|
41
|
+
| `loadKuckitModules` | Module loading |
|
|
42
|
+
| `defineKuckitModule` | Server module definition |
|
|
43
|
+
| `disposeContainer` | Container cleanup |
|
|
44
|
+
| `asClass`, `asFunction` | DI registration helpers |
|
|
45
|
+
| `asValue` | DI value registration |
|
|
54
46
|
|
|
55
47
|
### @kuckit/sdk-react
|
|
56
48
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
|
|
49
|
+
| Export | Purpose |
|
|
50
|
+
| -------------------------- | ------------------------ |
|
|
51
|
+
| `defineKuckitClientModule` | Client module definition |
|
|
52
|
+
| `loadKuckitClientModules` | Client module loading |
|
|
53
|
+
| `KuckitNavProvider` | Navigation provider |
|
|
54
|
+
| `useKuckitNav` | Navigation hook |
|
|
55
|
+
| `useRpc` | RPC client hook |
|
|
56
|
+
|
|
57
|
+
### @kuckit/api
|
|
58
|
+
|
|
59
|
+
| Export | Purpose |
|
|
60
|
+
| -------------------- | ----------------------- |
|
|
61
|
+
| `publicProcedure` | Public oRPC procedure |
|
|
62
|
+
| `protectedProcedure` | Auth-required procedure |
|
|
63
|
+
| `createContext` | oRPC context factory |
|
|
64
|
+
| `appRouter` | Base app router |
|
|
65
|
+
|
|
66
|
+
### @kuckit/db
|
|
67
|
+
|
|
68
|
+
| Export | Purpose |
|
|
69
|
+
| ------------ | -------------------------- |
|
|
70
|
+
| `createDb` | Drizzle instance factory |
|
|
71
|
+
| `createPool` | PostgreSQL pool factory |
|
|
72
|
+
| `authSchema` | Better-Auth schema exports |
|
|
73
|
+
|
|
74
|
+
### @kuckit/auth
|
|
75
|
+
|
|
76
|
+
| Export | Purpose |
|
|
77
|
+
| ------------ | --------------------- |
|
|
78
|
+
| `auth` | Better-Auth instance |
|
|
79
|
+
| `authClient` | Client auth utilities |
|
|
65
80
|
|
|
66
81
|
## Import Patterns
|
|
67
82
|
|
|
@@ -83,30 +98,35 @@ import {
|
|
|
83
98
|
loadKuckitClientModules,
|
|
84
99
|
KuckitNavProvider,
|
|
85
100
|
useKuckitNav,
|
|
101
|
+
useRpc,
|
|
86
102
|
} from '@kuckit/sdk-react'
|
|
87
103
|
|
|
88
|
-
//
|
|
89
|
-
import {
|
|
104
|
+
// API imports (for modules)
|
|
105
|
+
import { protectedProcedure, publicProcedure } from '@kuckit/api'
|
|
90
106
|
|
|
91
|
-
//
|
|
92
|
-
import {
|
|
93
|
-
|
|
94
|
-
// Contracts imports
|
|
95
|
-
import { CreateUserInput, UserDTO, createUserSchema } from '@kuckit/contracts'
|
|
107
|
+
// Database imports
|
|
108
|
+
import { createDb, createPool } from '@kuckit/db/connection'
|
|
96
109
|
```
|
|
97
110
|
|
|
98
111
|
## Package Dependencies
|
|
99
112
|
|
|
100
113
|
### What Each Package Can Import
|
|
101
114
|
|
|
102
|
-
| Package
|
|
103
|
-
|
|
|
104
|
-
|
|
|
105
|
-
|
|
|
106
|
-
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
|
115
|
+
| Package | Allowed Imports |
|
|
116
|
+
| ------------ | ------------------------------- |
|
|
117
|
+
| Your modules | @kuckit/\* packages, zod |
|
|
118
|
+
| apps/server | @kuckit/\*, your modules |
|
|
119
|
+
| apps/web | @kuckit/sdk-react, your modules |
|
|
120
|
+
|
|
121
|
+
### Module Internal Layers
|
|
122
|
+
|
|
123
|
+
Within your modules, follow Clean Architecture:
|
|
124
|
+
|
|
125
|
+
| Layer | Can Import |
|
|
126
|
+
| -------- | ----------------------------- |
|
|
127
|
+
| domain | (none - pure Zod schemas) |
|
|
128
|
+
| ports | domain |
|
|
129
|
+
| usecases | domain, ports |
|
|
130
|
+
| adapters | domain, drizzle-orm |
|
|
131
|
+
| api | domain, usecases, @kuckit/api |
|
|
132
|
+
| ui | @kuckit/sdk-react, react |
|
package/templates/base/AGENTS.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
```bash
|
|
6
6
|
bun install # Install dependencies
|
|
7
7
|
docker compose up -d # Start PostgreSQL
|
|
8
|
-
bun run db:
|
|
8
|
+
bun run db:push # Sync schema to database (dev) or db:migrate (prod)
|
|
9
9
|
bun run dev # Start dev servers (web + server)
|
|
10
10
|
```
|
|
11
11
|
|
|
@@ -17,15 +17,15 @@ __APP_NAME_KEBAB__/
|
|
|
17
17
|
│ ├── server/ # Express + oRPC backend (port 3000)
|
|
18
18
|
│ └── web/ # React + TanStack Router frontend (port 3001)
|
|
19
19
|
├── packages/
|
|
20
|
-
│ ├── api/ # Shared API context and types
|
|
21
|
-
│ ├── auth/ # Better-Auth configuration
|
|
22
|
-
│ ├── db/ # Drizzle ORM, migrations, schema
|
|
23
20
|
│ └── items-module/ # Example Kuckit module (reference implementation)
|
|
24
21
|
├── .env.example # Environment template
|
|
25
22
|
├── docker-compose.yml # PostgreSQL container
|
|
23
|
+
├── drizzle.config.ts # Drizzle pointing to @kuckit/db + module schemas
|
|
26
24
|
└── turbo.json # Turborepo configuration
|
|
27
25
|
```
|
|
28
26
|
|
|
27
|
+
**Note:** Core packages (`api`, `auth`, `db`, `domain`, `contracts`) are installed from npm as `@kuckit/*` dependencies, not copied into your project.
|
|
28
|
+
|
|
29
29
|
## Module Development
|
|
30
30
|
|
|
31
31
|
Kuckit uses a **module-based architecture** where each module contains its own Clean Architecture layers internally.
|
|
@@ -47,15 +47,21 @@ packages/your-module/
|
|
|
47
47
|
|
|
48
48
|
### Creating a New Module
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
```bash
|
|
51
|
+
bunx kuckit generate module your-module
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This scaffolds a full Clean Architecture module. Then:
|
|
55
|
+
|
|
56
|
+
1. Implement your domain entities in `domain/`
|
|
57
|
+
2. Define repository interfaces in `ports/`
|
|
58
|
+
3. Implement adapters in `adapters/`
|
|
59
|
+
4. Create use cases in `usecases/`
|
|
60
|
+
5. Expose API in `api/` via oRPC router
|
|
61
|
+
6. Register module in `apps/server/src/config/modules.ts`
|
|
62
|
+
7. Add client module to `apps/web/src/modules.client.ts`
|
|
63
|
+
8. Add schema path to `drizzle.config.ts` in project root
|
|
64
|
+
9. Run `bun run db:push` to create the table
|
|
59
65
|
|
|
60
66
|
### Dependency Rules
|
|
61
67
|
|
|
@@ -256,6 +262,26 @@ export const wireModuleRpcRouters = (registrations: ApiRegistration[]) => {
|
|
|
256
262
|
}
|
|
257
263
|
```
|
|
258
264
|
|
|
265
|
+
### REST Router Pattern
|
|
266
|
+
|
|
267
|
+
For modules that need direct Express response access (e.g., AI streaming with `pipeUIMessageStreamToResponse`), use REST routers instead of oRPC:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// In your module's registerApi()
|
|
271
|
+
ctx.addApiRegistration({
|
|
272
|
+
type: 'rest-router',
|
|
273
|
+
name: 'ai',
|
|
274
|
+
router: createAiRouter(),
|
|
275
|
+
prefix: '/ai', // Optional, defaults to /<name>
|
|
276
|
+
})
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
REST routers are mounted at `/api<prefix>` (e.g., `/api/ai/chat`). They receive:
|
|
280
|
+
|
|
281
|
+
- Per-request scoped container via `req.scope`
|
|
282
|
+
- Session via `req.scope.cradle.session`
|
|
283
|
+
- Full Express `Request` and `Response` objects
|
|
284
|
+
|
|
259
285
|
### Typing DI in Routers
|
|
260
286
|
|
|
261
287
|
Use a module-local interface to type `context.di.cradle`:
|
|
@@ -284,14 +310,14 @@ export const invoicesRouter = {
|
|
|
284
310
|
|
|
285
311
|
### Add a new database table
|
|
286
312
|
|
|
287
|
-
1. Define schema in your module's `adapters/`
|
|
313
|
+
1. Define schema in your module's `adapters/` directory
|
|
288
314
|
2. Run `bun run db:generate`
|
|
289
315
|
3. Run `bun run db:migrate`
|
|
290
316
|
|
|
291
317
|
### Add authentication to an endpoint
|
|
292
318
|
|
|
293
319
|
```typescript
|
|
294
|
-
import { protectedProcedure } from '@
|
|
320
|
+
import { protectedProcedure } from '@kuckit/api'
|
|
295
321
|
|
|
296
322
|
export const myRouter = {
|
|
297
323
|
protectedRoute: protectedProcedure.input(mySchema).handler(async ({ input, context }) => {
|
|
@@ -342,6 +368,51 @@ See `.env.example` for required variables:
|
|
|
342
368
|
- `PORT` - Server port (default: 3000)
|
|
343
369
|
- `VITE_API_URL` - API URL for frontend
|
|
344
370
|
|
|
371
|
+
## Troubleshooting
|
|
372
|
+
|
|
373
|
+
### 404 Errors on API Calls
|
|
374
|
+
|
|
375
|
+
**Symptom**: `POST /rpc/items/list 404 (Not Found)` with multiple retries
|
|
376
|
+
|
|
377
|
+
**Cause**: Server and client modules are out of sync. The client has a module registered but the server doesn't.
|
|
378
|
+
|
|
379
|
+
**Fix**: Ensure both files register the same modules:
|
|
380
|
+
|
|
381
|
+
- `apps/server/src/config/modules.ts` - Server modules
|
|
382
|
+
- `apps/web/src/modules.client.ts` - Client modules
|
|
383
|
+
|
|
384
|
+
**Prevention**: Run `bunx kuckit doctor` to detect mismatches.
|
|
385
|
+
|
|
386
|
+
### "Relation does not exist" Database Errors
|
|
387
|
+
|
|
388
|
+
**Symptom**: `error: relation "items" does not exist`
|
|
389
|
+
|
|
390
|
+
**Cause**: Module schema not registered in `drizzle.config.ts`.
|
|
391
|
+
|
|
392
|
+
**Fix**: Add the module's schema path to `drizzle.config.ts` (in project root):
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
schema: [
|
|
396
|
+
'./node_modules/@kuckit/db/dist/schema/auth.js',
|
|
397
|
+
'./packages/your-module/src/adapters',
|
|
398
|
+
],
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Then run:
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
bun run db:generate
|
|
405
|
+
bun run db:migrate
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Module Not Appearing in Navigation
|
|
409
|
+
|
|
410
|
+
**Symptom**: Module pages work but nav items don't show.
|
|
411
|
+
|
|
412
|
+
**Cause**: Client module not registered or missing `navItems`.
|
|
413
|
+
|
|
414
|
+
**Fix**: Verify module is in `apps/web/src/modules.client.ts` and defines `navItems` in `defineKuckitClientModule()`.
|
|
415
|
+
|
|
345
416
|
## Related Documentation
|
|
346
417
|
|
|
347
418
|
- [Kuckit SDK](https://github.com/draphonix/kuckit)
|
|
@@ -8,14 +8,16 @@ Express backend hosting oRPC API, Better-Auth authentication, and the Kuckit mod
|
|
|
8
8
|
|
|
9
9
|
## Key Files
|
|
10
10
|
|
|
11
|
-
| File
|
|
12
|
-
|
|
|
13
|
-
| `server.ts`
|
|
14
|
-
| `container.ts`
|
|
15
|
-
| `config/modules.ts`
|
|
16
|
-
| `rpc.ts`
|
|
17
|
-
| `rpc-router-registry.ts`
|
|
18
|
-
| `
|
|
11
|
+
| File | Purpose |
|
|
12
|
+
| ------------------------- | -------------------------- |
|
|
13
|
+
| `server.ts` | Entry point, bootstrap |
|
|
14
|
+
| `container.ts` | DI container setup |
|
|
15
|
+
| `config/modules.ts` | Module registration |
|
|
16
|
+
| `rpc.ts` | oRPC handler setup |
|
|
17
|
+
| `rpc-router-registry.ts` | Mutable router for modules |
|
|
18
|
+
| `rest-router-registry.ts` | REST router collection |
|
|
19
|
+
| `module-rest-routes.ts` | REST router wiring |
|
|
20
|
+
| `auth.ts` | Better-Auth configuration |
|
|
19
21
|
|
|
20
22
|
## Module Loading Sequence
|
|
21
23
|
|
|
@@ -26,10 +28,11 @@ The server bootstraps in this order:
|
|
|
26
28
|
2. loadKuckitModules() with onApiRegistrations callback:
|
|
27
29
|
├─► register() hooks run (DI bindings)
|
|
28
30
|
├─► registerApi() hooks run (routers collected)
|
|
29
|
-
├─► onApiRegistrations() - Wire
|
|
31
|
+
├─► onApiRegistrations() - Wire RPC and REST routers
|
|
30
32
|
└─► onBootstrap() hooks run (startup logic)
|
|
31
33
|
3. setupRPC() - Create RPCHandler AFTER modules loaded
|
|
32
|
-
4. Express
|
|
34
|
+
4. setupModuleRestRouters() - Mount REST routers to Express
|
|
35
|
+
5. Express listens
|
|
33
36
|
```
|
|
34
37
|
|
|
35
38
|
## Router Registry Pattern
|
|
@@ -56,12 +59,34 @@ await loadKuckitModules({
|
|
|
56
59
|
modules: getModuleSpecs(),
|
|
57
60
|
onApiRegistrations: (registrations) => {
|
|
58
61
|
wireModuleRpcRouters(registrations) // Wire BEFORE setupRPC()
|
|
62
|
+
collectModuleRestRouters(registrations) // Collect REST routers
|
|
59
63
|
},
|
|
60
64
|
})
|
|
61
65
|
|
|
62
66
|
setupRPC(app) // Now create handler with fully-wired router
|
|
67
|
+
setupModuleRestRouters(app) // Mount REST routers at /api/<name>
|
|
63
68
|
```
|
|
64
69
|
|
|
70
|
+
## REST Router Pattern
|
|
71
|
+
|
|
72
|
+
For modules that need direct Express response access (e.g., AI streaming), use REST routers:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// In your module's registerApi()
|
|
76
|
+
ctx.addApiRegistration({
|
|
77
|
+
type: 'rest-router',
|
|
78
|
+
name: 'ai',
|
|
79
|
+
router: createAiRouter(),
|
|
80
|
+
prefix: '/ai', // Optional, defaults to /<name>
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
REST routers are mounted at `/api<prefix>` (e.g., `/api/ai/chat`). They receive:
|
|
85
|
+
|
|
86
|
+
- Per-request scoped container via `req.scope`
|
|
87
|
+
- Session via `req.scope.cradle.session`
|
|
88
|
+
- Full Express `Request` and `Response` objects
|
|
89
|
+
|
|
65
90
|
## Per-Request Scoping
|
|
66
91
|
|
|
67
92
|
Each HTTP request gets a scoped container with:
|
|
@@ -10,17 +10,17 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"express": "^5.1.0",
|
|
12
12
|
"cors": "^2.8.5",
|
|
13
|
-
"dotenv": "^17.
|
|
13
|
+
"dotenv": "^17.0.0",
|
|
14
14
|
"awilix": "^12.0.5",
|
|
15
15
|
"pg": "^8.14.1",
|
|
16
16
|
"@orpc/server": "^1.10.0",
|
|
17
17
|
"@orpc/zod": "^1.10.0",
|
|
18
|
-
"better-auth": "^1.3.
|
|
19
|
-
"zod": "^
|
|
20
|
-
"@kuckit/sdk": "^
|
|
21
|
-
"@
|
|
22
|
-
"@
|
|
23
|
-
"@
|
|
18
|
+
"better-auth": "^1.3.0",
|
|
19
|
+
"zod": "^3.23.0",
|
|
20
|
+
"@kuckit/sdk": "^2.0.0",
|
|
21
|
+
"@kuckit/api": "^2.0.0",
|
|
22
|
+
"@kuckit/auth": "^2.0.0",
|
|
23
|
+
"@kuckit/db": "^2.0.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/express": "^5.0.1",
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import type { ModuleSpec } from '@kuckit/sdk'
|
|
2
|
-
|
|
3
|
-
// Import your modules here
|
|
4
|
-
// import { kuckitModule as itemsModule } from '@__APP_NAME_KEBAB__/items-module'
|
|
2
|
+
import { kuckitModule as itemsModule } from '@__APP_NAME_KEBAB__/items-module'
|
|
5
3
|
|
|
6
4
|
/**
|
|
7
5
|
* Module specifications for the server application
|
|
8
6
|
*
|
|
9
7
|
* Add modules here to configure the server's functionality.
|
|
10
8
|
* Modules are loaded in order, with dependencies resolved automatically.
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT: Server and client modules must be kept in sync!
|
|
11
|
+
* If you add/remove a module here, also update apps/web/src/modules.client.ts
|
|
11
12
|
*/
|
|
12
13
|
export const getModuleSpecs = (): ModuleSpec[] => {
|
|
13
14
|
const modules: ModuleSpec[] = [
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
//
|
|
17
|
-
// config: { ... },
|
|
18
|
-
// },
|
|
15
|
+
// KUCKIT_SERVER_MODULES_START
|
|
16
|
+
{ module: itemsModule },
|
|
17
|
+
// KUCKIT_SERVER_MODULES_END
|
|
19
18
|
]
|
|
20
19
|
|
|
21
20
|
return modules
|