@robsun/create-keystone-app 0.1.12 → 0.1.13
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/create-keystone-app.js +3 -0
- package/package.json +1 -1
- package/template/README.md +8 -0
- package/template/config.yaml +39 -1
- package/template/docs/CONVENTIONS.md +134 -0
|
@@ -114,6 +114,9 @@ function stripDemo(targetDir) {
|
|
|
114
114
|
updateFile(path.join(targetDir, 'apps', 'web', 'src', 'app.config.ts'), (content) =>
|
|
115
115
|
content.replace(/,\s*['"]demo['"]/, '')
|
|
116
116
|
);
|
|
117
|
+
updateFile(path.join(targetDir, 'config.yaml'), (content) =>
|
|
118
|
+
content.replace(/\r?\n\s*-\s*['"]demo['"]\s*/g, '')
|
|
119
|
+
);
|
|
117
120
|
updateFile(path.join(targetDir, 'README.md'), (content) => {
|
|
118
121
|
let next = content.replace(
|
|
119
122
|
'Minimal Keystone platform shell (web + server) with a demo module.',
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# __RAW_NAME__
|
|
2
2
|
Minimal Keystone platform shell (web + server) with a demo module.
|
|
3
3
|
|
|
4
|
+
## Guides
|
|
5
|
+
- `docs/CONVENTIONS.md` - module structure, routing/menu/permission rules, API patterns, and tests.
|
|
6
|
+
|
|
4
7
|
## Prereqs
|
|
5
8
|
- Node 18+ and pnpm
|
|
6
9
|
- Go 1.23+
|
|
@@ -21,6 +24,11 @@ pnpm server:dev
|
|
|
21
24
|
pnpm dev
|
|
22
25
|
```
|
|
23
26
|
|
|
27
|
+
## Project Structure
|
|
28
|
+
- `apps/web/`: React + Vite shell and business modules (`src/modules/*`).
|
|
29
|
+
- `apps/server/`: Go API and module wiring (demo routes by default).
|
|
30
|
+
- `config.yaml`: runtime config (ports, database, queue, storage).
|
|
31
|
+
|
|
24
32
|
Demo module:
|
|
25
33
|
|
|
26
34
|
- Menu: Demo Tasks
|
package/template/config.yaml
CHANGED
|
@@ -1,13 +1,51 @@
|
|
|
1
1
|
server:
|
|
2
2
|
port: "8080"
|
|
3
3
|
mode: "debug"
|
|
4
|
+
swagger_enabled: true
|
|
5
|
+
|
|
6
|
+
modules:
|
|
7
|
+
enabled:
|
|
8
|
+
- "keystone"
|
|
9
|
+
- "demo"
|
|
10
|
+
|
|
4
11
|
database:
|
|
5
12
|
driver: "sqlite"
|
|
13
|
+
host: "localhost"
|
|
14
|
+
port: "5432"
|
|
15
|
+
user: "keystone"
|
|
16
|
+
password: "keystone"
|
|
17
|
+
dbname: "keystone"
|
|
18
|
+
sslmode: "disable"
|
|
6
19
|
path: "./data/keystone-local.db"
|
|
20
|
+
|
|
7
21
|
jwt:
|
|
8
22
|
secret: "change-me-in-prod"
|
|
23
|
+
access_token_ttl: 2
|
|
24
|
+
refresh_token_ttl: 168
|
|
25
|
+
|
|
26
|
+
approval:
|
|
27
|
+
callback_secret: ""
|
|
28
|
+
|
|
29
|
+
pdf:
|
|
30
|
+
font_path: ""
|
|
31
|
+
|
|
9
32
|
queue:
|
|
10
33
|
driver: "memory"
|
|
34
|
+
buffer: 200
|
|
35
|
+
redis:
|
|
36
|
+
addr: "localhost:6379"
|
|
37
|
+
password: ""
|
|
38
|
+
db: 0
|
|
39
|
+
key: "keystone:jobs"
|
|
40
|
+
|
|
11
41
|
storage:
|
|
12
42
|
driver: "local"
|
|
13
|
-
local_dir: "./storage"
|
|
43
|
+
local_dir: "./storage"
|
|
44
|
+
base_url: ""
|
|
45
|
+
s3:
|
|
46
|
+
endpoint: ""
|
|
47
|
+
region: ""
|
|
48
|
+
bucket: ""
|
|
49
|
+
access_key: ""
|
|
50
|
+
secret_key: ""
|
|
51
|
+
use_ssl: true
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Keystone App Conventions
|
|
2
|
+
|
|
3
|
+
## Goals
|
|
4
|
+
- Keep modules predictable across web and server.
|
|
5
|
+
- Keep routing, menus, permissions, and help content in one place.
|
|
6
|
+
- Follow the tradeflow app patterns for structure and naming.
|
|
7
|
+
|
|
8
|
+
## Project Layout
|
|
9
|
+
- `apps/web/`: React + Vite app.
|
|
10
|
+
- `apps/server/`: Go API app.
|
|
11
|
+
- `apps/web/src/app.config.ts`: web runtime config (modules, branding, approval).
|
|
12
|
+
- `config.yaml`: server runtime config (modules, database, queue, storage).
|
|
13
|
+
|
|
14
|
+
## Frontend Module Rules
|
|
15
|
+
- Each business module lives in `apps/web/src/modules/<module>`.
|
|
16
|
+
- `index.ts` must register the module:
|
|
17
|
+
- `registerModule({ name, routes, i18n })`.
|
|
18
|
+
- `routes.tsx` owns menu/breadcrumb/permission metadata via `handle`.
|
|
19
|
+
- Pages go in `pages/`, shared UI in `components/`, API calls in `services/`, types in `types.ts`, shared state in `stores/`.
|
|
20
|
+
- Lazy-load page components and wrap with `Suspense`.
|
|
21
|
+
|
|
22
|
+
Example module entry:
|
|
23
|
+
```ts
|
|
24
|
+
import { registerModule } from '@robsun/keystone-web-core'
|
|
25
|
+
import { orderRoutes } from './routes'
|
|
26
|
+
|
|
27
|
+
registerModule({ name: 'orders', routes: orderRoutes })
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Example route meta:
|
|
31
|
+
```tsx
|
|
32
|
+
{
|
|
33
|
+
path: 'orders',
|
|
34
|
+
element: <Outlet />,
|
|
35
|
+
handle: {
|
|
36
|
+
menu: { label: 'Orders', icon: <FileTextOutlined />, permission: 'sales:order:view' },
|
|
37
|
+
breadcrumb: 'Orders',
|
|
38
|
+
permission: 'sales:order:view',
|
|
39
|
+
helpKey: 'sales/orders',
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Permissions and Menu Rules
|
|
45
|
+
- Permission format: `domain:resource:action` (wildcards allowed, e.g. `inventory:*:*`).
|
|
46
|
+
- Menus are derived from `handle.menu`. If a route should not appear, omit `handle.menu`.
|
|
47
|
+
- Breadcrumbs are derived from `handle.breadcrumb`.
|
|
48
|
+
- Use `handle.menu.order` to control menu ordering when needed.
|
|
49
|
+
|
|
50
|
+
## Help Docs
|
|
51
|
+
- Store help markdown under `apps/web/src/modules/<module>/help/**`.
|
|
52
|
+
- Use frontmatter keys: `helpKey`, `title`, `description`, `category`, `tags`, `relatedKeys`.
|
|
53
|
+
- Route `handle.helpKey` must match the markdown `helpKey`.
|
|
54
|
+
- Enable app help by pointing Vite to your help folder (`helpDir` in `vite.config.ts`).
|
|
55
|
+
|
|
56
|
+
Frontmatter example:
|
|
57
|
+
```md
|
|
58
|
+
---
|
|
59
|
+
helpKey: "inventory/warehouses"
|
|
60
|
+
title: "Warehouse Management"
|
|
61
|
+
description: "Manage warehouses and locations."
|
|
62
|
+
category: "inventory"
|
|
63
|
+
tags: ["warehouse", "location"]
|
|
64
|
+
relatedKeys: ["inventory/stock"]
|
|
65
|
+
---
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## API and Services
|
|
69
|
+
- Use `api` from `@robsun/keystone-web-core` for HTTP.
|
|
70
|
+
- If your API base path changes, call `setApiBaseUrl` once at startup.
|
|
71
|
+
- Keep API calls in `services/*.ts`, return typed data, and let pages handle UI state.
|
|
72
|
+
- For paginated endpoints, map `page`/`page_size` (server) to `page`/`pageSize` (web).
|
|
73
|
+
|
|
74
|
+
Example service:
|
|
75
|
+
```ts
|
|
76
|
+
import { api, type ApiResponse, type PaginatedData } from '@robsun/keystone-web-core'
|
|
77
|
+
|
|
78
|
+
export async function listItems(page = 1, pageSize = 20) {
|
|
79
|
+
const { data } = await api.get<ApiResponse<PaginatedData<Item>>>('/items', {
|
|
80
|
+
params: { page, page_size: pageSize },
|
|
81
|
+
})
|
|
82
|
+
return data.data
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## State
|
|
87
|
+
- Use local state for single pages.
|
|
88
|
+
- Use zustand stores for shared state or cross-page flows.
|
|
89
|
+
- Store shape should include `loading`, `error`, `filters`, and a `fetch` method.
|
|
90
|
+
|
|
91
|
+
## Naming
|
|
92
|
+
- Page components: `*Page.tsx` (e.g. `InventoryListPage.tsx`).
|
|
93
|
+
- API modules: `services/api.ts` or `services/<feature>.ts`.
|
|
94
|
+
- Store modules: `stores/*Store.ts` or `stores/use*Store.ts`.
|
|
95
|
+
- Domain types: `types.ts` (export interfaces and enums).
|
|
96
|
+
|
|
97
|
+
## Backend Module Rules
|
|
98
|
+
For production modules, mirror this layout:
|
|
99
|
+
```
|
|
100
|
+
apps/server/internal/modules/<module>/
|
|
101
|
+
module.go
|
|
102
|
+
api/routes/
|
|
103
|
+
api/handler/
|
|
104
|
+
domain/service/
|
|
105
|
+
infra/repository/
|
|
106
|
+
bootstrap/migrations/
|
|
107
|
+
bootstrap/seeds/
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Module interface (simplified):
|
|
111
|
+
```go
|
|
112
|
+
type Module interface {
|
|
113
|
+
Name() string
|
|
114
|
+
RegisterRoutes(rg *gin.RouterGroup)
|
|
115
|
+
RegisterModels() []interface{}
|
|
116
|
+
RegisterPermissions(reg *permissions.Registry) error
|
|
117
|
+
RegisterJobs(reg *jobs.Registry) error
|
|
118
|
+
Migrate(db *gorm.DB) error
|
|
119
|
+
Seed(db *gorm.DB) error
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Register modules and enable them via `config.yaml` (`modules.enabled`).
|
|
124
|
+
Keep the enabled list aligned with `app.config.ts`.
|
|
125
|
+
|
|
126
|
+
## Routing and Responses (Server)
|
|
127
|
+
- Mount API under `/api/v1`.
|
|
128
|
+
- Use auth, rbac, and tenant guards consistently across module routes.
|
|
129
|
+
- Use `github.com/robsuncn/keystone/api/response` helpers for JSON responses.
|
|
130
|
+
|
|
131
|
+
## Testing
|
|
132
|
+
- Web: `apps/web/tests/{unit,component,e2e,perf}` with `*.test.ts(x)`.
|
|
133
|
+
- Server: `apps/server/tests/{unit,integration,e2e,fixtures}` with `*_test.go`.
|
|
134
|
+
- Run `go test ./...` for server changes; add a web test runner when needed.
|