@hiai-gg/hiai-docs 0.0.1

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 (216) hide show
  1. package/.all-contributorsrc +18 -0
  2. package/.claude/settings.local.json +61 -0
  3. package/.dockerignore +113 -0
  4. package/.env.example +68 -0
  5. package/.github/FUNDING.yml +5 -0
  6. package/.github/ISSUE_TEMPLATE/bug_report.md +74 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.md +78 -0
  8. package/.github/dependabot.yml +136 -0
  9. package/.github/pull_request_template.md +96 -0
  10. package/.github/workflows/ci.yml +283 -0
  11. package/AGENTS.md +237 -0
  12. package/CODE_OF_CONDUCT.md +134 -0
  13. package/CONTRIBUTING.md +77 -0
  14. package/Caddyfile +50 -0
  15. package/Dockerfile.backend +60 -0
  16. package/LICENSE +21 -0
  17. package/README.md +284 -0
  18. package/RELEASE_CHECKLIST.md +34 -0
  19. package/SECURITY.md +60 -0
  20. package/backend/package.json +43 -0
  21. package/backend/src/__tests__/auth-helpers.test.ts +51 -0
  22. package/backend/src/__tests__/chunker.test.ts +65 -0
  23. package/backend/src/__tests__/config.test.ts +91 -0
  24. package/backend/src/__tests__/csrf.test.ts +91 -0
  25. package/backend/src/__tests__/embedding.test.ts +48 -0
  26. package/backend/src/__tests__/rate-limit.test.ts +46 -0
  27. package/backend/src/__tests__/routes.test.ts +38 -0
  28. package/backend/src/__tests__/schema.test.ts +31 -0
  29. package/backend/src/__tests__/validation.test.ts +556 -0
  30. package/backend/src/api/middleware/auth.ts +56 -0
  31. package/backend/src/api/middleware/csrf.ts +91 -0
  32. package/backend/src/api/middleware/rate-limit.ts +77 -0
  33. package/backend/src/api/middleware/webhook-verify.ts +22 -0
  34. package/backend/src/api/routes/attachments.ts +280 -0
  35. package/backend/src/api/routes/auth.ts +52 -0
  36. package/backend/src/api/routes/collaboration.ts +121 -0
  37. package/backend/src/api/routes/documents.ts +664 -0
  38. package/backend/src/api/routes/folders.ts +226 -0
  39. package/backend/src/api/routes/search.ts +354 -0
  40. package/backend/src/api/routes/share.ts +512 -0
  41. package/backend/src/api/routes/tags.ts +247 -0
  42. package/backend/src/api/routes/versions.ts +99 -0
  43. package/backend/src/api/routes/webhooks.ts +43 -0
  44. package/backend/src/embedding/chunker.ts +74 -0
  45. package/backend/src/embedding/index.ts +117 -0
  46. package/backend/src/embedding/providers/ollama.ts +63 -0
  47. package/backend/src/embedding/providers/openrouter.ts +71 -0
  48. package/backend/src/embedding/utils.ts +13 -0
  49. package/backend/src/embedding/worker.ts +89 -0
  50. package/backend/src/index.ts +147 -0
  51. package/backend/src/lib/auth-helpers.ts +27 -0
  52. package/backend/src/lib/auth.ts +35 -0
  53. package/backend/src/lib/config.ts +73 -0
  54. package/backend/src/lib/db.ts +7 -0
  55. package/backend/src/lib/embedding-queue.ts +12 -0
  56. package/backend/src/lib/logger.ts +18 -0
  57. package/backend/src/lib/markdown-to-doc.ts +45 -0
  58. package/backend/src/lib/minio.ts +46 -0
  59. package/backend/src/lib/redis.ts +19 -0
  60. package/backend/src/lib/yjs-provider.ts +182 -0
  61. package/backend/tests/integration/_harness.ts +754 -0
  62. package/backend/tests/integration/auth.test.ts +296 -0
  63. package/backend/tests/integration/routes.documents.test.ts +459 -0
  64. package/backend/tests/integration/routes.folders.test.ts +337 -0
  65. package/backend/tests/integration/routes.search.test.ts +322 -0
  66. package/backend/tests/integration/routes.share.test.ts +773 -0
  67. package/backend/tests/integration/routes.tags.test.ts +425 -0
  68. package/backend/tests/integration/routes.versions.test.ts +233 -0
  69. package/backend/tsconfig.json +18 -0
  70. package/docker-compose.yml +218 -0
  71. package/docs/API.md +328 -0
  72. package/docs/ARCHITECTURE.md +75 -0
  73. package/docs/DEPLOYMENT.md +113 -0
  74. package/docs/PRODUCTION_STATUS.md +61 -0
  75. package/docs/openapi.json +385 -0
  76. package/frontend/.svelte-kit.old/ambient.d.ts +230 -0
  77. package/frontend/.svelte-kit.old/env.d.ts +1 -0
  78. package/frontend/.svelte-kit.old/generated/client/app.js +46 -0
  79. package/frontend/.svelte-kit.old/generated/client/matchers.js +1 -0
  80. package/frontend/.svelte-kit.old/generated/client/nodes/0.js +3 -0
  81. package/frontend/.svelte-kit.old/generated/client/nodes/1.js +1 -0
  82. package/frontend/.svelte-kit.old/generated/client/nodes/10.js +3 -0
  83. package/frontend/.svelte-kit.old/generated/client/nodes/2.js +1 -0
  84. package/frontend/.svelte-kit.old/generated/client/nodes/3.js +1 -0
  85. package/frontend/.svelte-kit.old/generated/client/nodes/4.js +1 -0
  86. package/frontend/.svelte-kit.old/generated/client/nodes/5.js +3 -0
  87. package/frontend/.svelte-kit.old/generated/client/nodes/6.js +1 -0
  88. package/frontend/.svelte-kit.old/generated/client/nodes/7.js +3 -0
  89. package/frontend/.svelte-kit.old/generated/client/nodes/8.js +1 -0
  90. package/frontend/.svelte-kit.old/generated/client/nodes/9.js +3 -0
  91. package/frontend/.svelte-kit.old/generated/root.js +3 -0
  92. package/frontend/.svelte-kit.old/generated/root.svelte +80 -0
  93. package/frontend/.svelte-kit.old/generated/server/internal.js +55 -0
  94. package/frontend/.svelte-kit.old/non-ambient.d.ts +59 -0
  95. package/frontend/.svelte-kit.old/tsconfig.json +59 -0
  96. package/frontend/.svelte-kit.old/types/route_meta_data.json +40 -0
  97. package/frontend/.svelte-kit.old/types/src/routes/$types.d.ts +21 -0
  98. package/frontend/.svelte-kit.old/types/src/routes/(app)/$types.d.ts +30 -0
  99. package/frontend/.svelte-kit.old/types/src/routes/(app)/docs/[id]/$types.d.ts +27 -0
  100. package/frontend/.svelte-kit.old/types/src/routes/(app)/docs/[id]/proxy+page.ts +25 -0
  101. package/frontend/.svelte-kit.old/types/src/routes/api/[...path]/$types.d.ts +10 -0
  102. package/frontend/.svelte-kit.old/types/src/routes/folders/[id]/$types.d.ts +27 -0
  103. package/frontend/.svelte-kit.old/types/src/routes/folders/[id]/proxy+page.ts +15 -0
  104. package/frontend/.svelte-kit.old/types/src/routes/login/$types.d.ts +17 -0
  105. package/frontend/.svelte-kit.old/types/src/routes/register/$types.d.ts +17 -0
  106. package/frontend/.svelte-kit.old/types/src/routes/s/[token]/$types.d.ts +20 -0
  107. package/frontend/.svelte-kit.old/types/src/routes/s/[token]/proxy+page.ts +6 -0
  108. package/frontend/.svelte-kit.old/types/src/routes/search/$types.d.ts +19 -0
  109. package/frontend/.svelte-kit.old/types/src/routes/search/proxy+page.ts +26 -0
  110. package/frontend/.svelte-kit.old/types/src/routes/settings/$types.d.ts +17 -0
  111. package/frontend/Dockerfile +44 -0
  112. package/frontend/biome.json +40 -0
  113. package/frontend/components.json +18 -0
  114. package/frontend/messages/en.json +434 -0
  115. package/frontend/package.json +70 -0
  116. package/frontend/project.inlang/settings.json +12 -0
  117. package/frontend/src/app.css +6 -0
  118. package/frontend/src/app.d.ts +13 -0
  119. package/frontend/src/app.html +30 -0
  120. package/frontend/src/hooks.server.ts +10 -0
  121. package/frontend/src/hooks.ts +10 -0
  122. package/frontend/src/lib/api/attachments.ts +45 -0
  123. package/frontend/src/lib/api/client.test.ts +15 -0
  124. package/frontend/src/lib/api/client.ts +57 -0
  125. package/frontend/src/lib/api/documents.ts +83 -0
  126. package/frontend/src/lib/api/folders.ts +180 -0
  127. package/frontend/src/lib/api/search.test.ts +52 -0
  128. package/frontend/src/lib/api/search.ts +128 -0
  129. package/frontend/src/lib/api/settings.ts +95 -0
  130. package/frontend/src/lib/api/share.ts +71 -0
  131. package/frontend/src/lib/api/tags.test.ts +91 -0
  132. package/frontend/src/lib/api/tags.ts +87 -0
  133. package/frontend/src/lib/auth-client.ts +10 -0
  134. package/frontend/src/lib/collaboration.ts +63 -0
  135. package/frontend/src/lib/components/AttachmentUpload.svelte +110 -0
  136. package/frontend/src/lib/components/DatePicker.svelte +322 -0
  137. package/frontend/src/lib/components/DocumentCard.svelte +166 -0
  138. package/frontend/src/lib/components/EmptyState.svelte +49 -0
  139. package/frontend/src/lib/components/FolderCard.svelte +93 -0
  140. package/frontend/src/lib/components/ScrollToTop.svelte +72 -0
  141. package/frontend/src/lib/components/SearchBar.svelte +47 -0
  142. package/frontend/src/lib/components/SearchResult.svelte +115 -0
  143. package/frontend/src/lib/components/SettingsDialog.svelte +271 -0
  144. package/frontend/src/lib/components/ShareDialog.svelte +158 -0
  145. package/frontend/src/lib/components/ShareLink.svelte +98 -0
  146. package/frontend/src/lib/components/TagCreateDialog.svelte +284 -0
  147. package/frontend/src/lib/components/VersionDiff.svelte +55 -0
  148. package/frontend/src/lib/components/VersionHistory.svelte +96 -0
  149. package/frontend/src/lib/components/editor/DocumentTitle.svelte +87 -0
  150. package/frontend/src/lib/components/editor/EditorToolbar.svelte +1367 -0
  151. package/frontend/src/lib/components/editor/HiAiEditor.svelte +531 -0
  152. package/frontend/src/lib/components/editor/LinkDialog.svelte +134 -0
  153. package/frontend/src/lib/components/editor/MarkdownToggle.svelte +88 -0
  154. package/frontend/src/lib/components/editor/editorExtensions.ts +53 -0
  155. package/frontend/src/lib/components/editor/markdown.ts +38 -0
  156. package/frontend/src/lib/components/sidebar/FolderTree.svelte +731 -0
  157. package/frontend/src/lib/components/sidebar/RecentDocs.svelte +311 -0
  158. package/frontend/src/lib/components/sidebar/Sidebar.svelte +156 -0
  159. package/frontend/src/lib/components/sidebar/TagList.svelte +200 -0
  160. package/frontend/src/lib/components/ui/confirm-dialog/ConfirmDialog.svelte +76 -0
  161. package/frontend/src/lib/components/ui/confirm-dialog/index.ts +1 -0
  162. package/frontend/src/lib/stores/tag-store.svelte.ts +56 -0
  163. package/frontend/src/lib/stores/theme.svelte.ts +97 -0
  164. package/frontend/src/lib/svelte.d.ts +6 -0
  165. package/frontend/src/lib/types.ts +44 -0
  166. package/frontend/src/lib/utils/clipboard.ts +17 -0
  167. package/frontend/src/lib/utils/strip-markdown.ts +59 -0
  168. package/frontend/src/lib/utils.ts +33 -0
  169. package/frontend/src/routes/(app)/+layout.svelte +17 -0
  170. package/frontend/src/routes/(app)/+page.server.ts +10 -0
  171. package/frontend/src/routes/(app)/+page.svelte +303 -0
  172. package/frontend/src/routes/(app)/docs/[id]/+page.server.ts +10 -0
  173. package/frontend/src/routes/(app)/docs/[id]/+page.svelte +1108 -0
  174. package/frontend/src/routes/(app)/docs/[id]/+page.ts +24 -0
  175. package/frontend/src/routes/(app)/search/+page.svelte +593 -0
  176. package/frontend/src/routes/(app)/search/+page.ts +25 -0
  177. package/frontend/src/routes/+error.svelte +12 -0
  178. package/frontend/src/routes/+layout.svelte +18 -0
  179. package/frontend/src/routes/+layout.ts +2 -0
  180. package/frontend/src/routes/api/[...path]/+server.ts +111 -0
  181. package/frontend/src/routes/folders/[id]/+page.server.ts +10 -0
  182. package/frontend/src/routes/folders/[id]/+page.svelte +319 -0
  183. package/frontend/src/routes/folders/[id]/+page.ts +14 -0
  184. package/frontend/src/routes/login/+page.svelte +90 -0
  185. package/frontend/src/routes/register/+page.svelte +97 -0
  186. package/frontend/src/routes/s/[token]/+page.svelte +496 -0
  187. package/frontend/src/routes/s/[token]/+page.ts +5 -0
  188. package/frontend/src/routes/settings/+page.svelte +175 -0
  189. package/frontend/static/favicon.png +0 -0
  190. package/frontend/static/logo.png +0 -0
  191. package/frontend/svelte.config.js +15 -0
  192. package/frontend/tsconfig.json +15 -0
  193. package/frontend/vite.config.ts +25 -0
  194. package/init.sql +9 -0
  195. package/logo.png +0 -0
  196. package/package.json +39 -0
  197. package/package.public.json +39 -0
  198. package/packages/db/drizzle.config.ts +10 -0
  199. package/packages/db/package.json +30 -0
  200. package/packages/db/src/client.ts +9 -0
  201. package/packages/db/src/index.ts +2 -0
  202. package/packages/db/src/migrations/0000_nice_bedlam.sql +165 -0
  203. package/packages/db/src/migrations/0001_w2_3_test.sql +5 -0
  204. package/packages/db/src/migrations/0002_rename_content_json.sql +2 -0
  205. package/packages/db/src/migrations/meta/0000_snapshot.json +1331 -0
  206. package/packages/db/src/migrations/meta/0001_snapshot.json +1399 -0
  207. package/packages/db/src/migrations/meta/0002_snapshot.json +1399 -0
  208. package/packages/db/src/migrations/meta/_journal.json +27 -0
  209. package/packages/db/src/schema.ts +378 -0
  210. package/packages/db/tsconfig.json +17 -0
  211. package/scripts/export-openapi.ts +37 -0
  212. package/scripts/health-check.sh +75 -0
  213. package/scripts/migrate.sh +135 -0
  214. package/scripts/prework_backup.sh +25 -0
  215. package/scripts/release.sh +83 -0
  216. package/tsconfig.json +25 -0
@@ -0,0 +1,218 @@
1
+ # hiai-docs Docker Compose
2
+ # Copy .env.example to .env before running
3
+
4
+ services:
5
+ postgres:
6
+ image: pgvector/pgvector:pg18
7
+ restart: unless-stopped
8
+ ports:
9
+ - "${DB_PORT:-5433}:5432"
10
+ volumes:
11
+ - pgdata:/var/lib/postgresql
12
+ - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
13
+ environment:
14
+ POSTGRES_DB: ${DB_NAME:-hiai_docs}
15
+ POSTGRES_USER: ${DB_USER:-aiuser}
16
+ POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme}
17
+ healthcheck:
18
+ test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-aiuser} -d ${DB_NAME:-hiai_docs}"]
19
+ interval: 10s
20
+ timeout: 5s
21
+ retries: 5
22
+ networks:
23
+ - hiai-docs-net
24
+ deploy:
25
+ resources:
26
+ limits:
27
+ memory: 2G
28
+ cpus: "2"
29
+
30
+ redis:
31
+ image: redis:8-alpine
32
+ restart: unless-stopped
33
+ ports:
34
+ - "${REDIS_PORT:-6384}:6379"
35
+ volumes:
36
+ - redis_data:/data
37
+ healthcheck:
38
+ test: ["CMD", "redis-cli", "ping"]
39
+ interval: 10s
40
+ timeout: 5s
41
+ retries: 5
42
+ networks:
43
+ - hiai-docs-net
44
+ deploy:
45
+ resources:
46
+ limits:
47
+ memory: 256M
48
+ cpus: "0.5"
49
+
50
+ ollama:
51
+ image: ollama/ollama:0.13.4
52
+ restart: unless-stopped
53
+ # 11435 host: avoids conflict with primary Ollama on 11434
54
+ ports:
55
+ - "11435:11434"
56
+ volumes:
57
+ - ollama_data:/root/.ollama
58
+ healthcheck:
59
+ test: ["CMD", "ollama", "list"]
60
+ interval: 30s
61
+ timeout: 10s
62
+ retries: 3
63
+ start_period: 30s
64
+ networks:
65
+ - hiai-docs-net
66
+ deploy:
67
+ resources:
68
+ limits:
69
+ memory: 2G
70
+ cpus: "2"
71
+
72
+ minio:
73
+ image: minio/minio:RELEASE.2025-06-13T14-19-31Z
74
+ restart: unless-stopped
75
+ # 9021 host: avoids conflict with webs-minio (9001) and ai-shared-minio (9011)
76
+ ports:
77
+ - "9000:9000"
78
+ - "9021:9001"
79
+ volumes:
80
+ - minio_data:/data
81
+ command: server /data --console-address ":9001"
82
+ environment:
83
+ MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:-minioadmin}
84
+ MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:-minioadmin}
85
+ healthcheck:
86
+ test: ["CMD", "mc", "ready", "local"]
87
+ interval: 10s
88
+ timeout: 5s
89
+ retries: 5
90
+ networks:
91
+ - hiai-docs-net
92
+ deploy:
93
+ resources:
94
+ limits:
95
+ memory: 256M
96
+ cpus: "0.5"
97
+
98
+ api:
99
+ build:
100
+ context: .
101
+ dockerfile: Dockerfile.backend
102
+ network: host
103
+ restart: unless-stopped
104
+ ports:
105
+ - "${API_PORT:-50700}:50700"
106
+ depends_on:
107
+ postgres:
108
+ condition: service_healthy
109
+ redis:
110
+ condition: service_healthy
111
+ minio:
112
+ condition: service_healthy
113
+ ollama:
114
+ condition: service_healthy
115
+ healthcheck:
116
+ # $$ escapes compose interpolation so API_PORT is resolved at runtime
117
+ # inside the container (not baked in at compose-parse time).
118
+ test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:$${API_PORT}/api/health || exit 1"]
119
+ interval: 15s
120
+ timeout: 5s
121
+ retries: 3
122
+ start_period: 10s
123
+ environment:
124
+ DATABASE_URL: postgresql://${DB_USER:-aiuser}:${DB_PASSWORD:-changeme}@postgres:5432/${DB_NAME:-hiai_docs}
125
+ REDIS_URL: redis://redis:6379
126
+ MINIO_ENDPOINT: minio
127
+ MINIO_PORT: 9000
128
+ MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
129
+ MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
130
+ MINIO_BUCKET: ${MINIO_BUCKET:-hiai-docs}
131
+ MINIO_PUBLIC_ENDPOINT: localhost
132
+ MINIO_PUBLIC_PORT: 9000
133
+ BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}
134
+ BETTER_AUTH_URL: ${BETTER_AUTH_URL:-http://localhost:50700}
135
+ CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:50701,http://127.0.0.1:50701}
136
+ EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-ollama}
137
+ EMBEDDING_MODEL: ${EMBEDDING_MODEL:-nomic-embed-text}
138
+ EMBEDDING_OLLAMA_URL: http://ollama:11434
139
+ EMBEDDING_FALLBACK_PROVIDER: ${EMBEDDING_FALLBACK_PROVIDER:-openrouter}
140
+ EMBEDDING_FALLBACK_MODEL: ${EMBEDDING_FALLBACK_MODEL:-openai/text-embedding-3-small}
141
+ OPENROUTER_API_KEY: ${OPENROUTER_API_KEY}
142
+ API_PORT: ${API_PORT:-50700}
143
+ NODE_ENV: production
144
+ LOG_LEVEL: ${LOG_LEVEL:-info}
145
+ networks:
146
+ - hiai-docs-net
147
+ deploy:
148
+ resources:
149
+ limits:
150
+ memory: 512M
151
+ cpus: "1"
152
+
153
+ web:
154
+ build:
155
+ context: .
156
+ dockerfile: frontend/Dockerfile
157
+ network: host
158
+ restart: unless-stopped
159
+ ports:
160
+ - "${WEB_PORT:-50701}:50701"
161
+ depends_on:
162
+ api:
163
+ condition: service_healthy
164
+ healthcheck:
165
+ # $$ escapes compose interpolation so WEB_PORT is resolved at runtime
166
+ test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:$${WEB_PORT}/ || exit 1"]
167
+ interval: 15s
168
+ timeout: 5s
169
+ retries: 3
170
+ start_period: 10s
171
+ environment:
172
+ API_URL: http://api:${API_PORT:-50700}
173
+ PORT: ${WEB_PORT:-50701}
174
+ WEB_PORT: ${WEB_PORT:-50701}
175
+ networks:
176
+ - hiai-docs-net
177
+ deploy:
178
+ resources:
179
+ limits:
180
+ memory: 512M
181
+ cpus: "1"
182
+
183
+ caddy:
184
+ image: caddy:2-alpine
185
+ restart: unless-stopped
186
+ profiles:
187
+ - caddy
188
+ ports:
189
+ - "50708:80"
190
+ - "50709:443"
191
+ depends_on:
192
+ api:
193
+ condition: service_healthy
194
+ web:
195
+ condition: service_healthy
196
+ volumes:
197
+ - ./Caddyfile:/etc/caddy/Caddyfile:ro
198
+ - caddy_data:/data
199
+ - caddy_config:/config
200
+ networks:
201
+ - hiai-docs-net
202
+ deploy:
203
+ resources:
204
+ limits:
205
+ memory: 256M
206
+ cpus: "0.5"
207
+
208
+ networks:
209
+ hiai-docs-net:
210
+ driver: bridge
211
+
212
+ volumes:
213
+ pgdata:
214
+ redis_data:
215
+ ollama_data:
216
+ minio_data:
217
+ caddy_data:
218
+ caddy_config:
package/docs/API.md ADDED
@@ -0,0 +1,328 @@
1
+ # API Reference
2
+
3
+ Base URL: `http://localhost:50700`
4
+
5
+ All responses are JSON. Errors follow `{ error: string, details?: unknown }`.
6
+
7
+ ## Authentication
8
+
9
+ Most endpoints require a valid Better Auth session cookie. Public endpoints (health check, shared content access) are noted below.
10
+
11
+ ```bash
12
+ # Sign in (sets session cookie)
13
+ curl -X POST http://localhost:50700/api/auth/sign-in \
14
+ -H "Content-Type: application/json" \
15
+ -d '{"email": "user@example.com", "password": "secret"}'
16
+
17
+ # Sign up
18
+ curl -X POST http://localhost:50700/api/auth/sign-up \
19
+ -H "Content-Type: application/json" \
20
+ -d '{"name": "User", "email": "user@example.com", "password": "secret"}'
21
+
22
+ # Get current session
23
+ curl http://localhost:50700/api/auth/session
24
+
25
+ # Sign out
26
+ curl -X POST http://localhost:50700/api/auth/sign-out
27
+ ```
28
+
29
+ ## Health
30
+
31
+ ```
32
+ GET /api/health # → { status: "ok", timestamp: "..." }
33
+ ```
34
+
35
+ ## Documents
36
+
37
+ ```
38
+ GET /api/documents # List (paginated)
39
+ POST /api/documents # Create
40
+ GET /api/documents/:id # Get with tags
41
+ PATCH /api/documents/:id # Update (saves version)
42
+ DELETE /api/documents/:id # Delete (cascade)
43
+ ```
44
+
45
+ ### List documents
46
+
47
+ ```bash
48
+ curl "http://localhost:50700/api/documents?page=1&limit=20&folderId=UUID&tag=UUID"
49
+ ```
50
+
51
+ Response: `{ items: Document[], total: number, page: number, limit: number }`
52
+
53
+ ### Create document
54
+
55
+ ```bash
56
+ curl -X POST http://localhost:50700/api/documents \
57
+ -H "Content-Type: application/json" \
58
+ -d '{"title": "My Doc", "content": "Hello world", "folderId": "UUID"}'
59
+ ```
60
+
61
+ ### Update document
62
+
63
+ ```bash
64
+ curl -X PATCH http://localhost:50700/api/documents/UUID \
65
+ -H "Content-Type: application/json" \
66
+ -d '{"title": "Updated", "content": "New content"}'
67
+ ```
68
+
69
+ ### Duplicate document
70
+
71
+ ```bash
72
+ curl -X POST http://localhost:50700/api/documents/UUID/duplicate
73
+ ```
74
+
75
+ Creates a copy with "(Copy)" suffix, including version snapshot and embedding queue.
76
+
77
+ ### Export document
78
+
79
+ ```bash
80
+ curl http://localhost:50700/api/documents/UUID/export
81
+ ```
82
+
83
+ Returns the document content as a `.md` file download.
84
+
85
+ ### Import document
86
+
87
+ ```bash
88
+ # JSON import
89
+ curl -X POST http://localhost:50700/api/documents/import \
90
+ -H "Content-Type: application/json" \
91
+ -d '{"title": "Imported", "content": "# Hello"}'
92
+
93
+ # File upload
94
+ curl -X POST http://localhost:50700/api/documents/import \
95
+ -F "file=@doc.md" \
96
+ -F "folderId=UUID"
97
+ ```
98
+
99
+ Supports `.md`, `.txt`, `.markdown`, `.json` files (max 10 MB).
100
+
101
+ ### Document versions
102
+
103
+ ```
104
+ GET /api/documents/:id/versions # List version history
105
+ GET /api/documents/:id/versions/:vid # Get specific version
106
+ ```
107
+
108
+ Versions are auto-saved on every create/update. Each entry includes `id, content, contentJson, createdBy, createdAt`.
109
+
110
+ ## Document Attachments
111
+
112
+ ```
113
+ POST /api/documents/:id/attachments # Upload image attachment
114
+ GET /api/documents/:id/attachments # List attachments
115
+ ```
116
+
117
+ Image uploads are stored in MinIO with integrity verification. Max file size: 10 MB. Only `image/*` MIME types accepted.
118
+
119
+ ```bash
120
+ curl -X POST http://localhost:50700/api/documents/UUID/attachments \
121
+ -F "file=@screenshot.png"
122
+ ```
123
+
124
+ Response includes `id, filename, mimeType, size, url` (presigned S3 URL, 24h expiry).
125
+
126
+ ## Collaboration (WebSocket)
127
+
128
+ ```
129
+ WS /ws/collab/:documentId # Real-time collaborative editing
130
+ ```
131
+
132
+ Uses Yjs for CRDT-based conflict resolution. Authentication via query param `?token=<session_token_or_api_key>`.
133
+
134
+ ```bash
135
+ # Connect via wscat (install: npm install -g wscat)
136
+ wscat -c "ws://localhost:50700/ws/collab/DOCUMENT_ID?token=API_KEY"
137
+ ```
138
+
139
+ Messages are JSON: `{ type: "sync" | "update" | "ping", update?: "base64", state?: "base64", clientId: number }`.
140
+
141
+ ## Webhooks
142
+
143
+ ```
144
+ POST /api/webhooks/minio # MinIO bucket event webhook
145
+ ```
146
+
147
+ Verifies `x-minio-signature` header against `WEBHOOK_SECRET`. Currently handles `s3:ObjectRemoved:Delete` events to sync attachment DB records.
148
+
149
+ ## Folders
150
+
151
+ ```
152
+ GET /api/folders # List (tree, root-level unless ?parentId=UUID)
153
+ GET /api/folders/:id # Get single folder
154
+ POST /api/folders # Create
155
+ PATCH /api/folders/:id # Rename/move
156
+ DELETE /api/folders/:id # Delete
157
+ ```
158
+
159
+ ### List folders
160
+
161
+ ```bash
162
+ curl "http://localhost:50700/api/folders?parentId=UUID"
163
+ ```
164
+
165
+ Returns root folders when `parentId` is omitted.
166
+
167
+ ### Create folder
168
+
169
+ ```bash
170
+ curl -X POST http://localhost:50700/api/folders \
171
+ -H "Content-Type: application/json" \
172
+ -d '{"name": "My Folder", "parentId": "UUID"}'
173
+ ```
174
+
175
+ ## Search
176
+
177
+ ```
178
+ GET /api/search # Full-text + semantic search (PUBLIC)
179
+ GET /api/search/suggest # Quick title suggestions (PUBLIC)
180
+ ```
181
+
182
+ ### Full search
183
+
184
+ ```bash
185
+ curl "http://localhost:50700/api/search?q=query&folder=UUID&tags=tag1,tag2&dateFrom=2026-01-01&dateTo=2026-12-31&sort=relevance&page=1&limit=20"
186
+ ```
187
+
188
+ Query parameters:
189
+
190
+ | Param | Type | Description |
191
+ |-------|------|-------------|
192
+ | `q` | string | Search query |
193
+ | `folder` | UUID | Filter by folder |
194
+ | `tags` | string | Comma-separated tag names (ANY match) |
195
+ | `dateFrom` | ISO date | Filter docs created after |
196
+ | `dateTo` | ISO date | Filter docs created before |
197
+ | `sort` | enum | `relevance`, `date_desc`, `date_asc`, `name_asc`, `name_desc` |
198
+ | `page` | int | Page number (default 1) |
199
+ | `limit` | int | Per page (default 20, max 100) |
200
+
201
+ Response: `{ items: SearchResult[], total, page, limit }` where each item has `id, title, snippet, score, folderId, createdAt, updatedAt`.
202
+
203
+ ### Quick suggest
204
+
205
+ ```bash
206
+ curl "http://localhost:50700/api/search/suggest?q=deploy"
207
+ ```
208
+
209
+ Returns top 5 title matches with similarity scores.
210
+
211
+ ## Share Links
212
+
213
+ ```
214
+ GET /api/share # List user's share links
215
+ POST /api/share # Create link
216
+ GET /api/share/:token # Access shared content (PUBLIC)
217
+ DELETE /api/share/:id # Revoke link
218
+ POST /api/share/:id/guests # Add guest email
219
+ DELETE /api/share/:id/guests/:email # Remove guest access
220
+ ```
221
+
222
+ ### Create share link
223
+
224
+ ```bash
225
+ curl -X POST http://localhost:50700/api/share \
226
+ -H "Content-Type: application/json" \
227
+ -d '{"documentId": "UUID", "password": "optional", "expiresIn": "7d"}'
228
+ ```
229
+
230
+ Expires options: `1h`, `1d`, `7d`, `30d`, `never`.
231
+
232
+ ### Access shared content
233
+
234
+ ```bash
235
+ # Public — no auth required. Rate limited: 10 req/min per IP.
236
+ curl http://localhost:50700/api/share/TOKEN
237
+
238
+ # With password
239
+ curl http://localhost:50700/api/share/TOKEN \
240
+ -H "x-share-password: secret"
241
+ ```
242
+
243
+ Returns 410 Gone if expired, 401 if password required/invalid.
244
+
245
+ ## Tags
246
+
247
+ ```
248
+ GET /api/tags # List tags with counts
249
+ POST /api/tags # Create tag
250
+ PATCH /api/tags/:id # Update tag
251
+ DELETE /api/tags/:id # Delete tag
252
+ POST /api/documents/:docId/tags # Tag document
253
+ DELETE /api/documents/:docId/tags/:tagId # Untag document
254
+ ```
255
+
256
+ ## Agent Integration
257
+
258
+ hiai-docs is designed for AI agent integration via its REST API. Use API key authentication for programmatic access.
259
+
260
+ ### API Key Auth
261
+
262
+ Set `HIAI_DOCS_API_KEY` in your `.env` file. All API requests use Bearer token:
263
+
264
+ ```bash
265
+ curl -H "Authorization: Bearer $HIAI_DOCS_API_KEY" \
266
+ http://localhost:50700/api/documents
267
+ ```
268
+
269
+ ### Semantic Search (RAG)
270
+
271
+ ```bash
272
+ # Search documents by meaning (hybrid full-text + vector)
273
+ curl -H "Authorization: Bearer $HIAI_DOCS_API_KEY" \
274
+ "http://localhost:50700/api/search?q=how+to+deploy+docker"
275
+
276
+ # Response includes relevance scores:
277
+ # { items: [{ id, title, content, score, rank }] }
278
+ ```
279
+
280
+ ### Document CRUD for Agents
281
+
282
+ ```bash
283
+ # Create document
284
+ curl -X POST http://localhost:50700/api/documents \
285
+ -H "Authorization: Bearer $HIAI_DOCS_API_KEY" \
286
+ -H "Content-Type: application/json" \
287
+ -d '{"title": "Agent Note", "content": "Important finding..."}'
288
+
289
+ # Read document
290
+ curl -H "Authorization: Bearer $HIAI_DOCS_API_KEY" \
291
+ http://localhost:50700/api/documents/UUID
292
+
293
+ # Update document
294
+ curl -X PATCH http://localhost:50700/api/documents/UUID \
295
+ -H "Authorization: Bearer $HIAI_DOCS_API_KEY" \
296
+ -H "Content-Type: application/json" \
297
+ -d '{"content": "Updated with new findings..."}'
298
+ ```
299
+
300
+ ### Mastra Integration
301
+
302
+ ```typescript
303
+ import { Mastra } from "@mastra/core";
304
+
305
+ const docsTool = {
306
+ name: "search_knowledge",
307
+ description: "Search the knowledge base for relevant documents",
308
+ execute: async ({ query }) => {
309
+ const res = await fetch(
310
+ `http://localhost:50700/api/search?q=${encodeURIComponent(query)}`,
311
+ { headers: { Authorization: `Bearer ${process.env.HIAI_DOCS_API_KEY}` } }
312
+ );
313
+ return res.json();
314
+ },
315
+ };
316
+ ```
317
+
318
+ ## Error Codes
319
+
320
+ | Code | Meaning |
321
+ |------|---------|
322
+ | 400 | Validation error (check `details`) |
323
+ | 401 | Not authenticated |
324
+ | 403 | Forbidden (not owner) |
325
+ | 404 | Resource not found |
326
+ | 410 | Share link expired |
327
+ | 429 | Rate limited (check `retry-after` header) |
328
+ | 500 | Internal server error |
@@ -0,0 +1,75 @@
1
+ # Architecture
2
+
3
+ ## Monorepo Structure
4
+
5
+ ```
6
+ hiai-docs/
7
+ ├── backend/ # Elysia REST API (Bun runtime)
8
+ │ └── src/
9
+ │ ├── api/routes/ # Route handlers (documents, folders, search, share, tags, auth)
10
+ │ ├── api/middleware/# Auth middleware
11
+ │ ├── embedding/ # Embedding pipeline (chunker, providers, queue)
12
+ │ └── lib/ # Shared utilities (db, redis, config, logger, minio)
13
+ ├── frontend/ # SvelteKit 2 + Svelte 5 + Tailwind CSS v4
14
+ │ └── src/
15
+ │ ├── routes/ # Pages (+page.svelte per route)
16
+ │ └── lib/
17
+ │ ├── components/ # UI components (sidebar, editor, cards)
18
+ │ ├── components/ui/ # shadcn-svelte primitives
19
+ │ └── api/ # API client functions
20
+ ├── packages/db/ # Drizzle ORM schema + migrations (shared)
21
+ │ └── src/
22
+ │ ├── schema.ts # Table definitions + relations
23
+ │ └── client.ts # Database client
24
+ └── docker-compose.yml # Full stack deployment
25
+ ```
26
+
27
+ ## Tech Stack
28
+
29
+ | Layer | Technology |
30
+ |-------|-----------|
31
+ | Runtime | Bun 1.3.14+ |
32
+ | Backend | Elysia 1.4.28+ |
33
+ | ORM | Drizzle 0.45.2+ |
34
+ | Database | PostgreSQL 18 + pgvector |
35
+ | Cache | Redis 8.6+ |
36
+ | Auth | Better Auth |
37
+ | Frontend | SvelteKit 2.60+ / Svelte 5.55+ |
38
+ | UI | shadcn-svelte (new-york) + Tailwind v4 |
39
+ | Editor | TipTap + svelte-tiptap |
40
+ | Embeddings | Ollama (configurable) |
41
+ | Storage | MinIO (S3-compatible) |
42
+
43
+ ## Data Flow
44
+
45
+ ```
46
+ User → SvelteKit Frontend → REST API (Elysia) → PostgreSQL
47
+ → Redis (queue/cache)
48
+ → MinIO (attachments)
49
+ → Ollama (embeddings)
50
+ ```
51
+
52
+ 1. User creates/edits document in TipTap editor
53
+ 2. Frontend PATCHes document via API
54
+ 3. API saves content + version to PostgreSQL
55
+ 4. API enqueues embedding job to Redis
56
+ 5. Background worker fetches document, chunks text, generates vector via Ollama
57
+ 6. Worker stores vector in pgvector column
58
+
59
+ Search queries run hybrid: full-text (tsvector) + semantic (pgvector cosine).
60
+
61
+ ## Module Boundaries
62
+
63
+ - `api/` imports from `lib/` and `embedding/` — never the reverse
64
+ - `embedding/` imports from `lib/` only
65
+ - `lib/` has no imports from `api/` or `embedding/`
66
+ - `packages/db/` is imported by both backend and has no dependencies on either
67
+
68
+ ## Security Model
69
+
70
+ - **Data isolation**: every query filters by `ownerId` (user-scoped)
71
+ - **Auth**: Better Auth session cookies (7-day expiry)
72
+ - **Sharing**: token-based links with optional password + expiry
73
+ - **Rate limiting**: 10 req/min per IP on public share endpoints
74
+ - **Validation**: Zod schemas on all API inputs
75
+ - **No secrets in code**: all config via environment variables