create-questpie 2.0.1 → 2.0.2

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.
Files changed (37) hide show
  1. package/README.md +10 -6
  2. package/dist/index.mjs +139 -24
  3. package/package.json +5 -3
  4. package/skills/questpie/AGENTS.md +2664 -0
  5. package/skills/questpie/SKILL.md +181 -0
  6. package/skills/questpie/references/auth.md +121 -0
  7. package/skills/questpie/references/business-logic.md +550 -0
  8. package/skills/questpie/references/codegen-plugin-api.md +382 -0
  9. package/skills/questpie/references/crud-api.md +378 -0
  10. package/skills/questpie/references/data-modeling.md +489 -0
  11. package/skills/questpie/references/extend.md +493 -0
  12. package/skills/questpie/references/field-types.md +386 -0
  13. package/skills/questpie/references/infrastructure-adapters.md +545 -0
  14. package/skills/questpie/references/multi-tenancy.md +364 -0
  15. package/skills/questpie/references/production.md +475 -0
  16. package/skills/questpie/references/query-operators.md +125 -0
  17. package/skills/questpie/references/quickstart.md +549 -0
  18. package/skills/questpie/references/rules.md +327 -0
  19. package/skills/questpie/references/tanstack-query.md +520 -0
  20. package/skills/questpie-admin/AGENTS.md +1442 -0
  21. package/skills/questpie-admin/SKILL.md +410 -0
  22. package/skills/questpie-admin/references/blocks.md +307 -0
  23. package/skills/questpie-admin/references/custom-ui.md +305 -0
  24. package/skills/questpie-admin/references/views.md +433 -0
  25. package/templates/tanstack-start/AGENTS.md +17 -13
  26. package/templates/tanstack-start/CLAUDE.md +15 -12
  27. package/templates/tanstack-start/README.md +19 -13
  28. package/templates/tanstack-start/env.example +1 -1
  29. package/templates/tanstack-start/package.json +20 -6
  30. package/templates/tanstack-start/src/lib/env.ts +1 -1
  31. package/templates/tanstack-start/src/questpie/server/config/admin.ts +27 -30
  32. package/templates/tanstack-start/src/routeTree.gen.ts +138 -0
  33. package/templates/tanstack-start/src/routes/__root.tsx +0 -2
  34. package/templates/tanstack-start/src/routes/admin.tsx +8 -1
  35. package/templates/tanstack-start/src/tanstack-start.d.ts +1 -0
  36. package/templates/tanstack-start/src/vite-env.d.ts +1 -0
  37. package/templates/tanstack-start/vite.config.ts +1 -3
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: questpie
3
+ description: QUESTPIE framework — server-first TypeScript CMS. File-convention codegen, collections, globals, routes, jobs, services, emails, blocks, typed client SDK, TanStack Query integration, adapters (queue, search, realtime, storage, email, KV). Use when building, reviewing, or refactoring any QUESTPIE project.
4
+ license: MIT
5
+ metadata:
6
+ author: questpie
7
+ version: "3.0.0"
8
+ ---
9
+
10
+ # QUESTPIE Framework
11
+
12
+ Server-first TypeScript application framework. Define your data schema once using standalone factories, codegen generates the typed runtime, and any frontend consumes it through introspection.
13
+
14
+ ## When to Apply
15
+
16
+ Reference these guidelines when:
17
+ - Creating or modifying collections, globals, routes, jobs, services, emails, blocks
18
+ - Working with file conventions or codegen pipeline
19
+ - Configuring adapters (queue, search, storage, realtime, email, KV)
20
+ - Setting up access control, hooks, or validation
21
+ - Building typed client SDK queries or TanStack Query integrations
22
+ - Writing modules or plugins for QUESTPIE
23
+ - Scaffolding a new project or onboarding
24
+
25
+ ## Import Paths — Critical
26
+
27
+ | Factory | Import From | Needs Codegen? |
28
+ |---|---|---|
29
+ | `collection(name)` | `#questpie/factories` | Yes |
30
+ | `global(name)` | `#questpie/factories` | Yes |
31
+ | `block(name)` | `#questpie/factories` | Yes |
32
+ | `adminConfig({...})` | `#questpie/factories` | Yes |
33
+ | `route()` | `"questpie"` | No |
34
+ | `job({...})` | `"questpie"` | No |
35
+ | `service()` | `"questpie"` | No |
36
+ | `email({...})` | `"questpie"` | No |
37
+ | `migration({...})` | `"questpie"` | No |
38
+ | `seed({...})` | `"questpie"` | No |
39
+ | `runtimeConfig({...})` | `"questpie"` | No |
40
+ | `appConfig({...})` | `"questpie"` | No |
41
+ | `authConfig({...})` | `"questpie"` | No |
42
+ | `createClient<AppConfig>()` | `"questpie/client"` | No |
43
+ | `createQuestpieQueryOptions()` | `"@questpie/tanstack-query"` | No |
44
+
45
+ ## Reference Topics
46
+
47
+ ### Core
48
+
49
+ | Topic | File | Covers |
50
+ |---|---|---|
51
+ | Quickstart | `references/quickstart.md` | Scaffold, configure, codegen, migrate, serve — zero to running app |
52
+ | Data Modeling | `references/data-modeling.md` | Collections, globals, fields, relations, options, localization |
53
+ | Field Types | `references/field-types.md` | All built-in field types with options and operators |
54
+ | Rules | `references/rules.md` | Access control (row/field level), hooks lifecycle, validation |
55
+ | Business Logic | `references/business-logic.md` | Routes, jobs, services, email templates, context injection |
56
+ | CRUD API | `references/crud-api.md` | Server-side `find`, `create`, `update`, `delete`, globals API |
57
+ | Query Operators | `references/query-operators.md` | `where` clause operators by field type |
58
+
59
+ ### Infrastructure
60
+
61
+ | Topic | File | Covers |
62
+ |---|---|---|
63
+ | Production | `references/production.md` | Queue, search, realtime, storage, email, KV adapter setup |
64
+ | Auth | `references/auth.md` | Better Auth integration, session, providers, access patterns |
65
+ | Adapters | `references/infrastructure-adapters.md` | All adapter configs: pg-boss, S3, SMTP, pgNotify, Redis |
66
+
67
+ ### Extend
68
+
69
+ | Topic | File | Covers |
70
+ |---|---|---|
71
+ | Extend | `references/extend.md` | Custom modules, fields, operators, adapters, codegen plugins |
72
+ | Codegen Plugin API | `references/codegen-plugin-api.md` | Plugin architecture, category declarations, templates |
73
+ | Multi-Tenancy | `references/multi-tenancy.md` | Scope isolation, workspace filtering, ScopeProvider |
74
+
75
+ ### Client
76
+
77
+ | Topic | File | Covers |
78
+ |---|---|---|
79
+ | TanStack Query | `references/tanstack-query.md` | `q.collections.*`, `q.globals.*`, `q.routes.*`, realtime queries |
80
+
81
+ ## Key Patterns — Quick Reference
82
+
83
+ ### Collection
84
+
85
+ ```ts
86
+ import { collection } from "#questpie/factories";
87
+
88
+ export default collection("posts")
89
+ .fields(({ f }) => ({
90
+ title: f.text().required(),
91
+ status: f.select([{ value: "draft", label: "Draft" }]),
92
+ author: f.relation("users").required(),
93
+ }))
94
+ .access({
95
+ read: true,
96
+ create: ({ session }) => !!session,
97
+ update: ({ session, doc }) => doc.authorId === session?.user?.id,
98
+ })
99
+ .hooks({
100
+ beforeChange: async ({ data, operation }) => {
101
+ if (operation === "create") data.slug = slugify(data.title);
102
+ return data;
103
+ },
104
+ })
105
+ .options({ versioning: true, timestamps: true });
106
+ ```
107
+
108
+ ### Route
109
+
110
+ ```ts
111
+ import { route } from "questpie";
112
+ import z from "zod";
113
+
114
+ export default route()
115
+ .post()
116
+ .schema(z.object({ period: z.enum(["day", "week", "month"]) }))
117
+ .handler(async ({ input, collections }) => {
118
+ return collections.posts.find({ where: { status: "published" } });
119
+ });
120
+ ```
121
+
122
+ ### Job
123
+
124
+ ```ts
125
+ import { job } from "questpie";
126
+ import z from "zod";
127
+
128
+ export default job({
129
+ name: "sendReminder",
130
+ schema: z.object({ userId: z.string() }),
131
+ retryDelay: 5, // seconds (not ms!)
132
+ handler: async ({ payload, email, collections }) => {
133
+ const user = await collections.users.findOne({ where: { id: payload.userId } });
134
+ await email.send("reminder", { to: user.email, data: { name: user.name } });
135
+ },
136
+ });
137
+ ```
138
+
139
+ ### Client SDK
140
+
141
+ ```ts
142
+ import { createClient } from "questpie/client";
143
+ import type { AppConfig } from "#questpie";
144
+
145
+ const client = createClient<AppConfig>({
146
+ baseURL: typeof window !== "undefined" ? window.location.origin : process.env.APP_URL,
147
+ basePath: "/api",
148
+ });
149
+
150
+ const { docs } = await client.collections.posts.find({
151
+ where: { status: "published" },
152
+ orderBy: { createdAt: "desc" },
153
+ with: { author: true },
154
+ });
155
+ ```
156
+
157
+ ### Queue Dispatch
158
+
159
+ ```ts
160
+ // In any handler with AppContext:
161
+ await queue.sendReminder.publish({ userId: "abc" });
162
+ // NOT queue.send("sendReminder", payload)
163
+ ```
164
+
165
+ ## Common Mistakes
166
+
167
+ | Severity | Mistake | Fix |
168
+ |---|---|---|
169
+ | CRITICAL | Files in wrong directory | Collections in `collections/`, routes in `routes/`, etc. |
170
+ | CRITICAL | Missing `export default` on convention files | Codegen silently ignores files without default export |
171
+ | CRITICAL | Importing route/job/service from `#questpie/factories` | Use `"questpie"` — only collection/global/block/adminConfig use `#questpie/factories` |
172
+ | HIGH | Forgetting `questpie generate` after adding files | Re-run codegen on any file add/remove in convention dirs |
173
+ | HIGH | Job handler uses `input` instead of `payload` | Jobs destructure `{ payload }`, routes destructure `{ input }` |
174
+ | HIGH | `queue.send("name", data)` | Use `queue.jobName.publish(data)` |
175
+ | HIGH | `beforeCreate` / `afterCreate` hook names | Use `beforeChange` / `afterChange` with `operation === "create"` guard |
176
+ | MEDIUM | Using npm/yarn instead of Bun | QUESTPIE requires Bun as package manager |
177
+ | MEDIUM | Editing `.generated/` files | Never edit — re-run `questpie generate` |
178
+
179
+ ## Full Compiled Document
180
+
181
+ For the complete framework reference with all topics expanded: `AGENTS.md`
@@ -0,0 +1,121 @@
1
+ # Authentication Reference
2
+
3
+ Detailed authentication configuration for QUESTPIE using Better Auth.
4
+
5
+ ## File Convention
6
+
7
+ Auth is configured via `config/auth.ts` using the `authConfig()` factory:
8
+
9
+ ```ts
10
+ // src/questpie/server/config/auth.ts
11
+ import { authConfig } from "questpie";
12
+
13
+ export default authConfig({
14
+ emailAndPassword: {
15
+ enabled: true,
16
+ requireEmailVerification: false,
17
+ },
18
+ baseURL: process.env.APP_URL || "http://localhost:3000",
19
+ basePath: "/api/auth",
20
+ secret: process.env.BETTER_AUTH_SECRET || "change-me",
21
+ });
22
+ ```
23
+
24
+ Codegen discovers this file automatically. No manual registration needed.
25
+
26
+ ## Configuration Options
27
+
28
+ | Option | Type | Default | Description |
29
+ | ------------------------------------------- | --------- | ------------- | ----------------------------------------------------------- |
30
+ | `emailAndPassword.enabled` | `boolean` | `false` | Enable email/password authentication |
31
+ | `emailAndPassword.requireEmailVerification` | `boolean` | `false` | Require email verification before login |
32
+ | `baseURL` | `string` | — | Application public URL (used for OAuth callbacks) |
33
+ | `basePath` | `string` | `"/api/auth"` | Auth API route prefix |
34
+ | `secret` | `string` | — | Session signing secret. **Must be 32+ chars in production** |
35
+
36
+ ## Session Access
37
+
38
+ ### In Routes
39
+
40
+ ```ts
41
+ import { route } from "questpie";
42
+ import z from "zod";
43
+
44
+ export default route()
45
+ .post()
46
+ .schema(z.object({ postId: z.string() }))
47
+ .handler(async ({ input, session, collections }) => {
48
+ if (!session) {
49
+ throw new Error("Not authenticated");
50
+ }
51
+
52
+ const user = session.user;
53
+ // user.id - unique user ID
54
+ // user.email - user email address
55
+ // user.name - user display name
56
+
57
+ const post = await collections.posts.create({
58
+ title: "My Post",
59
+ author: user.id,
60
+ });
61
+
62
+ return post;
63
+ });
64
+ ```
65
+
66
+ ### In Hooks
67
+
68
+ ```ts
69
+ .hooks({
70
+ beforeChange: async ({ data, operation, session }) => {
71
+ if (operation === "create") {
72
+ if (!session) throw new Error("Must be logged in");
73
+ data.createdBy = session.user.id;
74
+ }
75
+ return data;
76
+ },
77
+ })
78
+ ```
79
+
80
+ ### In Access Rules
81
+
82
+ ```ts
83
+ .access({
84
+ // Public read
85
+ read: true,
86
+
87
+ // Authenticated users can create
88
+ create: ({ session }) => !!session,
89
+
90
+ // Only admins can update/delete
91
+ update: ({ session }) => (session?.user as any)?.role === "admin",
92
+ delete: ({ session }) => (session?.user as any)?.role === "admin",
93
+ })
94
+ ```
95
+
96
+ ## User Collection
97
+
98
+ The `adminModule` provides a built-in `user` collection. It stores:
99
+
100
+ - `id` -- unique identifier
101
+ - `email` -- email address
102
+ - `name` -- display name
103
+ - `image` -- avatar URL
104
+ - `emailVerified` -- verification status
105
+
106
+ This collection is automatically created when you add the admin module to your config.
107
+
108
+ ## Environment Variables
109
+
110
+ | Variable | Required | Description |
111
+ | -------------------- | ---------- | --------------------------------------------------------- |
112
+ | `APP_URL` | Yes | Public URL -- used for OAuth callback URLs |
113
+ | `BETTER_AUTH_SECRET` | Yes (prod) | Session signing secret. Use a random 32+ character string |
114
+
115
+ ## Production Security Checklist
116
+
117
+ 1. Set `BETTER_AUTH_SECRET` to a strong random value (32+ chars)
118
+ 2. Set `APP_URL` to your production domain (HTTPS)
119
+ 3. Enable `requireEmailVerification` if using email/password
120
+ 4. Use HTTPS for all auth endpoints
121
+ 5. Configure proper CORS if API and frontend are on different domains