Export: pond ZIP of Markdown, and .docx/.odt per page #65
Labels
No Label
area:auth
area:docs
area:export
area:ops
area:storage
area:supply-chain
auth
backend
blocked
collab
deployment
docs
effort:L
effort:M
effort:S
frontend
plugins
qa
vs-nfd
vs-nfd:blocker
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: stwaidele/dorfteich#65
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Beyond the M2 per-page Markdown export, users export whole ponds and office formats (vision).
Scope
Endpoints:
GET /ponds/:id/export/markdown(ZIP: one .md per page, folder per label optionally, media directory, wikilinks as relative links),POST /pages/:id/exportwith formatdocx|odt(conversion job: markdown → pandoc → file; embedded images inlined); export menu on page (md/docx/odt/pdf placeholder) and pond settings (ZIP); exports respect the requester's read permissions (pond export contains only readable pages).Acceptance criteria
Technical notes
Dependencies
Depends on #52, #62.
Size: ~1.5 days
Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add
deanden), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.Done in
699c003. Pipeline fully green (all 7 contexts, incl. the new export e2e pack); deployed to Test + Int and verified live.What shipped
GET /ponds/:id/export/markdown— streams a ZIP of the pond's readable pages as Markdown: one<slug>.mdper page, amedia/directory, wikilinks rewritten to relative[text](slug.md)links (plain text when the target isn't readable), image sources rewritten tomedia/<id>.<ext>. Thereaderguard is "may see the pond"; the service filters to the pages the requester may actually read, so a label-restricted reader gets only their slice. Pages are appended as strings and media as read streams, so memory stays bounded for a large pond.POST /pages/:id/export {format: docx|odt}— enqueues amarkdown → pandoc → fileconversion job (the #62 queue): embedded images are inlined asdata:URIs so the sidecar embeds them, wikilinks flatten to text. The client pollsGET /jobs/:idand downloadsGET /jobs/:id/result..docx/.odtrun the job and download; PDF is a disabled placeholder for Gotenberg, #67), and a "Download pond as ZIP" link in pond settings. Newexporti18n namespace (de+en). Markdown copy/download stay as-is (#30).Acceptance criteria
export.service.db.test.tsasserts<slug>.md+media/<id>.pngentries and the rewritten/[text](slug.md); verified live (see below).gfm → docxof the page's Markdown; the DB test asserts the pandoc input (image inlined, wikilink flattened); live docx is a valid OOXML file.Robustness fix (found during e2e): an attachment row whose bytes are missing on disk (data drift) used to throw an unhandled read-stream error and crash the api during a pond export. Now
FileStorageService.existsgates inclusion (with a defensive stream error handler), and the per-page export drops an unreadable image instead of failing — covered by a new DB test.Deps:
archiver(streaming ZIP; pinned to v7 for CommonJS compat — v8 is ESM-only and can't berequired by the Nest build),fflate(dev, reads ZIPs in tests).Tests:
export-markdown.test.ts(transforms) +export.service.db.test.ts(ZIP contents, permission omission, docx job, 500-page streaming, missing-media skip). e2eexport.spec.ts: ZIP download from pond settings;.docxexport self-skips without a pandoc sidecar (as the import pack, #64). api suite 213 green.Live verification (Int): pond ZIP →
collab-test.zipwith 3.mdpages + amedia/file, andfield-notes.md(imported in #63) carrying a working relative. Page docx export → jobsucceeded, result a valid.docx(correct OOXML MIME, 11.5 KB). Test: both export routes deployed (401 unauthenticated),readyzok; CD smoke tests green.Next: #66 (pond fonts), #67 (PDF via Gotenberg — a new sidecar, provisioned like the pandoc one).