create-chaaskit 0.1.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.
Files changed (122) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +25 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/add-infra.d.ts +6 -0
  6. package/dist/commands/add-infra.d.ts.map +1 -0
  7. package/dist/commands/add-infra.js +160 -0
  8. package/dist/commands/add-infra.js.map +1 -0
  9. package/dist/commands/build.d.ts +2 -0
  10. package/dist/commands/build.d.ts.map +1 -0
  11. package/dist/commands/build.js +63 -0
  12. package/dist/commands/build.js.map +1 -0
  13. package/dist/commands/db-sync.d.ts +13 -0
  14. package/dist/commands/db-sync.d.ts.map +1 -0
  15. package/dist/commands/db-sync.js +108 -0
  16. package/dist/commands/db-sync.js.map +1 -0
  17. package/dist/commands/dev.d.ts +7 -0
  18. package/dist/commands/dev.d.ts.map +1 -0
  19. package/dist/commands/dev.js +61 -0
  20. package/dist/commands/dev.js.map +1 -0
  21. package/dist/commands/init.d.ts +9 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +214 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +57 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/templates/.env.example +24 -0
  30. package/dist/templates/README.md +81 -0
  31. package/dist/templates/app/components/AcceptInviteClient.tsx +10 -0
  32. package/dist/templates/app/components/AdminDashboardClient.tsx +10 -0
  33. package/dist/templates/app/components/AdminTeamClient.tsx +10 -0
  34. package/dist/templates/app/components/AdminTeamsClient.tsx +10 -0
  35. package/dist/templates/app/components/AdminUsersClient.tsx +10 -0
  36. package/dist/templates/app/components/ApiKeysClient.tsx +10 -0
  37. package/dist/templates/app/components/AutomationsClient.tsx +10 -0
  38. package/dist/templates/app/components/ChatClient.tsx +13 -0
  39. package/dist/templates/app/components/ClientOnly.tsx +6 -0
  40. package/dist/templates/app/components/DocumentsClient.tsx +10 -0
  41. package/dist/templates/app/components/OAuthConsentClient.tsx +10 -0
  42. package/dist/templates/app/components/PricingClient.tsx +10 -0
  43. package/dist/templates/app/components/TeamSettingsClient.tsx +10 -0
  44. package/dist/templates/app/components/VerifyEmailClient.tsx +10 -0
  45. package/dist/templates/app/entry.client.tsx +12 -0
  46. package/dist/templates/app/entry.server.tsx +67 -0
  47. package/dist/templates/app/root.tsx +91 -0
  48. package/dist/templates/app/routes/_index.tsx +82 -0
  49. package/dist/templates/app/routes/admin._index.tsx +57 -0
  50. package/dist/templates/app/routes/admin.teams.$teamId.tsx +57 -0
  51. package/dist/templates/app/routes/admin.teams._index.tsx +57 -0
  52. package/dist/templates/app/routes/admin.users.tsx +57 -0
  53. package/dist/templates/app/routes/api-keys.tsx +57 -0
  54. package/dist/templates/app/routes/automations.tsx +57 -0
  55. package/dist/templates/app/routes/chat._index.tsx +11 -0
  56. package/dist/templates/app/routes/chat.admin._index.tsx +10 -0
  57. package/dist/templates/app/routes/chat.admin.teams.$teamId.tsx +10 -0
  58. package/dist/templates/app/routes/chat.admin.teams._index.tsx +10 -0
  59. package/dist/templates/app/routes/chat.admin.users.tsx +10 -0
  60. package/dist/templates/app/routes/chat.api-keys.tsx +10 -0
  61. package/dist/templates/app/routes/chat.automations.tsx +10 -0
  62. package/dist/templates/app/routes/chat.documents.tsx +10 -0
  63. package/dist/templates/app/routes/chat.team.$teamId.settings.tsx +10 -0
  64. package/dist/templates/app/routes/chat.thread.$threadId.tsx +11 -0
  65. package/dist/templates/app/routes/chat.tsx +39 -0
  66. package/dist/templates/app/routes/documents.tsx +57 -0
  67. package/dist/templates/app/routes/invite.$token.tsx +10 -0
  68. package/dist/templates/app/routes/login.tsx +334 -0
  69. package/dist/templates/app/routes/oauth.consent.tsx +10 -0
  70. package/dist/templates/app/routes/pricing.tsx +10 -0
  71. package/dist/templates/app/routes/privacy.tsx +197 -0
  72. package/dist/templates/app/routes/register.tsx +398 -0
  73. package/dist/templates/app/routes/shared.$shareId.tsx +226 -0
  74. package/dist/templates/app/routes/team.$teamId.settings.tsx +57 -0
  75. package/dist/templates/app/routes/terms.tsx +173 -0
  76. package/dist/templates/app/routes/thread.$threadId.tsx +102 -0
  77. package/dist/templates/app/routes/verify-email.tsx +10 -0
  78. package/dist/templates/app/routes.ts +47 -0
  79. package/dist/templates/config/app.config.ts +216 -0
  80. package/dist/templates/docs/admin.md +257 -0
  81. package/dist/templates/docs/api-keys.md +403 -0
  82. package/dist/templates/docs/authentication.md +247 -0
  83. package/dist/templates/docs/configuration.md +1212 -0
  84. package/dist/templates/docs/custom-pages.md +466 -0
  85. package/dist/templates/docs/deployment.md +362 -0
  86. package/dist/templates/docs/development.md +411 -0
  87. package/dist/templates/docs/documents.md +293 -0
  88. package/dist/templates/docs/extensions.md +639 -0
  89. package/dist/templates/docs/index.md +139 -0
  90. package/dist/templates/docs/installation.md +286 -0
  91. package/dist/templates/docs/mcp.md +952 -0
  92. package/dist/templates/docs/native-tools.md +688 -0
  93. package/dist/templates/docs/queue.md +514 -0
  94. package/dist/templates/docs/scheduled-prompts.md +279 -0
  95. package/dist/templates/docs/settings.md +415 -0
  96. package/dist/templates/docs/slack.md +318 -0
  97. package/dist/templates/docs/styling.md +288 -0
  98. package/dist/templates/extensions/agents/.gitkeep +0 -0
  99. package/dist/templates/extensions/pages/.gitkeep +0 -0
  100. package/dist/templates/extensions/payment-plans/.gitkeep +0 -0
  101. package/dist/templates/index.html +16 -0
  102. package/dist/templates/infra-aws/.github/workflows/deploy.yml +95 -0
  103. package/dist/templates/infra-aws/README.md +207 -0
  104. package/dist/templates/infra-aws/bin/cdk.ts +18 -0
  105. package/dist/templates/infra-aws/cdk.json +43 -0
  106. package/dist/templates/infra-aws/config/deployment.ts +156 -0
  107. package/dist/templates/infra-aws/lib/chaaskit-stack.ts +419 -0
  108. package/dist/templates/infra-aws/package.json +27 -0
  109. package/dist/templates/infra-aws/scripts/build-app.sh +63 -0
  110. package/dist/templates/infra-aws/tsconfig.json +25 -0
  111. package/dist/templates/package.json +46 -0
  112. package/dist/templates/prisma/schema/base.prisma +584 -0
  113. package/dist/templates/prisma/schema/custom.prisma +24 -0
  114. package/dist/templates/prisma/schema.prisma +271 -0
  115. package/dist/templates/public/favicon.svg +4 -0
  116. package/dist/templates/public/logo.svg +4 -0
  117. package/dist/templates/react-router.config.ts +11 -0
  118. package/dist/templates/server.js +52 -0
  119. package/dist/templates/src/main.tsx +8 -0
  120. package/dist/templates/tsconfig.json +26 -0
  121. package/dist/templates/vite.config.ts +26 -0
  122. package/package.json +46 -0
@@ -0,0 +1,257 @@
1
+ # Admin Dashboard
2
+
3
+ The Admin Dashboard provides site-wide administration capabilities for managing users, teams, and viewing usage analytics.
4
+
5
+ ## Configuration
6
+
7
+ Site administrators are configured via the `admin` section in `config/app.config.ts`:
8
+
9
+ ```typescript
10
+ admin: {
11
+ emails: [
12
+ 'admin@example.com',
13
+ 'another-admin@example.com',
14
+ ],
15
+ }
16
+ ```
17
+
18
+ Users whose email addresses are in this list will see the "Admin" link in the sidebar and have access to all admin features.
19
+
20
+ ### Admin Access
21
+
22
+ Admin access is granted if the user meets either condition:
23
+ - Their email is listed in `config.admin.emails` (case-insensitive)
24
+ - They have `isAdmin: true` in the database (legacy support)
25
+
26
+ ## Admin Pages
27
+
28
+ ### Dashboard (`/admin`)
29
+
30
+ The main admin dashboard displays:
31
+
32
+ - **Stats Cards**: Total users, teams, threads, messages, and recent activity
33
+ - **Usage Chart**: Visual chart showing messages and token usage over time
34
+ - Period selector: 7, 30, or 90 days
35
+ - Metric selector: Messages, Input Tokens, Output Tokens, Total Tokens
36
+ - Summary row with total, daily average, and peak day
37
+ - **Plan Distribution**: Breakdown of users by subscription plan
38
+ - **Recent Feedback**: Latest user feedback on AI responses
39
+
40
+ Navigation links to Manage Users and Manage Teams (if teams enabled).
41
+
42
+ ### User Management (`/admin/users`)
43
+
44
+ Lists all users in the system with:
45
+
46
+ | Column | Description |
47
+ |--------|-------------|
48
+ | User | Name, email, avatar, OAuth provider |
49
+ | Plan | Dropdown to change user's subscription plan |
50
+ | Messages | Message count this month |
51
+ | Teams | Clickable pills showing team memberships with roles |
52
+ | Admin | Toggle button to grant/revoke database admin flag |
53
+ | Joined | Account creation date |
54
+
55
+ Features:
56
+ - **Search**: Filter users by email or name
57
+ - **Pagination**: Navigate through large user lists
58
+ - **Team Links**: Click a team pill to view that team's details
59
+
60
+ ### Team Management (`/admin/teams`)
61
+
62
+ Lists all teams in the system (only visible if teams are enabled):
63
+
64
+ | Column | Description |
65
+ |--------|-------------|
66
+ | Team | Team name and avatar |
67
+ | Members | Number of team members |
68
+ | Threads | Number of team threads |
69
+ | Created | Team creation date |
70
+
71
+ Features:
72
+ - **Search**: Filter teams by name
73
+ - **Pagination**: Navigate through large team lists
74
+ - **Click to View**: Click any team row to see team details
75
+
76
+ ### Team Details (`/admin/teams/:teamId`)
77
+
78
+ Displays detailed information about a specific team:
79
+
80
+ - **Stats**: Member count, thread count, creation date
81
+ - **Team Context**: The AI context configured for team conversations
82
+ - **Members List**: All team members with:
83
+ - Name and email (clickable to search in user management)
84
+ - Role badge (owner, admin, member, viewer)
85
+ - Join date
86
+
87
+ ## API Endpoints
88
+
89
+ All admin endpoints require authentication and admin access.
90
+
91
+ ### Stats & Analytics
92
+
93
+ | Method | Endpoint | Description |
94
+ |--------|----------|-------------|
95
+ | `GET` | `/api/admin/stats` | Dashboard statistics |
96
+ | `GET` | `/api/admin/usage` | Usage data over time |
97
+ | `GET` | `/api/admin/feedback` | Feedback statistics and recent items |
98
+
99
+ **Usage Query Parameters:**
100
+
101
+ | Parameter | Type | Default | Description |
102
+ |-----------|------|---------|-------------|
103
+ | `days` | number | 30 | Number of days of data (1-365) |
104
+
105
+ ### User Management
106
+
107
+ | Method | Endpoint | Description |
108
+ |--------|----------|-------------|
109
+ | `GET` | `/api/admin/users` | Paginated user list |
110
+ | `PATCH` | `/api/admin/users/:userId` | Update user (plan, isAdmin) |
111
+
112
+ **User List Query Parameters:**
113
+
114
+ | Parameter | Type | Default | Description |
115
+ |-----------|------|---------|-------------|
116
+ | `page` | number | 1 | Page number |
117
+ | `pageSize` | number | 20 | Users per page (max 100) |
118
+ | `search` | string | - | Filter by email or name |
119
+
120
+ **User Update Body:**
121
+
122
+ ```typescript
123
+ {
124
+ isAdmin?: boolean; // Grant or revoke admin status
125
+ plan?: string; // Change subscription plan
126
+ }
127
+ ```
128
+
129
+ ### Team Management
130
+
131
+ | Method | Endpoint | Description |
132
+ |--------|----------|-------------|
133
+ | `GET` | `/api/admin/teams` | Paginated team list |
134
+ | `GET` | `/api/admin/teams/:teamId` | Team details with members |
135
+
136
+ **Team List Query Parameters:**
137
+
138
+ | Parameter | Type | Default | Description |
139
+ |-----------|------|---------|-------------|
140
+ | `page` | number | 1 | Page number |
141
+ | `pageSize` | number | 20 | Teams per page (max 100) |
142
+ | `search` | string | - | Filter by team name |
143
+ | `includeArchived` | boolean | false | Include archived teams |
144
+
145
+ ## Response Types
146
+
147
+ ### AdminStats
148
+
149
+ ```typescript
150
+ interface AdminStats {
151
+ totalUsers: number;
152
+ totalTeams: number;
153
+ totalThreads: number;
154
+ totalMessages: number;
155
+ planDistribution: Record<string, number>;
156
+ newUsersLast30Days: number;
157
+ messagesLast30Days: number;
158
+ }
159
+ ```
160
+
161
+ ### UsageDataPoint
162
+
163
+ ```typescript
164
+ interface UsageDataPoint {
165
+ date: string; // "2024-01-15"
166
+ messages: number; // Count of messages
167
+ inputTokens: number; // Total input tokens
168
+ outputTokens: number;// Total output tokens
169
+ }
170
+ ```
171
+
172
+ ### AdminUser
173
+
174
+ ```typescript
175
+ interface AdminUser {
176
+ id: string;
177
+ email: string;
178
+ name?: string | null;
179
+ avatarUrl?: string | null;
180
+ isAdmin: boolean;
181
+ plan: string;
182
+ messagesThisMonth: number;
183
+ credits: number;
184
+ emailVerified: boolean;
185
+ oauthProvider?: string | null;
186
+ createdAt: Date;
187
+ threadCount: number;
188
+ teamCount: number;
189
+ teams: AdminUserTeam[];
190
+ }
191
+
192
+ interface AdminUserTeam {
193
+ id: string;
194
+ name: string;
195
+ role: string;
196
+ }
197
+ ```
198
+
199
+ ### AdminTeam / AdminTeamDetails
200
+
201
+ ```typescript
202
+ interface AdminTeam {
203
+ id: string;
204
+ name: string;
205
+ memberCount: number;
206
+ threadCount: number;
207
+ createdAt: Date;
208
+ archivedAt?: Date | null;
209
+ }
210
+
211
+ interface AdminTeamDetails extends AdminTeam {
212
+ context?: string | null;
213
+ members: AdminTeamMember[];
214
+ }
215
+
216
+ interface AdminTeamMember {
217
+ id: string;
218
+ email: string;
219
+ name?: string | null;
220
+ avatarUrl?: string | null;
221
+ role: string;
222
+ joinedAt: Date;
223
+ }
224
+ ```
225
+
226
+ ## Security Considerations
227
+
228
+ 1. **Config-based access**: Admin emails are defined in server configuration, not user-editable
229
+ 2. **Case-insensitive matching**: Email comparison is case-insensitive
230
+ 3. **Self-protection**: Users cannot remove their own admin status
231
+ 4. **Audit trail**: All user changes are logged with timestamps
232
+ 5. **No destructive actions**: Admin can modify users but cannot delete accounts (preserves data integrity)
233
+
234
+ ## Extending Admin Features
235
+
236
+ To add custom admin functionality:
237
+
238
+ 1. **Add API endpoints** in `packages/server/src/api/admin.ts`
239
+ 2. **Add types** in `packages/shared/src/types/admin.ts`
240
+ 3. **Create pages** in `packages/client/src/pages/Admin*.tsx`
241
+ 4. **Add routes** in `packages/client/src/App.tsx` wrapped with `<AdminRoute>`
242
+
243
+ Example adding a new admin page:
244
+
245
+ ```tsx
246
+ // App.tsx
247
+ <Route
248
+ path="/admin/custom"
249
+ element={
250
+ <AdminRoute>
251
+ <AdminCustomPage />
252
+ </AdminRoute>
253
+ }
254
+ />
255
+ ```
256
+
257
+ The `AdminRoute` component handles authentication and admin access verification.
@@ -0,0 +1,403 @@
1
+ # API Keys
2
+
3
+ API Keys allow users to access the API programmatically. This is useful for building integrations, CLI tools, or automated workflows.
4
+
5
+ ## Configuration
6
+
7
+ Enable API keys in `config/app.config.ts`:
8
+
9
+ ```typescript
10
+ api: {
11
+ enabled: true,
12
+ keyPrefix: 'myapp-', // Optional, default: "sk-"
13
+ allowedPlans: ['pro', 'enterprise'], // Optional: restrict to specific plans
14
+ allowedEndpoints: [ // Required: whitelist endpoints for API key access
15
+ '/api/chat',
16
+ '/api/threads',
17
+ '/api/threads/**',
18
+ ],
19
+ }
20
+ ```
21
+
22
+ ### Configuration Options
23
+
24
+ | Option | Type | Default | Description |
25
+ |--------|------|---------|-------------|
26
+ | `enabled` | boolean | `false` | Enable API key creation and management |
27
+ | `keyPrefix` | string | `"sk-"` | Prefix for generated API keys |
28
+ | `allowedPlans` | string[] | `undefined` | If set, only these plans can create keys |
29
+ | `allowedEndpoints` | string[] | `[]` | Endpoints accessible via API keys (required) |
30
+
31
+ ### Endpoint Patterns
32
+
33
+ The `allowedEndpoints` array supports pattern matching:
34
+
35
+ | Pattern | Matches | Does NOT Match |
36
+ |---------|---------|----------------|
37
+ | `/api/threads` | `/api/threads` (exact) | `/api/threads/123` |
38
+ | `/api/threads/*` | `/api/threads/123` | `/api/threads/123/messages` |
39
+ | `/api/threads/**` | `/api/threads/123`, `/api/threads/123/messages` | `/api/thread` |
40
+
41
+ **Pattern Types:**
42
+ - **Exact match**: `/api/chat` - matches only that exact path
43
+ - **Single segment wildcard (`*`)**: `/api/threads/*` - matches one path segment
44
+ - **Multi-segment wildcard (`**`)**: `/api/threads/**` - matches any depth
45
+
46
+ ### Example Configurations
47
+
48
+ **Minimal (chat only):**
49
+ ```typescript
50
+ api: {
51
+ enabled: true,
52
+ allowedEndpoints: ['/api/chat'],
53
+ }
54
+ ```
55
+
56
+ **Full access:**
57
+ ```typescript
58
+ api: {
59
+ enabled: true,
60
+ allowedEndpoints: [
61
+ '/api/chat',
62
+ '/api/threads',
63
+ '/api/threads/**',
64
+ '/api/search',
65
+ '/api/export/*',
66
+ ],
67
+ }
68
+ ```
69
+
70
+ **Restricted to pro users with custom prefix:**
71
+ ```typescript
72
+ api: {
73
+ enabled: true,
74
+ keyPrefix: 'myapp-',
75
+ allowedPlans: ['pro', 'enterprise'],
76
+ allowedEndpoints: [
77
+ '/api/chat',
78
+ '/api/threads',
79
+ '/api/threads/*',
80
+ ],
81
+ }
82
+ ```
83
+
84
+ ## User Interface
85
+
86
+ When API keys are enabled, users can manage their keys from the Settings modal.
87
+
88
+ ### Settings Modal
89
+
90
+ A link to "Manage API Keys" appears in the Settings modal for users who have access to the feature (based on `allowedPlans`).
91
+
92
+ ### API Keys Page
93
+
94
+ The dedicated `/api-keys` page allows users to:
95
+
96
+ 1. **View existing keys** - Shows key name, prefix, scope, creation date, last used, and expiration
97
+ 2. **Create new keys** - With options for:
98
+ - **Name**: A label for the key (e.g., "My CLI Tool")
99
+ - **Scope**: Personal or team (if teams are enabled)
100
+ - **Expiration**: Never, 30 days, 90 days, or 1 year
101
+ 3. **Revoke keys** - Immediately invalidates a key
102
+
103
+ ### Key Display
104
+
105
+ - Keys are shown with a masked prefix (e.g., `sk-a1b2c3...`)
106
+ - The full key is only displayed once at creation time
107
+ - Users must copy and securely store their key immediately
108
+
109
+ ## API Key Format
110
+
111
+ Generated keys follow this format:
112
+
113
+ ```
114
+ {prefix}{48 random hex characters}
115
+ ```
116
+
117
+ Examples:
118
+ - Default prefix: `sk-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4`
119
+ - Custom prefix: `myapp-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4`
120
+
121
+ ## Security
122
+
123
+ ### Key Storage
124
+
125
+ - Keys are hashed with bcrypt before storage (like passwords)
126
+ - The full key cannot be retrieved after creation
127
+ - Only the prefix is stored in plain text for display purposes
128
+
129
+ ### Key Validation
130
+
131
+ On each request:
132
+ 1. The key prefix is used to find candidate keys
133
+ 2. The full key is verified against the bcrypt hash
134
+ 3. Expiration date is checked
135
+ 4. For team-scoped keys, team membership is verified
136
+
137
+ ### Endpoint Restrictions
138
+
139
+ - API keys can only access endpoints listed in `allowedEndpoints`
140
+ - If no endpoints are configured, API keys cannot access any endpoint
141
+ - Attempts to access non-whitelisted endpoints return 403 Forbidden
142
+
143
+ ### Automatic Invalidation
144
+
145
+ Team-scoped keys are automatically invalidated if:
146
+ - The user is removed from the team
147
+ - The team is deleted
148
+
149
+ ## Team-Scoped Keys
150
+
151
+ When teams are enabled, users can create keys scoped to a specific team.
152
+
153
+ ### Behavior
154
+
155
+ | Key Scope | Behavior |
156
+ |-----------|----------|
157
+ | Personal | API requests operate as the user's personal account |
158
+ | Team | API requests use the team context (threads, projects, etc.) |
159
+
160
+ ### Creating Team-Scoped Keys
161
+
162
+ 1. In the "Create API Key" modal, select a team from the "Scope" dropdown
163
+ 2. The user must be a member of the team to create a key for it
164
+ 3. The key will have access to team resources only
165
+
166
+ ### Team Context
167
+
168
+ When using a team-scoped key:
169
+ - Thread listing returns team threads
170
+ - New threads are created in the team context
171
+ - Team context is injected into AI prompts
172
+ - The `teamId` in request bodies is overridden by the key's team scope
173
+
174
+ ## Using API Keys
175
+
176
+ ### Authentication
177
+
178
+ Include the API key in the `Authorization` header:
179
+
180
+ ```bash
181
+ curl -H "Authorization: Bearer sk-your-api-key-here" \
182
+ https://your-app.com/api/threads
183
+ ```
184
+
185
+ ### Available Endpoints
186
+
187
+ The following endpoints can be enabled for API key access:
188
+
189
+ | Endpoint | Methods | Description |
190
+ |----------|---------|-------------|
191
+ | `/api/threads` | GET, POST | List threads, create new thread |
192
+ | `/api/threads/*` | GET, PATCH, DELETE | Get, update, delete a specific thread |
193
+ | `/api/threads/**` | Various | Thread sub-routes (messages, etc.) |
194
+ | `/api/chat` | POST | Send messages, streaming responses |
195
+ | `/api/search` | GET | Search threads by query |
196
+ | `/api/export/*` | GET | Export a thread (JSON, Markdown) |
197
+ | `/api/templates` | GET, POST, PATCH, DELETE | Prompt templates |
198
+ | `/api/user/settings` | GET, PATCH | User settings |
199
+ | `/api/user/usage` | GET | Usage statistics |
200
+ | `/api/projects` | GET, POST | Project management |
201
+ | `/api/projects/*` | GET, PATCH, DELETE | Specific project operations |
202
+
203
+ ### Example: Create a Thread
204
+
205
+ ```bash
206
+ curl -X POST \
207
+ -H "Authorization: Bearer sk-your-api-key" \
208
+ -H "Content-Type: application/json" \
209
+ -d '{"title": "New Thread"}' \
210
+ https://your-app.com/api/threads
211
+ ```
212
+
213
+ ### Example: Send a Message
214
+
215
+ ```bash
216
+ curl -X POST \
217
+ -H "Authorization: Bearer sk-your-api-key" \
218
+ -H "Content-Type: application/json" \
219
+ -d '{"threadId": "thread-id", "content": "Hello!"}' \
220
+ https://your-app.com/api/chat
221
+ ```
222
+
223
+ ### Example: Stream Response (SSE)
224
+
225
+ ```bash
226
+ curl -N \
227
+ -H "Authorization: Bearer sk-your-api-key" \
228
+ -H "Content-Type: application/json" \
229
+ -d '{"threadId": "thread-id", "content": "Hello!"}' \
230
+ https://your-app.com/api/chat
231
+ ```
232
+
233
+ The response is a Server-Sent Events stream with events:
234
+ - `thread` - Thread metadata
235
+ - `start` - Message ID
236
+ - `delta` - Content chunks
237
+ - `done` - Completion signal
238
+
239
+ ## API Endpoints
240
+
241
+ ### List API Keys
242
+
243
+ ```http
244
+ GET /api/api-keys
245
+ Authorization: Bearer <jwt-token>
246
+ ```
247
+
248
+ Returns the user's API keys (masked):
249
+
250
+ ```json
251
+ {
252
+ "keys": [
253
+ {
254
+ "id": "key-id",
255
+ "name": "My CLI Tool",
256
+ "keyPrefix": "sk-a1b2c3",
257
+ "teamId": null,
258
+ "team": null,
259
+ "lastUsedAt": "2024-01-15T10:30:00Z",
260
+ "expiresAt": null,
261
+ "createdAt": "2024-01-01T00:00:00Z"
262
+ }
263
+ ]
264
+ }
265
+ ```
266
+
267
+ ### Create API Key
268
+
269
+ ```http
270
+ POST /api/api-keys
271
+ Authorization: Bearer <jwt-token>
272
+ Content-Type: application/json
273
+
274
+ {
275
+ "name": "My CLI Tool",
276
+ "teamId": "optional-team-id",
277
+ "expiresAt": "2024-12-31T23:59:59Z"
278
+ }
279
+ ```
280
+
281
+ Returns the full key (only shown once):
282
+
283
+ ```json
284
+ {
285
+ "key": {
286
+ "id": "key-id",
287
+ "name": "My CLI Tool",
288
+ "keyPrefix": "sk-a1b2c3",
289
+ "teamId": null,
290
+ "teamName": null,
291
+ "createdAt": "2024-01-01T00:00:00Z",
292
+ "expiresAt": null
293
+ },
294
+ "secret": "sk-a1b2c3d4e5f6..."
295
+ }
296
+ ```
297
+
298
+ ### Delete API Key
299
+
300
+ ```http
301
+ DELETE /api/api-keys/:keyId
302
+ Authorization: Bearer <jwt-token>
303
+ ```
304
+
305
+ ### Check Access
306
+
307
+ ```http
308
+ GET /api/api-keys/access
309
+ Authorization: Bearer <jwt-token>
310
+ ```
311
+
312
+ Returns whether the user can create API keys:
313
+
314
+ ```json
315
+ {
316
+ "canAccess": true
317
+ }
318
+ ```
319
+
320
+ ## Error Responses
321
+
322
+ ### 401 Unauthorized
323
+
324
+ ```json
325
+ {"error": "Invalid API key"}
326
+ {"error": "API key expired"}
327
+ {"error": "API key invalid - no longer a team member"}
328
+ ```
329
+
330
+ ### 403 Forbidden
331
+
332
+ ```json
333
+ {"error": "API key access is not enabled for any endpoints"}
334
+ {"error": "API key access is not allowed for this endpoint"}
335
+ {"error": "API access not available for your plan"}
336
+ {"error": "You are not a member of this team"}
337
+ ```
338
+
339
+ ## Database Schema
340
+
341
+ ```prisma
342
+ model ApiKey {
343
+ id String @id @default(cuid())
344
+ userId String
345
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
346
+ teamId String?
347
+ team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade)
348
+ name String
349
+ keyPrefix String // First chars for display
350
+ keyHash String // bcrypt hash
351
+ lastUsedAt DateTime?
352
+ expiresAt DateTime?
353
+ createdAt DateTime @default(now())
354
+
355
+ @@index([userId])
356
+ @@index([teamId])
357
+ @@index([keyPrefix])
358
+ }
359
+ ```
360
+
361
+ ## Best Practices
362
+
363
+ 1. **Restrict Endpoints**: Only whitelist endpoints that are actually needed
364
+ 2. **Use Plan Restrictions**: Limit API access to paid plans if appropriate
365
+ 3. **Set Expiration Dates**: Encourage or require expiration for security
366
+ 4. **Use Team Scoping**: For team-related integrations, use team-scoped keys
367
+ 5. **Rotate Keys Regularly**: Periodically revoke and recreate keys
368
+ 6. **Monitor Usage**: Check `lastUsedAt` to identify unused keys
369
+ 7. **Custom Prefix**: Use a custom prefix to identify your app's keys
370
+
371
+ ## Troubleshooting
372
+
373
+ ### "API key access is not enabled for any endpoints"
374
+
375
+ The `allowedEndpoints` array is empty. Add the endpoints you want to allow:
376
+
377
+ ```typescript
378
+ api: {
379
+ enabled: true,
380
+ allowedEndpoints: ['/api/chat', '/api/threads/**'],
381
+ }
382
+ ```
383
+
384
+ ### "API key access is not allowed for this endpoint"
385
+
386
+ The endpoint you're trying to access is not in the `allowedEndpoints` list. Add it:
387
+
388
+ ```typescript
389
+ allowedEndpoints: [
390
+ '/api/search', // Add missing endpoint
391
+ ]
392
+ ```
393
+
394
+ ### "API access not available for your plan"
395
+
396
+ The user's plan is not in the `allowedPlans` list. Either:
397
+ - Upgrade the user's plan
398
+ - Add their plan to `allowedPlans`
399
+ - Remove `allowedPlans` to allow all plans
400
+
401
+ ### Keys not working after team removal
402
+
403
+ Team-scoped keys are invalidated when the user is removed from the team. The user needs to create a new personal key or be re-added to the team.