Stand-alone API group at /api/documents/{docId}/versions — one document
per docId (unique), each version stores .docx + optional .pdf as MinIO
objects with uploader userId/userName/createdAt (no auth, like
api/template; callers identify themselves per docs/PLAN-DOCVER.md).
- POST versions (multipart): validates fields/magic bytes/100MB cap,
uploads to MinIO first, cleans up objects if the DB insert fails;
returns {hasPdf, versionId, versionNumber} with server-authoritative
numbering (tx: upsert + SELECT FOR UPDATE, safe under parallel calls)
- GET versions: DocumentVersionDTO[] newest-first (404 for unknown docId)
- GET versions/{versionId}/download-link?format=docx|pdf: presigned URL
(docId+versionId matched together; pdf-missing = 404)
- tables documents/document_versions + migration drizzle/0005
- docker-compose.yml: judes-note-db + judes-note-minio (quay.io image,
host ports 19000/19001, POSTGRES_DB ecourt-note, pinned volume names)
- lib/openapi.ts: documents tag + paths for Swagger UI
- middleware: exempt api/documents from login redirect
- unit tests tests/lib/document-versioning.test.ts (23 cases)
wordaddin untouched — swap the mock later via NEXT_PUBLIC_ADDIN_API_BASE_URL.
Co-Authored-By: Claude Code <noreply@anthropic.com>
49 lines
1.5 KiB
JSON
49 lines
1.5 KiB
JSON
{
|
|
"name": "judes-note",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"scripts": {
|
|
"dev": "next dev",
|
|
"build": "next build",
|
|
"test": "vitest run",
|
|
"start": "next start",
|
|
"seed-samples": "node --env-file=.env scripts/seed-samples.mjs",
|
|
"postinstall": "node scripts/patch-pdf-worker.mjs && node scripts/copy-swagger-ui.mjs && node scripts/fetch-office-js.mjs",
|
|
"dev:https": "next dev --experimental-https",
|
|
"dev:https:cert": "next dev --experimental-https --experimental-https-key certs/localhost.key --experimental-https-cert certs/localhost.crt"
|
|
},
|
|
"dependencies": {
|
|
"@pdf-lib/fontkit": "^1.1.1",
|
|
"@xmldom/xmldom": "^0.9.12",
|
|
"drizzle-orm": "^0.45.2",
|
|
"lucide-react": "^1.42.0",
|
|
"minio": "^8.0.7",
|
|
"next": "^14.2.35",
|
|
"pdf-lib": "^1.17.1",
|
|
"pdfjs-dist": "^4.10.38",
|
|
"pizzip": "^3.3.0",
|
|
"pngjs": "^7.0.0",
|
|
"postgres": "^3.4.9",
|
|
"react": "^18.3.1",
|
|
"react-dom": "^18.3.1",
|
|
"swagger-ui-dist": "^5.33.1",
|
|
"utif2": "^4.1.0",
|
|
"xpath": "^0.0.34"
|
|
},
|
|
"devDependencies": {
|
|
"@types/node": "^26.5.0",
|
|
"@types/office-js": "^1.0.612",
|
|
"@types/pngjs": "^6.0.5",
|
|
"@types/react": "^18.3.31",
|
|
"@types/react-dom": "^18.3.7",
|
|
"autoprefixer": "^10.5.5",
|
|
"drizzle-kit": "^0.31.10",
|
|
"jsdom": "^29.1.1",
|
|
"office-addin-debugging": "^7.0.1",
|
|
"office-addin-dev-settings": "^4.0.1",
|
|
"postcss": "^8.5.28",
|
|
"tailwindcss": "^3.4.19",
|
|
"typescript": "^5.9.3",
|
|
"vitest": "^5.0.0"
|
|
}
|
|
}
|