dorfteich/apps/api/package.json
Claude Sonnet 5 98e159ab50
All checks were successful
CD / Build and push images (push) Successful in 1m52s
CI / Lint, typecheck, test (push) Successful in 1m34s
CI / Auth e2e pack (push) Successful in 1m44s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 8s
CD / Smoke tests against Test (push) Successful in 1m7s
CD / Promote to Int (push) Successful in 10s
Add page CRUD and Yjs state persistence (#23)
Prisma models `pages`/`page_updates`/`page_content_cache` per
data-model.md. Endpoints: POST /ponds/:id/pages (title -> empty Yjs doc
state, seeded via y-prosemirror), GET /pages/:id (meta + base64 state),
PUT /pages/:id/state (client-encoded Yjs state, rejected above the 5 MiB
operations.md limit or if it doesn't decode into a valid document for
the schema), PATCH /pages/:id (title/slug — explicit slug changes
validate uniqueness per pond, title-only renames keep the slug),
DELETE (soft). Access follows InterimAccessService via the page's pond,
same 404-not-403 interim rule as ponds.

State saves decode the Yjs update with yjs + y-prosemirror and run it
through the #24 shared derivation functions (docToPlainText/
docToMarkdown/docToHtml/extractOutline) to refresh page_content_cache.
The Yjs XmlFragment name ("default") and the derivation call are
factored so the collab server's persistence hooks (#35) can reuse both.

Raised the API's JSON body limit to 8 MiB (main.ts and the e2e test
app) to fit base64-encoded page state.

Closes #23
2026-07-05 22:25:41 +02:00

56 lines
1.5 KiB
JSON

{
"name": "@dorfteich/api",
"version": "0.0.0",
"private": true,
"description": "Dorfteich REST API server",
"license": "MIT",
"scripts": {
"build": "prisma generate && nest build",
"start": "node dist/main.js",
"start:dev": "prisma generate && nest start --watch",
"typecheck": "tsc --noEmit",
"test": "vitest run --passWithNoTests",
"db:migrate:dev": "prisma migrate dev",
"db:seed": "tsx prisma/seed.ts"
},
"dependencies": {
"@dorfteich/shared": "workspace:*",
"@nestjs/common": "^11.0.0",
"@nestjs/core": "^11.0.0",
"@nestjs/platform-express": "^11.0.0",
"@prisma/client": "^6.3.0",
"argon2": "^0.44.0",
"cookie-parser": "^1.4.7",
"fractional-indexing": "^4.0.0",
"i18next": "^26.3.4",
"nestjs-pino": "^4.3.0",
"nodemailer": "^9.0.3",
"pino": "^9.6.0",
"pino-http": "^10.4.0",
"prisma": "^6.3.0",
"prosemirror-model": "^1.25.9",
"prosemirror-state": "^1.4.4",
"prosemirror-view": "^1.42.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.0",
"y-prosemirror": "^1.3.7",
"y-protocols": "^1.0.7",
"yjs": "^13.6.31",
"zod": "^3.25.76"
},
"devDependencies": {
"@nestjs/cli": "^11.0.0",
"@nestjs/testing": "^11.0.0",
"@swc/core": "^1.10.0",
"@types/cookie-parser": "^1.4.10",
"@types/express": "^5.0.0",
"@types/nodemailer": "^8.0.1",
"@types/supertest": "^6.0.0",
"pino-pretty": "^13.0.0",
"supertest": "^7.0.0",
"tsx": "^4.19.0",
"unplugin-swc": "^1.5.0",
"vitest": "^3.0.0"
}
}