dorfteich/apps/api/src/import-export
Claude Opus 5 f8c241b11a
Some checks failed
CI / Lint, typecheck, test (pull_request) Failing after 6m26s
CI / Auth e2e pack (pull_request) Has been skipped
CI / Import/export fidelity gate (pull_request) Has been skipped
CI / Build container images (pull_request) Has been skipped
#304: custom fonts in the pickers, an admin screen, and the licence page
The backend from #303 could store an operator's font but nothing could
choose one: no list endpoint outside the Site-Admin routes, no @font-face
rules for a family that only exists at runtime, and no management UI.

Found while wiring it up — a real defect in #303, invisible to its tests:
`fontStack` cannot tell an uploaded family from a deleted one, so the PDF
exporter embedded the face and then never named it. Every export of a pond
using an operator font rendered in the system font while the job reported
success. Both `fontStack` call sites now take the uploaded families
(`buildPdfHtml`, `pondFontVariables`); `pdf-html.test.ts` pins the
regression from both sides. Verified against a real Gotenberg: with the
families the PDF embeds PlayfairDisplay-Bold, without them NotoSans-Bold —
that was the whole bug, in one diff of two PDFs.

- `GET /fonts/custom` is readable by any signed-in user, not Site Admins
  only: the pickers, the licence page and the injected `@font-face` rules
  all need it, and gating it would have forced a second, admin-only UI.
- Bundled and uploaded families are told apart by their `<optgroup>`, not
  by a badge — the grouping is then part of the control's semantics, so a
  screen reader announces it and the native mobile select keeps it. Within
  each source the catalog's category grouping is preserved.
- The delete confirmation names how many ponds use the family and what
  happens to them; focus moves to it and back on cancel. Deletion stays
  unblocked (the api's decision, #303) — the ponds degrade, they do not
  break.
- The licence page grew a second table. That is what makes an attribution
  obligation satisfiable: a commercial licence that requires naming the
  foundry needs a page to name it on.

Verified in the browser end to end (upload two weights → listed and
rendered in its own font → chosen in a pond → page renders in it → deleted
→ pond falls back): api suite for fonts/export 77 passed, a11y pack 11/11
locally in both schemes, lint/typecheck/i18n:check green.
2026-08-01 18:32:46 +02:00
..
classified-markdown.test.ts #210: mark the Markdown ZIP export with frontmatter, imprint and manifest 2026-07-31 07:13:53 +02:00
classified-markdown.ts #210: mark the Markdown ZIP export with frontmatter, imprint and manifest 2026-07-31 07:13:53 +02:00
conversion-job.e2e.db.test.ts #302: configurable pond start page, created with every new pond 2026-08-01 08:06:35 +02:00
conversion-job.service.ts #233: prune conversion job payloads for every job kind 2026-07-30 22:12:32 +02:00
conversion-payload-prune.e2e.db.test.ts #233: prune conversion job payloads for every job kind 2026-07-30 22:12:32 +02:00
conversion-worker.service.ts #209: pandoc reference documents carry the VS-NfD marking for DOCX/ODT 2026-07-31 07:09:47 +02:00
data-export.constants.ts Add self-service GDPR data export (#68) 2026-07-10 13:01:51 +02:00
data-export.controller.ts Add self-service GDPR data export (#68) 2026-07-10 13:01:51 +02:00
data-export.service.db.test.ts Add self-service GDPR data export (#68) 2026-07-10 13:01:51 +02:00
data-export.service.ts #222: read-access trail for classified pages 2026-07-31 12:12:55 +02:00
export-markdown.test.ts Add pond ZIP + per-page docx/odt export (#65) 2026-07-10 10:31:19 +02:00
export-markdown.ts Add pond ZIP + per-page docx/odt export (#65) 2026-07-10 10:31:19 +02:00
export.controller.ts #222: read-access trail for classified pages 2026-07-31 12:12:55 +02:00
export.fidelity.test.ts #209: pandoc reference documents carry the VS-NfD marking for DOCX/ODT 2026-07-31 07:09:47 +02:00
export.service.db.test.ts #212: mark attachment downloads by filename prefix and companion file 2026-07-31 07:29:16 +02:00
export.service.ts #304: custom fonts in the pickers, an admin screen, and the licence page 2026-08-01 18:32:46 +02:00
gotenberg.renderer.ts #208: VS-NfD marking in the Gotenberg per-page header and footer 2026-07-31 06:55:52 +02:00
import-export.module.ts #303: operator-uploaded fonts — storage, API, PDF embedding, backup 2026-08-01 14:49:13 +02:00
import-vault.e2e.db.test.ts Obsidian vault import: endpoint, job orchestration, rollback (#117) 2026-07-14 17:13:11 +02:00
import.constants.ts Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
import.controller.ts Obsidian vault import: endpoint, job orchestration, rollback (#117) 2026-07-14 17:13:11 +02:00
import.fixtures.test.ts Import .docx and .odt documents as new pages (#63) 2026-07-10 07:34:43 +02:00
import.service.db.test.ts Add document import UI in the sidebar (#64) 2026-07-10 09:38:31 +02:00
import.service.ts #210: mark the Markdown ZIP export with frontmatter, imprint and manifest 2026-07-31 07:13:53 +02:00
jobs.controller.ts Add conversion job queue and pandoc sidecar integration (#62) 2026-07-10 04:06:27 +02:00
obsidian-vault.test.ts Vault import: decode ZIP names as UTF-8 and NFC-normalize them 2026-07-15 13:24:58 +02:00
obsidian-vault.ts Vault import: decode ZIP names as UTF-8 and NFC-normalize them 2026-07-15 13:24:58 +02:00
pandoc.converter.test.ts Add conversion job queue and pandoc sidecar integration (#62) 2026-07-10 04:06:27 +02:00
pandoc.converter.ts #209: pandoc reference documents carry the VS-NfD marking for DOCX/ODT 2026-07-31 07:09:47 +02:00
pdf-html.test.ts #304: custom fonts in the pickers, an admin screen, and the licence page 2026-08-01 18:32:46 +02:00
pdf-html.ts #304: custom fonts in the pickers, an admin screen, and the licence page 2026-08-01 18:32:46 +02:00
pdf.fidelity.test.ts #208: VS-NfD marking in the Gotenberg per-page header and footer 2026-07-31 06:55:52 +02:00