-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathapi_spec.txt
More file actions
310 lines (260 loc) · 11 KB
/
api_spec.txt
File metadata and controls
310 lines (260 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
API SPEC - Zapnote Backend (local testing)
Overview
--------
- Base URL (local): http://localhost:<PORT> (default PORT from server startup)
- All JSON responses for success use:
{
"success": true,
"message": "<message>",
"data": <payload>
}
- Paginated success responses use:
{
"success": true,
"data": [ ... ],
"pagination": { page, limit, total, totalPages }
}
- Error responses:
{
"success": false,
"message": "<error message>",
...(errors?)
}
Notes about auth & test mode
----------------------------
- Most routes require Firebase authentication via middleware `authenticateFirebaseToken`.
Provide Authorization: Bearer <FIREBASE_ID_TOKEN> header.
- Several modules include a TEST MODE mock auth in router files for local testing (bypasses Firebase token):
- `workspace.route.ts` sets `req.userId = 'test-user-123'`
- `knowledge.route.ts` sets `req.userId = '11111111-1111-4111-8111-111111111111'`
Use these when testing locally in dev as they will bypass auth checks.
- Many endpoints also use workspace access checks and role requirements (OWNER, EDITOR, VIEWER) via middleware.
- Rate-limiting is applied to several endpoints; these are noted per-route.
General response shapes (interfaces reference)
----------------------------------------------
- UserProfile:
{ id, email, username, displayName, photoURL, createdAt }
- UserStats:
{ totalWorkspaces, ownedWorkspaces, totalKnowledgeItems, totalConversations }
- WorkspaceWithRole:
{ id, name, description, ownerId, createdAt, updatedAt, role, memberCount?, itemCount? }
- WorkspaceMemberWithUser:
{ id, role, joinedAt, user: { id, email, username, displayName, photoURL } }
- ConversationWithMessages:
{ id, title, userId, createdAt, updatedAt, messages: MessageWithSources[] }
- MessageWithSources:
{ id, role, content, sourceItemIds, createdAt, sources? }
- SearchResponse:
{ query, results: SearchResult[], totalResults }
- KnowledgeItemWithTags: see types (id, sourceUrl, userIntent, summary, contentType, status, tags[])
Routes
------
1) Health & test
-----------------
GET /health
- Auth: none
- Response: 200
{
success: true, (not using successResponse here, app returns custom object)
status: 'ok',
timestamp: 'ISO string',
environment: 'development' | 'production'
}
POST /api/test/seed
- Auth: none (DEV-only test route)
- Description: seeds a test user and workspace (IDs hard-coded in code)
- Response (200):
{
success: true,
message: 'Test data seeded successfully',
data: { user, workspace }
}
- Error: 500 with { success: false, error }
2) Users
--------
All routes under `/api/v1/users` require Firebase token (authenticateFirebaseToken) in production.
GET /api/v1/users/me
- Auth: Firebase
- Returns: UserProfile
- Example success:
{
"success": true,
"message": "User profile fetched successfully",
"data": { id, email, username, displayName, photoURL, createdAt }
}
PATCH /api/v1/users/me
- Auth: Firebase
- Rate limit: rateLimit('update-profile', 10, 3600)
- Body (JSON):
{
"username": "optional, string 3-50",
"displayName": "optional, string 1-100"
}
- Response: updated UserProfile
- Example success (200):
{ success: true, message: 'Profile updated successfully', data: { ... } }
- Validation errors: 400 with { success: false, message }
GET /api/v1/users/me/stats
- Auth: Firebase
- Returns: UserStats
- Example:
{ success: true, message: 'User stats fetched successfully', data: { totalWorkspaces: 3, ... } }
GET /api/v1/users/me/workspaces
- Auth: Firebase
- Returns: WorkspaceWithRole[]
DELETE /api/v1/users/me
- Auth: Firebase
- Rate limit: rateLimit('delete-account', 1, 3600)
- Response: { success: true, message: 'Account deleted successfully', data: null }
3) Workspaces
-------------
Base path: /api/v1/workspaces
Note: `workspace.route.ts` applies a mock auth middleware for local testing which sets `req.userId`.
POST /api/v1/workspaces
- Auth: (mocked in test) -> requires authenticated user
- Body:
{ "name": "string (1-100)", "description": "string <= 500 (optional)" }
- Response: 201
{ success: true, message: 'Workspace created successfully', data: WorkspaceWithRole }
- Validation error: 400
GET /api/v1/workspaces/:workspaceId
- Auth: mock or real
- Params: workspaceId UUID
- Response: WorkspaceWithRole (200)
PATCH /api/v1/workspaces/:workspaceId
- Auth: mock/real
- Middleware: requireRole('OWNER','EDITOR')
- Body: { name?: string, description?: string }
- Response: updated workspace
DELETE /api/v1/workspaces/:workspaceId
- Auth: mock/real
- Middleware: requireWorkspaceOwner
- Response: { success: true, message: 'Workspace deleted successfully', data: null }
GET /api/v1/workspaces/:workspaceId/members
- Auth: mock/real
- Response: WorkspaceMemberWithUser[]
POST /api/v1/workspaces/:workspaceId/members
- Auth: mock/real
- Middleware: requireRole('OWNER','EDITOR')
- Body: { "email": "valid email", "role": "OWNER|EDITOR|VIEWER" }
- Response: 201 { success: true, message: 'Member added successfully', data: member }
PATCH /api/v1/workspaces/:workspaceId/members/:memberId
- Auth: mock/real
- Middleware: requireWorkspaceOwner
- Body: { role: "OWNER|EDITOR|VIEWER" }
- Response: updated member
DELETE /api/v1/workspaces/:workspaceId/members/:memberId
- Auth: mock/real
- Middleware: requireWorkspaceOwner
- Response: { success: true, message: 'Member removed successfully', data: null }
POST /api/v1/workspaces/:workspaceId/leave
- Auth: mock/real
- Response: { success: true, message: 'Left workspace successfully', data: null }
4) Chat (Conversations & Messages)
----------------------------------
Base path: /api/v1/workspaces/:workspaceId/chat
Middleware: authenticateFirebaseToken, checkWorkspaceAccess
POST /
- Path: /api/v1/workspaces/:workspaceId/chat
- Rate limit: rateLimit('create-conversation', 50)
- Body: { "title": "optional string max 200" }
- Response: 201 { success: true, message: 'Conversation created successfully', data: Conversation }
GET /
- Path: /api/v1/workspaces/:workspaceId/chat
- Returns: conversations list (ConversationWithMessages[] or summary list)
GET /:conversationId
- Path params: conversationId (uuid)
- Query: ?limit=number (default 50)
- Response: ConversationWithMessages (includes messages up to limit)
POST /:conversationId/messages
- Rate limit: rateLimit('send-message', 100)
- Body: { "message": "string (1-2000)" }
- Response: { success: true, message: 'Message sent successfully', data: MessageWithSources }
DELETE /:conversationId
- Response: { success: true, message: 'Conversation deleted successfully', data: null }
5) Search
---------
Base path: /api/v1/workspaces/:workspaceId/search
Middleware: authenticateFirebaseToken, checkWorkspaceAccess
Rate limit: rateLimit('search', 100, 3600) on both endpoints
POST /semantic
- Body: { "query": "string 1-500", "limit": number (1-50, default 20), "filters": { contentType?: string, tags?: string[] } }
- Response: { success: true, message: 'Search completed successfully', data: SearchResponse }
(SearchResponse: { query, results: [ { id, title, summary, sourceUrl, contentType, similarity, tags, createdAt } ], totalResults })
POST /hybrid
- Same schema as /semantic
- Response: { success: true, message: 'Hybrid search completed successfully', data: SearchResponse }
6) Knowledge (Items)
--------------------
Base path: /api/v1/knowledge
Note: In local test mode, auth is mocked for knowledge routes (see `knowledge.route.ts`).
POST /:workspaceId
- Middleware: requireRole('OWNER','EDITOR')
- Rate limit: rateLimit('create-knowledge-item', 50, 3600)
- Body: { "sourceUrl": "valid url", "userIntent": "optional string <= 500" }
- Response: 201 { success: true, message: 'Knowledge item created, processing...', data: KnowledgeItem }
GET /:workspaceId
- Query params: page (int >=1 default1), limit (1-100 default20), type (ContentType optional), status (ProcessingStatus optional)
- Response (paginated): { success: true, data: [ KnowledgeItem... ], pagination: { page, limit, total, totalPages } }
GET /:workspaceId/:itemId
- Params: itemId UUID
- Response: { success: true, message: 'Knowledge item fetched successfully', data: KnowledgeItem }
PATCH /:workspaceId/:itemId
- Middleware: requireRole('OWNER','EDITOR')
- Body: { userIntent?: string }
- Response: updated item
DELETE /:workspaceId/:itemId
- Middleware: requireRole('OWNER','EDITOR')
- Response: { success: true, message: 'Knowledge item deleted successfully', data: null }
7) Whiteboard (Spaces & Elements)
---------------------------------
Base path: /api/v1/workspaces/:workspaceId/spaces
Middleware: authenticateFirebaseToken, checkWorkspaceAccess
Roles: requireRole('OWNER','EDITOR') for create/update/delete actions; delete space requires OWNER
POST /
- Create space
- Body: { name: "string 1-100" }
- Response: 201 { success: true, message: 'Space created successfully', data: { id, name, createdAt, updatedAt, ... } }
GET /
- Returns: list of spaces
GET /:spaceId
- Returns: space with elements
POST /:spaceId/elements
- Rate limit: rateLimit('create-element', 500)
- Body: { type: string, content: any }
- Response: 201 created element
- Emits socket event: 'element:created' to workspace and space
PATCH /:spaceId/elements/:elementId
- Body: { content: any }
- Response: updated element
- Emits socket event: 'element:updated' to workspace and space
PUT /:spaceId/elements/:elementId/move
- Rate limit: rateLimit('move-element', 1000)
- Body: { content: any } (contains position data)
- Response: { success: true, message: 'Element moved successfully', data: updatedElement }
- Emits socket event: 'element:moved' to workspace and space
DELETE /:spaceId/elements/:elementId
- Response: success
- Emits socket event: 'element:deleted' to workspace and space
DELETE /:spaceId (Owner only)
- Response: { success: true, message: 'Space deleted successfully', data: null }
- Emits socket event: 'space:deleted' to workspace
Validation & Error handling notes
---------------------------------
- Request validation uses `validateRequest` middleware with `zod` schemas. Invalid requests will be rejected with 400 status and an error message.
- Many endpoints check for required path params and throw 400 if missing (e.g., workspaceId, conversationId, itemId).
- Authentication failures will return 401/403 depending on middleware behavior.
- Rate limit middleware will return 429 when limits are exceeded.
Quick test checklist (local)
----------------------------
1. Start server (ensure env variables or use test mode paths)
2. Optionally call POST /api/test/seed to create test user/workspace used by mocked auth.
3. Test Workspaces endpoints (mock auth is enabled in router) - create, list, add members, etc.
4. Test Knowledge endpoints (mock auth enabled) - create item with valid sourceUrl, check paginated listing
5. Test Chat endpoints - create conversation, send messages, fetch conversation
6. Test Search endpoints - call /semantic and /hybrid with sample query
7. Test Whiteboard endpoints - create space, create element, update and delete
If you'd like, I can also:
- Generate an OpenAPI spec for these routes, or
- Add example curl commands for each endpoint into this file.
---