@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.
- package/.all-contributorsrc +18 -0
- package/.claude/settings.local.json +61 -0
- package/.dockerignore +113 -0
- package/.env.example +68 -0
- package/.github/FUNDING.yml +5 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +74 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +78 -0
- package/.github/dependabot.yml +136 -0
- package/.github/pull_request_template.md +96 -0
- package/.github/workflows/ci.yml +283 -0
- package/AGENTS.md +237 -0
- package/CODE_OF_CONDUCT.md +134 -0
- package/CONTRIBUTING.md +77 -0
- package/Caddyfile +50 -0
- package/Dockerfile.backend +60 -0
- package/LICENSE +21 -0
- package/README.md +284 -0
- package/RELEASE_CHECKLIST.md +34 -0
- package/SECURITY.md +60 -0
- package/backend/package.json +43 -0
- package/backend/src/__tests__/auth-helpers.test.ts +51 -0
- package/backend/src/__tests__/chunker.test.ts +65 -0
- package/backend/src/__tests__/config.test.ts +91 -0
- package/backend/src/__tests__/csrf.test.ts +91 -0
- package/backend/src/__tests__/embedding.test.ts +48 -0
- package/backend/src/__tests__/rate-limit.test.ts +46 -0
- package/backend/src/__tests__/routes.test.ts +38 -0
- package/backend/src/__tests__/schema.test.ts +31 -0
- package/backend/src/__tests__/validation.test.ts +556 -0
- package/backend/src/api/middleware/auth.ts +56 -0
- package/backend/src/api/middleware/csrf.ts +91 -0
- package/backend/src/api/middleware/rate-limit.ts +77 -0
- package/backend/src/api/middleware/webhook-verify.ts +22 -0
- package/backend/src/api/routes/attachments.ts +280 -0
- package/backend/src/api/routes/auth.ts +52 -0
- package/backend/src/api/routes/collaboration.ts +121 -0
- package/backend/src/api/routes/documents.ts +664 -0
- package/backend/src/api/routes/folders.ts +226 -0
- package/backend/src/api/routes/search.ts +354 -0
- package/backend/src/api/routes/share.ts +512 -0
- package/backend/src/api/routes/tags.ts +247 -0
- package/backend/src/api/routes/versions.ts +99 -0
- package/backend/src/api/routes/webhooks.ts +43 -0
- package/backend/src/embedding/chunker.ts +74 -0
- package/backend/src/embedding/index.ts +117 -0
- package/backend/src/embedding/providers/ollama.ts +63 -0
- package/backend/src/embedding/providers/openrouter.ts +71 -0
- package/backend/src/embedding/utils.ts +13 -0
- package/backend/src/embedding/worker.ts +89 -0
- package/backend/src/index.ts +147 -0
- package/backend/src/lib/auth-helpers.ts +27 -0
- package/backend/src/lib/auth.ts +35 -0
- package/backend/src/lib/config.ts +73 -0
- package/backend/src/lib/db.ts +7 -0
- package/backend/src/lib/embedding-queue.ts +12 -0
- package/backend/src/lib/logger.ts +18 -0
- package/backend/src/lib/markdown-to-doc.ts +45 -0
- package/backend/src/lib/minio.ts +46 -0
- package/backend/src/lib/redis.ts +19 -0
- package/backend/src/lib/yjs-provider.ts +182 -0
- package/backend/tests/integration/_harness.ts +754 -0
- package/backend/tests/integration/auth.test.ts +296 -0
- package/backend/tests/integration/routes.documents.test.ts +459 -0
- package/backend/tests/integration/routes.folders.test.ts +337 -0
- package/backend/tests/integration/routes.search.test.ts +322 -0
- package/backend/tests/integration/routes.share.test.ts +773 -0
- package/backend/tests/integration/routes.tags.test.ts +425 -0
- package/backend/tests/integration/routes.versions.test.ts +233 -0
- package/backend/tsconfig.json +18 -0
- package/docker-compose.yml +218 -0
- package/docs/API.md +328 -0
- package/docs/ARCHITECTURE.md +75 -0
- package/docs/DEPLOYMENT.md +113 -0
- package/docs/PRODUCTION_STATUS.md +61 -0
- package/docs/openapi.json +385 -0
- package/frontend/.svelte-kit.old/ambient.d.ts +230 -0
- package/frontend/.svelte-kit.old/env.d.ts +1 -0
- package/frontend/.svelte-kit.old/generated/client/app.js +46 -0
- package/frontend/.svelte-kit.old/generated/client/matchers.js +1 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/0.js +3 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/1.js +1 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/10.js +3 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/2.js +1 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/3.js +1 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/4.js +1 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/5.js +3 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/6.js +1 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/7.js +3 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/8.js +1 -0
- package/frontend/.svelte-kit.old/generated/client/nodes/9.js +3 -0
- package/frontend/.svelte-kit.old/generated/root.js +3 -0
- package/frontend/.svelte-kit.old/generated/root.svelte +80 -0
- package/frontend/.svelte-kit.old/generated/server/internal.js +55 -0
- package/frontend/.svelte-kit.old/non-ambient.d.ts +59 -0
- package/frontend/.svelte-kit.old/tsconfig.json +59 -0
- package/frontend/.svelte-kit.old/types/route_meta_data.json +40 -0
- package/frontend/.svelte-kit.old/types/src/routes/$types.d.ts +21 -0
- package/frontend/.svelte-kit.old/types/src/routes/(app)/$types.d.ts +30 -0
- package/frontend/.svelte-kit.old/types/src/routes/(app)/docs/[id]/$types.d.ts +27 -0
- package/frontend/.svelte-kit.old/types/src/routes/(app)/docs/[id]/proxy+page.ts +25 -0
- package/frontend/.svelte-kit.old/types/src/routes/api/[...path]/$types.d.ts +10 -0
- package/frontend/.svelte-kit.old/types/src/routes/folders/[id]/$types.d.ts +27 -0
- package/frontend/.svelte-kit.old/types/src/routes/folders/[id]/proxy+page.ts +15 -0
- package/frontend/.svelte-kit.old/types/src/routes/login/$types.d.ts +17 -0
- package/frontend/.svelte-kit.old/types/src/routes/register/$types.d.ts +17 -0
- package/frontend/.svelte-kit.old/types/src/routes/s/[token]/$types.d.ts +20 -0
- package/frontend/.svelte-kit.old/types/src/routes/s/[token]/proxy+page.ts +6 -0
- package/frontend/.svelte-kit.old/types/src/routes/search/$types.d.ts +19 -0
- package/frontend/.svelte-kit.old/types/src/routes/search/proxy+page.ts +26 -0
- package/frontend/.svelte-kit.old/types/src/routes/settings/$types.d.ts +17 -0
- package/frontend/Dockerfile +44 -0
- package/frontend/biome.json +40 -0
- package/frontend/components.json +18 -0
- package/frontend/messages/en.json +434 -0
- package/frontend/package.json +70 -0
- package/frontend/project.inlang/settings.json +12 -0
- package/frontend/src/app.css +6 -0
- package/frontend/src/app.d.ts +13 -0
- package/frontend/src/app.html +30 -0
- package/frontend/src/hooks.server.ts +10 -0
- package/frontend/src/hooks.ts +10 -0
- package/frontend/src/lib/api/attachments.ts +45 -0
- package/frontend/src/lib/api/client.test.ts +15 -0
- package/frontend/src/lib/api/client.ts +57 -0
- package/frontend/src/lib/api/documents.ts +83 -0
- package/frontend/src/lib/api/folders.ts +180 -0
- package/frontend/src/lib/api/search.test.ts +52 -0
- package/frontend/src/lib/api/search.ts +128 -0
- package/frontend/src/lib/api/settings.ts +95 -0
- package/frontend/src/lib/api/share.ts +71 -0
- package/frontend/src/lib/api/tags.test.ts +91 -0
- package/frontend/src/lib/api/tags.ts +87 -0
- package/frontend/src/lib/auth-client.ts +10 -0
- package/frontend/src/lib/collaboration.ts +63 -0
- package/frontend/src/lib/components/AttachmentUpload.svelte +110 -0
- package/frontend/src/lib/components/DatePicker.svelte +322 -0
- package/frontend/src/lib/components/DocumentCard.svelte +166 -0
- package/frontend/src/lib/components/EmptyState.svelte +49 -0
- package/frontend/src/lib/components/FolderCard.svelte +93 -0
- package/frontend/src/lib/components/ScrollToTop.svelte +72 -0
- package/frontend/src/lib/components/SearchBar.svelte +47 -0
- package/frontend/src/lib/components/SearchResult.svelte +115 -0
- package/frontend/src/lib/components/SettingsDialog.svelte +271 -0
- package/frontend/src/lib/components/ShareDialog.svelte +158 -0
- package/frontend/src/lib/components/ShareLink.svelte +98 -0
- package/frontend/src/lib/components/TagCreateDialog.svelte +284 -0
- package/frontend/src/lib/components/VersionDiff.svelte +55 -0
- package/frontend/src/lib/components/VersionHistory.svelte +96 -0
- package/frontend/src/lib/components/editor/DocumentTitle.svelte +87 -0
- package/frontend/src/lib/components/editor/EditorToolbar.svelte +1367 -0
- package/frontend/src/lib/components/editor/HiAiEditor.svelte +531 -0
- package/frontend/src/lib/components/editor/LinkDialog.svelte +134 -0
- package/frontend/src/lib/components/editor/MarkdownToggle.svelte +88 -0
- package/frontend/src/lib/components/editor/editorExtensions.ts +53 -0
- package/frontend/src/lib/components/editor/markdown.ts +38 -0
- package/frontend/src/lib/components/sidebar/FolderTree.svelte +731 -0
- package/frontend/src/lib/components/sidebar/RecentDocs.svelte +311 -0
- package/frontend/src/lib/components/sidebar/Sidebar.svelte +156 -0
- package/frontend/src/lib/components/sidebar/TagList.svelte +200 -0
- package/frontend/src/lib/components/ui/confirm-dialog/ConfirmDialog.svelte +76 -0
- package/frontend/src/lib/components/ui/confirm-dialog/index.ts +1 -0
- package/frontend/src/lib/stores/tag-store.svelte.ts +56 -0
- package/frontend/src/lib/stores/theme.svelte.ts +97 -0
- package/frontend/src/lib/svelte.d.ts +6 -0
- package/frontend/src/lib/types.ts +44 -0
- package/frontend/src/lib/utils/clipboard.ts +17 -0
- package/frontend/src/lib/utils/strip-markdown.ts +59 -0
- package/frontend/src/lib/utils.ts +33 -0
- package/frontend/src/routes/(app)/+layout.svelte +17 -0
- package/frontend/src/routes/(app)/+page.server.ts +10 -0
- package/frontend/src/routes/(app)/+page.svelte +303 -0
- package/frontend/src/routes/(app)/docs/[id]/+page.server.ts +10 -0
- package/frontend/src/routes/(app)/docs/[id]/+page.svelte +1108 -0
- package/frontend/src/routes/(app)/docs/[id]/+page.ts +24 -0
- package/frontend/src/routes/(app)/search/+page.svelte +593 -0
- package/frontend/src/routes/(app)/search/+page.ts +25 -0
- package/frontend/src/routes/+error.svelte +12 -0
- package/frontend/src/routes/+layout.svelte +18 -0
- package/frontend/src/routes/+layout.ts +2 -0
- package/frontend/src/routes/api/[...path]/+server.ts +111 -0
- package/frontend/src/routes/folders/[id]/+page.server.ts +10 -0
- package/frontend/src/routes/folders/[id]/+page.svelte +319 -0
- package/frontend/src/routes/folders/[id]/+page.ts +14 -0
- package/frontend/src/routes/login/+page.svelte +90 -0
- package/frontend/src/routes/register/+page.svelte +97 -0
- package/frontend/src/routes/s/[token]/+page.svelte +496 -0
- package/frontend/src/routes/s/[token]/+page.ts +5 -0
- package/frontend/src/routes/settings/+page.svelte +175 -0
- package/frontend/static/favicon.png +0 -0
- package/frontend/static/logo.png +0 -0
- package/frontend/svelte.config.js +15 -0
- package/frontend/tsconfig.json +15 -0
- package/frontend/vite.config.ts +25 -0
- package/init.sql +9 -0
- package/logo.png +0 -0
- package/package.json +39 -0
- package/package.public.json +39 -0
- package/packages/db/drizzle.config.ts +10 -0
- package/packages/db/package.json +30 -0
- package/packages/db/src/client.ts +9 -0
- package/packages/db/src/index.ts +2 -0
- package/packages/db/src/migrations/0000_nice_bedlam.sql +165 -0
- package/packages/db/src/migrations/0001_w2_3_test.sql +5 -0
- package/packages/db/src/migrations/0002_rename_content_json.sql +2 -0
- package/packages/db/src/migrations/meta/0000_snapshot.json +1331 -0
- package/packages/db/src/migrations/meta/0001_snapshot.json +1399 -0
- package/packages/db/src/migrations/meta/0002_snapshot.json +1399 -0
- package/packages/db/src/migrations/meta/_journal.json +27 -0
- package/packages/db/src/schema.ts +378 -0
- package/packages/db/tsconfig.json +17 -0
- package/scripts/export-openapi.ts +37 -0
- package/scripts/health-check.sh +75 -0
- package/scripts/migrate.sh +135 -0
- package/scripts/prework_backup.sh +25 -0
- package/scripts/release.sh +83 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
## Quick Start (Docker Compose)
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/hiai-gg/hiai-docs.git
|
|
7
|
+
cd hiai-docs
|
|
8
|
+
cp .env.example .env
|
|
9
|
+
# Edit .env with your values (see Environment Variables below)
|
|
10
|
+
|
|
11
|
+
docker compose up -d
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The app will be available at:
|
|
15
|
+
- Frontend: `http://localhost:50701`
|
|
16
|
+
- API: `http://localhost:50700`
|
|
17
|
+
- API Docs: `http://localhost:50700/api/docs`
|
|
18
|
+
- MinIO Console: `http://localhost:9001`
|
|
19
|
+
|
|
20
|
+
## Local Development
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bun install
|
|
24
|
+
|
|
25
|
+
# Start infrastructure only (use shared ai-core services or local docker)
|
|
26
|
+
docker compose -f docker-compose.dev.yml up -d
|
|
27
|
+
|
|
28
|
+
# Push database schema
|
|
29
|
+
cd packages/db && bun run db:push && cd ../..
|
|
30
|
+
|
|
31
|
+
# Start backend and frontend in separate terminals
|
|
32
|
+
cd backend && bun run dev # → localhost:50700
|
|
33
|
+
cd frontend && bun run dev # → localhost:50701
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Environment Variables
|
|
37
|
+
|
|
38
|
+
Copy `.env.example` and fill in:
|
|
39
|
+
|
|
40
|
+
| Variable | Required | Default | Description |
|
|
41
|
+
|----------|----------|---------|-------------|
|
|
42
|
+
| `DB_USER` | Yes | `aiuser` | PostgreSQL username |
|
|
43
|
+
| `DB_PASSWORD` | Yes | `changeme` | PostgreSQL password |
|
|
44
|
+
| `DB_NAME` | Yes | `hiai_docs` | Database name |
|
|
45
|
+
| `DB_HOST` | Yes | `localhost` | PostgreSQL host |
|
|
46
|
+
| `DB_PORT` | Yes | `5433` | PostgreSQL port |
|
|
47
|
+
| `BETTER_AUTH_SECRET` | **Yes** | — | Random 32+ char string |
|
|
48
|
+
| `BETTER_AUTH_URL` | Yes | `http://localhost:50700` | Public API URL |
|
|
49
|
+
| `MINIO_ACCESS_KEY` | Yes | `minioadmin` | MinIO access key |
|
|
50
|
+
| `MINIO_SECRET_KEY` | Yes | `minioadmin` | MinIO secret key |
|
|
51
|
+
| `MINIO_BUCKET` | Yes | `hiai-docs` | MinIO bucket name |
|
|
52
|
+
| `EMBEDDING_PROVIDER` | No | `ollama` | `ollama`, `openrouter`, or `voyage` |
|
|
53
|
+
| `EMBEDDING_MODEL` | No | `nomic-embed-text` | Model name |
|
|
54
|
+
| `OPENROUTER_API_KEY` | If fallback | — | OpenRouter API key |
|
|
55
|
+
| `API_PORT` | No | `50700` | Backend port |
|
|
56
|
+
| `WEB_PORT` | No | `50701` | Frontend port |
|
|
57
|
+
| `NODE_ENV` | No | `development` | `development` or `production` |
|
|
58
|
+
| `LOG_LEVEL` | No | `info` | `trace`/`debug`/`info`/`warn`/`error`/`fatal` |
|
|
59
|
+
|
|
60
|
+
## Production Considerations
|
|
61
|
+
|
|
62
|
+
### TLS
|
|
63
|
+
|
|
64
|
+
Use Caddy (included) or a reverse proxy. The default Caddyfile routes:
|
|
65
|
+
- `/api/*` → backend
|
|
66
|
+
- `/*` → frontend
|
|
67
|
+
|
|
68
|
+
For custom domains, update `Caddyfile` with your domain.
|
|
69
|
+
|
|
70
|
+
### Backups
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Database
|
|
74
|
+
docker compose exec postgres pg_dump -U aiuser hiai_docs > backup.sql
|
|
75
|
+
|
|
76
|
+
# Restore
|
|
77
|
+
cat backup.sql | docker compose exec -T postgres psql -U aiuser -d hiai_docs
|
|
78
|
+
|
|
79
|
+
# MinIO attachments
|
|
80
|
+
docker compose exec minio mc mirror /data ./backup-minio/
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Health Checks
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
curl -fsS http://localhost:50700/api/health
|
|
87
|
+
# → {"status":"ok","timestamp":"..."}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Database Migrations
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Generate migration from schema changes
|
|
94
|
+
cd packages/db && bun run db:generate
|
|
95
|
+
|
|
96
|
+
# Apply migration
|
|
97
|
+
bun run db:migrate
|
|
98
|
+
|
|
99
|
+
# Push schema directly (dev only)
|
|
100
|
+
bun run db:push
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Services
|
|
104
|
+
|
|
105
|
+
| Container | Port | Purpose |
|
|
106
|
+
|-----------|------|---------|
|
|
107
|
+
| postgres | 5433 | PostgreSQL 18 + pgvector |
|
|
108
|
+
| redis | 6380 | Cache/queue |
|
|
109
|
+
| ollama | 11434 | Embedding provider |
|
|
110
|
+
| minio | 9000/9001 | S3-compatible file storage |
|
|
111
|
+
| api | 50700 | Elysia REST API |
|
|
112
|
+
| web | 50701 | SvelteKit frontend |
|
|
113
|
+
| caddy | 80/443 | Reverse proxy |
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Production Status Report
|
|
2
|
+
|
|
3
|
+
> **Status:** ✅ READY FOR DEPLOYMENT
|
|
4
|
+
> **Last verified:** 2026-06-14
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Verification Results
|
|
9
|
+
|
|
10
|
+
| Check | Status |
|
|
11
|
+
|-------|--------|
|
|
12
|
+
| Typecheck | ✅ PASS — 0 errors across all packages |
|
|
13
|
+
| Tests | ✅ PASS — 178/178 passing |
|
|
14
|
+
| Build | ✅ PASS — Docker multi-stage builds |
|
|
15
|
+
| Health checks | ✅ PASS |
|
|
16
|
+
|
|
17
|
+
## 2. Architecture
|
|
18
|
+
|
|
19
|
+
10 route files: auth, documents, folders, search, share, tags, attachments, versions, webhooks, collaboration.
|
|
20
|
+
|
|
21
|
+
Security: rate limiting, Zod validation, owner_id scoping, CSRF protection, CORS, security headers.
|
|
22
|
+
|
|
23
|
+
## 3. Deployment
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/hiai-gg/hiai-docs.git && cd hiai-docs
|
|
27
|
+
cp .env.example .env
|
|
28
|
+
docker compose pull && docker compose up -d
|
|
29
|
+
docker compose exec api bun run db:migrate
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Ports
|
|
33
|
+
|
|
34
|
+
| Port | Service |
|
|
35
|
+
|------|---------|
|
|
36
|
+
| 50700 | API |
|
|
37
|
+
| 50701 | Frontend |
|
|
38
|
+
| 5433 | PostgreSQL |
|
|
39
|
+
| 6384 | Redis |
|
|
40
|
+
| 9020 | MinIO S3 |
|
|
41
|
+
| 80/443 | Caddy |
|
|
42
|
+
|
|
43
|
+
## 4. Testing
|
|
44
|
+
|
|
45
|
+
178 tests passing. Run: `bun test`, `cd backend && bun test`, `cd frontend && bun test`.
|
|
46
|
+
|
|
47
|
+
## 5. Security Checklist
|
|
48
|
+
|
|
49
|
+
Authentication, CSRF, rate limiting, Zod validation, owner scoping, CORS, HSTS, CSP, X-Frame-Options, password hashing (Argon2id), API key auth, non-root containers, parameterized queries — all in place.
|
|
50
|
+
|
|
51
|
+
## 6. Known Issues
|
|
52
|
+
|
|
53
|
+
- **Biome/Svelte 5:** 44 false-positive lint errors on Svelte 5 runes (non-blocking)
|
|
54
|
+
- **Typebox pin:** required for Elysia 1.4.28 compatibility
|
|
55
|
+
- **OPENROUTER_API_KEY:** placeholder, replace before production
|
|
56
|
+
- **No E2E tests:** tracked in todo.md T6.3
|
|
57
|
+
- **No automated backups:** operator responsibility
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
*Status: ✅ READY FOR DEPLOYMENT*
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openapi": "3.1.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "hiai-docs API",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "Self-hosted AI-first documentation platform. Full-text + semantic search, version history, sharing, and folder organization.",
|
|
7
|
+
"contact": {
|
|
8
|
+
"name": "hiai-gg",
|
|
9
|
+
"url": "https://github.com/hiai-gg/hiai-docs"
|
|
10
|
+
},
|
|
11
|
+
"license": {
|
|
12
|
+
"name": "MIT",
|
|
13
|
+
"url": "https://opensource.org/licenses/MIT"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"servers": [
|
|
17
|
+
{ "url": "http://localhost:50700", "description": "Local development" }
|
|
18
|
+
],
|
|
19
|
+
"tags": [
|
|
20
|
+
{ "name": "Health", "description": "Health check" },
|
|
21
|
+
{ "name": "Auth", "description": "Authentication" },
|
|
22
|
+
{ "name": "Documents", "description": "Document CRUD" },
|
|
23
|
+
{ "name": "Folders", "description": "Folder management" },
|
|
24
|
+
{ "name": "Tags", "description": "Tag management" },
|
|
25
|
+
{ "name": "Versions", "description": "Document version history" },
|
|
26
|
+
{ "name": "Search", "description": "Hybrid full-text + semantic search" },
|
|
27
|
+
{ "name": "Share", "description": "Sharing and guest access" }
|
|
28
|
+
],
|
|
29
|
+
"paths": {
|
|
30
|
+
"/api/health": {
|
|
31
|
+
"get": {
|
|
32
|
+
"tags": ["Health"],
|
|
33
|
+
"summary": "Health check",
|
|
34
|
+
"operationId": "getHealth",
|
|
35
|
+
"responses": {
|
|
36
|
+
"200": {
|
|
37
|
+
"description": "Service is healthy",
|
|
38
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/HealthResponse" } } }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"/api/documents": {
|
|
44
|
+
"get": {
|
|
45
|
+
"tags": ["Documents"],
|
|
46
|
+
"summary": "List documents",
|
|
47
|
+
"operationId": "listDocuments",
|
|
48
|
+
"security": [{ "sessionAuth": [] }],
|
|
49
|
+
"parameters": [
|
|
50
|
+
{ "name": "folderId", "in": "query", "schema": { "type": "string", "format": "uuid" } },
|
|
51
|
+
{ "name": "tag", "in": "query", "schema": { "type": "string", "format": "uuid" } },
|
|
52
|
+
{ "name": "page", "in": "query", "schema": { "type": "integer", "default": 1, "minimum": 1 } },
|
|
53
|
+
{ "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 } }
|
|
54
|
+
],
|
|
55
|
+
"responses": {
|
|
56
|
+
"200": {
|
|
57
|
+
"description": "Paginated list of documents",
|
|
58
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/DocumentListResponse" } } }
|
|
59
|
+
},
|
|
60
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"post": {
|
|
64
|
+
"tags": ["Documents"],
|
|
65
|
+
"summary": "Create document",
|
|
66
|
+
"operationId": "createDocument",
|
|
67
|
+
"security": [{ "sessionAuth": [] }],
|
|
68
|
+
"requestBody": {
|
|
69
|
+
"required": true,
|
|
70
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateDocument" } } }
|
|
71
|
+
},
|
|
72
|
+
"responses": {
|
|
73
|
+
"201": { "description": "Document created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Document" } } } },
|
|
74
|
+
"400": { "$ref": "#/components/responses/BadRequest" },
|
|
75
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"/api/documents/{id}": {
|
|
80
|
+
"get": {
|
|
81
|
+
"tags": ["Documents"],
|
|
82
|
+
"summary": "Get document with tags",
|
|
83
|
+
"operationId": "getDocument",
|
|
84
|
+
"security": [{ "sessionAuth": [] }],
|
|
85
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
86
|
+
"responses": {
|
|
87
|
+
"200": { "description": "Document details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DocumentWithTags" } } } },
|
|
88
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
89
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"patch": {
|
|
93
|
+
"tags": ["Documents"],
|
|
94
|
+
"summary": "Update document (auto-saves version)",
|
|
95
|
+
"operationId": "updateDocument",
|
|
96
|
+
"security": [{ "sessionAuth": [] }],
|
|
97
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
98
|
+
"requestBody": {
|
|
99
|
+
"required": true,
|
|
100
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateDocument" } } }
|
|
101
|
+
},
|
|
102
|
+
"responses": {
|
|
103
|
+
"200": { "description": "Document updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Document" } } } },
|
|
104
|
+
"400": { "$ref": "#/components/responses/BadRequest" },
|
|
105
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
106
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"delete": {
|
|
110
|
+
"tags": ["Documents"],
|
|
111
|
+
"summary": "Delete document",
|
|
112
|
+
"operationId": "deleteDocument",
|
|
113
|
+
"security": [{ "sessionAuth": [] }],
|
|
114
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
115
|
+
"responses": {
|
|
116
|
+
"200": { "description": "Document deleted" },
|
|
117
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
118
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"/api/folders": {
|
|
123
|
+
"get": {
|
|
124
|
+
"tags": ["Folders"],
|
|
125
|
+
"summary": "List folders",
|
|
126
|
+
"operationId": "listFolders",
|
|
127
|
+
"security": [{ "sessionAuth": [] }],
|
|
128
|
+
"parameters": [{ "name": "parentId", "in": "query", "schema": { "type": "string", "format": "uuid" } }],
|
|
129
|
+
"responses": {
|
|
130
|
+
"200": { "description": "List of folders", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Folder" } } } } },
|
|
131
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"post": {
|
|
135
|
+
"tags": ["Folders"],
|
|
136
|
+
"summary": "Create folder",
|
|
137
|
+
"operationId": "createFolder",
|
|
138
|
+
"security": [{ "sessionAuth": [] }],
|
|
139
|
+
"requestBody": {
|
|
140
|
+
"required": true,
|
|
141
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateFolder" } } }
|
|
142
|
+
},
|
|
143
|
+
"responses": {
|
|
144
|
+
"201": { "description": "Folder created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Folder" } } } },
|
|
145
|
+
"400": { "$ref": "#/components/responses/BadRequest" },
|
|
146
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"/api/folders/{id}": {
|
|
151
|
+
"patch": {
|
|
152
|
+
"tags": ["Folders"],
|
|
153
|
+
"summary": "Update folder",
|
|
154
|
+
"operationId": "updateFolder",
|
|
155
|
+
"security": [{ "sessionAuth": [] }],
|
|
156
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
157
|
+
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateFolder" } } } },
|
|
158
|
+
"responses": {
|
|
159
|
+
"200": { "description": "Folder updated" },
|
|
160
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
161
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"delete": {
|
|
165
|
+
"tags": ["Folders"],
|
|
166
|
+
"summary": "Delete folder",
|
|
167
|
+
"operationId": "deleteFolder",
|
|
168
|
+
"security": [{ "sessionAuth": [] }],
|
|
169
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
170
|
+
"responses": {
|
|
171
|
+
"200": { "description": "Folder deleted" },
|
|
172
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
173
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
"/api/tags": {
|
|
178
|
+
"get": {
|
|
179
|
+
"tags": ["Tags"],
|
|
180
|
+
"summary": "List tags with document counts",
|
|
181
|
+
"operationId": "listTags",
|
|
182
|
+
"security": [{ "sessionAuth": [] }],
|
|
183
|
+
"responses": {
|
|
184
|
+
"200": { "description": "List of tags", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TagWithCount" } } } } },
|
|
185
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"post": {
|
|
189
|
+
"tags": ["Tags"],
|
|
190
|
+
"summary": "Create tag",
|
|
191
|
+
"operationId": "createTag",
|
|
192
|
+
"security": [{ "sessionAuth": [] }],
|
|
193
|
+
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateTag" } } } },
|
|
194
|
+
"responses": {
|
|
195
|
+
"201": { "description": "Tag created" },
|
|
196
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
197
|
+
"409": { "description": "Tag name already exists" }
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"/api/tags/{id}": {
|
|
202
|
+
"patch": {
|
|
203
|
+
"tags": ["Tags"],
|
|
204
|
+
"summary": "Update tag",
|
|
205
|
+
"operationId": "updateTag",
|
|
206
|
+
"security": [{ "sessionAuth": [] }],
|
|
207
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
208
|
+
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateTag" } } } },
|
|
209
|
+
"responses": {
|
|
210
|
+
"200": { "description": "Tag updated" },
|
|
211
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
212
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"delete": {
|
|
216
|
+
"tags": ["Tags"],
|
|
217
|
+
"summary": "Delete tag",
|
|
218
|
+
"operationId": "deleteTag",
|
|
219
|
+
"security": [{ "sessionAuth": [] }],
|
|
220
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
221
|
+
"responses": {
|
|
222
|
+
"200": { "description": "Tag deleted" },
|
|
223
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
"/api/documents/{id}/tags": {
|
|
228
|
+
"post": {
|
|
229
|
+
"tags": ["Tags"],
|
|
230
|
+
"summary": "Add tag to document",
|
|
231
|
+
"operationId": "addTagToDocument",
|
|
232
|
+
"security": [{ "sessionAuth": [] }],
|
|
233
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
234
|
+
"requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "tagId": { "type": "string", "format": "uuid" } }, "required": ["tagId"] } } } },
|
|
235
|
+
"responses": {
|
|
236
|
+
"201": { "description": "Tag added" },
|
|
237
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
238
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
"/api/documents/{id}/tags/{tagId}": {
|
|
243
|
+
"delete": {
|
|
244
|
+
"tags": ["Tags"],
|
|
245
|
+
"summary": "Remove tag from document",
|
|
246
|
+
"operationId": "removeTagFromDocument",
|
|
247
|
+
"security": [{ "sessionAuth": [] }],
|
|
248
|
+
"parameters": [
|
|
249
|
+
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
|
|
250
|
+
{ "name": "tagId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
|
|
251
|
+
],
|
|
252
|
+
"responses": {
|
|
253
|
+
"200": { "description": "Tag removed" },
|
|
254
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
"/api/documents/{id}/versions": {
|
|
259
|
+
"get": {
|
|
260
|
+
"tags": ["Versions"],
|
|
261
|
+
"summary": "List document versions",
|
|
262
|
+
"operationId": "listVersions",
|
|
263
|
+
"security": [{ "sessionAuth": [] }],
|
|
264
|
+
"parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
|
|
265
|
+
"responses": {
|
|
266
|
+
"200": { "description": "List of versions", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Version" } } } } },
|
|
267
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
268
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"/api/documents/{id}/versions/{vid}": {
|
|
273
|
+
"get": {
|
|
274
|
+
"tags": ["Versions"],
|
|
275
|
+
"summary": "Get specific version",
|
|
276
|
+
"operationId": "getVersion",
|
|
277
|
+
"security": [{ "sessionAuth": [] }],
|
|
278
|
+
"parameters": [
|
|
279
|
+
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
|
|
280
|
+
{ "name": "vid", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
|
|
281
|
+
],
|
|
282
|
+
"responses": {
|
|
283
|
+
"200": { "description": "Version details" },
|
|
284
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
285
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"/api/search": {
|
|
290
|
+
"get": {
|
|
291
|
+
"tags": ["Search"],
|
|
292
|
+
"summary": "Hybrid full-text + semantic search",
|
|
293
|
+
"operationId": "search",
|
|
294
|
+
"security": [{ "sessionAuth": [] }],
|
|
295
|
+
"parameters": [
|
|
296
|
+
{ "name": "q", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Search query" },
|
|
297
|
+
{ "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } },
|
|
298
|
+
{ "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } }
|
|
299
|
+
],
|
|
300
|
+
"responses": {
|
|
301
|
+
"200": { "description": "Search results", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } } },
|
|
302
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
"/api/search/suggest": {
|
|
307
|
+
"get": {
|
|
308
|
+
"tags": ["Search"],
|
|
309
|
+
"summary": "Title autocomplete suggestions",
|
|
310
|
+
"operationId": "searchSuggest",
|
|
311
|
+
"security": [{ "sessionAuth": [] }],
|
|
312
|
+
"parameters": [{ "name": "q", "in": "query", "required": true, "schema": { "type": "string" } }],
|
|
313
|
+
"responses": {
|
|
314
|
+
"200": { "description": "Suggestions", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SearchSuggestion" } } } } },
|
|
315
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
"/api/share/link": {
|
|
320
|
+
"post": {
|
|
321
|
+
"tags": ["Share"],
|
|
322
|
+
"summary": "Create share link",
|
|
323
|
+
"operationId": "createShareLink",
|
|
324
|
+
"security": [{ "sessionAuth": [] }],
|
|
325
|
+
"requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateShareLink" } } } },
|
|
326
|
+
"responses": {
|
|
327
|
+
"201": { "description": "Share link created" },
|
|
328
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
"/api/share/{token}": {
|
|
333
|
+
"get": {
|
|
334
|
+
"tags": ["Share"],
|
|
335
|
+
"summary": "Access shared document/folder (public)",
|
|
336
|
+
"operationId": "accessShareLink",
|
|
337
|
+
"parameters": [
|
|
338
|
+
{ "name": "token", "in": "path", "required": true, "schema": { "type": "string" } },
|
|
339
|
+
{ "name": "password", "in": "query", "schema": { "type": "string" } }
|
|
340
|
+
],
|
|
341
|
+
"responses": {
|
|
342
|
+
"200": { "description": "Shared content" },
|
|
343
|
+
"401": { "description": "Password required or invalid" },
|
|
344
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
345
|
+
"429": { "description": "Rate limited" }
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
"components": {
|
|
351
|
+
"securitySchemes": {
|
|
352
|
+
"sessionAuth": {
|
|
353
|
+
"type": "apiKey",
|
|
354
|
+
"in": "cookie",
|
|
355
|
+
"name": "better-auth.session_token",
|
|
356
|
+
"description": "Session cookie from Better Auth"
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
"responses": {
|
|
360
|
+
"Unauthorized": { "description": "Authentication required", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Unauthorized" } } } } } },
|
|
361
|
+
"BadRequest": { "description": "Invalid input", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" }, "details": { "type": "object" } } } } } },
|
|
362
|
+
"NotFound": { "description": "Resource not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Document not found" } } } } } }
|
|
363
|
+
},
|
|
364
|
+
"schemas": {
|
|
365
|
+
"HealthResponse": { "type": "object", "properties": { "status": { "type": "string", "example": "ok" }, "timestamp": { "type": "string", "format": "date-time" } } },
|
|
366
|
+
"Document": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "ownerId": { "type": "string", "format": "uuid" }, "folderId": { "type": "string", "format": "uuid", "nullable": true }, "title": { "type": "string" }, "content": { "type": "string" }, "contentJson": { "nullable": true }, "metadata": { "nullable": true }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } },
|
|
367
|
+
"DocumentWithTags": { "allOf": [{ "$ref": "#/components/schemas/Document" }, { "type": "object", "properties": { "tags": { "type": "array", "items": { "$ref": "#/components/schemas/Tag" } } } }] },
|
|
368
|
+
"DocumentListResponse": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Document" } }, "total": { "type": "integer" }, "page": { "type": "integer" }, "limit": { "type": "integer" } } },
|
|
369
|
+
"CreateDocument": { "type": "object", "properties": { "title": { "type": "string", "default": "Untitled" }, "content": { "type": "string" }, "folderId": { "type": "string", "format": "uuid" } } },
|
|
370
|
+
"UpdateDocument": { "type": "object", "properties": { "title": { "type": "string" }, "content": { "type": "string" }, "contentJson": {}, "metadata": {}, "folderId": { "type": "string", "format": "uuid", "nullable": true } } },
|
|
371
|
+
"Folder": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "ownerId": { "type": "string", "format": "uuid" }, "parentId": { "type": "string", "format": "uuid", "nullable": true }, "name": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } },
|
|
372
|
+
"CreateFolder": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string" }, "parentId": { "type": "string", "format": "uuid" } } },
|
|
373
|
+
"UpdateFolder": { "type": "object", "properties": { "name": { "type": "string" }, "parentId": { "type": "string", "format": "uuid", "nullable": true } } },
|
|
374
|
+
"Tag": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "color": { "type": "string", "nullable": true }, "createdAt": { "type": "string", "format": "date-time" } } },
|
|
375
|
+
"TagWithCount": { "allOf": [{ "$ref": "#/components/schemas/Tag" }, { "type": "object", "properties": { "documentCount": { "type": "integer" } } }] },
|
|
376
|
+
"CreateTag": { "type": "object", "required": ["name"], "properties": { "name": { "type": "string" }, "color": { "type": "string" } } },
|
|
377
|
+
"UpdateTag": { "type": "object", "properties": { "name": { "type": "string" }, "color": { "type": "string" } } },
|
|
378
|
+
"Version": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "documentId": { "type": "string", "format": "uuid" }, "content": { "type": "string" }, "contentJson": { "nullable": true }, "createdBy": { "type": "string", "format": "uuid" }, "createdAt": { "type": "string", "format": "date-time" } } },
|
|
379
|
+
"SearchResponse": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/SearchResult" } }, "total": { "type": "integer" }, "page": { "type": "integer" }, "limit": { "type": "integer" } } },
|
|
380
|
+
"SearchResult": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "title": { "type": "string" }, "snippet": { "type": "string" }, "score": { "type": "number" }, "folder_id": { "type": "string", "format": "uuid", "nullable": true }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } },
|
|
381
|
+
"SearchSuggestion": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "title": { "type": "string" }, "score": { "type": "number" } } },
|
|
382
|
+
"CreateShareLink": { "type": "object", "properties": { "documentId": { "type": "string", "format": "uuid" }, "folderId": { "type": "string", "format": "uuid" }, "password": { "type": "string" }, "expiresIn": { "type": "integer", "description": "Seconds until expiration" } } }
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|