All checks were successful
CD / Build and push images (push) Successful in 10m39s
CI / Lint, typecheck, test (push) Successful in 3m12s
CI / Auth e2e pack (push) Successful in 4m9s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 9s
CD / Smoke tests against Test (push) Successful in 1m18s
CD / Promote to Int (push) Successful in 11s
A signed-in account can export all of its own data — profile, a list of its memberships/grants, and the Markdown of its personal pond plus the shared ponds it owns — as one ZIP. Foreign content never appears: only owned ponds are bundled and the per-page read filter (reused from #65) runs for each. - Reuse the conversion-job queue as the async carrier: a `data_export` job whose worker branch resolves DataExportService via a token (no DI cycle), builds the ZIP, and stores it with an `expiresAt`. The download link 404s past expiry and an hourly scheduled purge drops the bytes (data minimization, security.md §Privacy). - Extract ExportService.appendPondMarkdown so the pond ZIP (#65) and the data export share one read-filtered pond archiver. - Rate-limit requests per account (RateLimitService); POST /users/me/data-export enqueues, GET /jobs/:id(/result) poll/download. - Settings UI "Export my data" (de+en); web share pollJob/downloadJobResult between the document and data export hooks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
49 lines
2.0 KiB
TypeScript
49 lines
2.0 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
/**
|
|
* Import/export conversion job types shared between api and web (ADR 0009,
|
|
* issue #62). A conversion runs asynchronously against the pandoc sidecar;
|
|
* the client enqueues it and polls `GET /jobs/:id` for this view.
|
|
*/
|
|
export type ConversionJobStatus = 'pending' | 'running' | 'succeeded' | 'failed';
|
|
|
|
export interface ConversionJobView {
|
|
id: string;
|
|
status: ConversionJobStatus;
|
|
kind: string;
|
|
sourceFormat: string;
|
|
targetFormat: string;
|
|
/** Set only when `status` is `failed` — a code from the errors namespace
|
|
* (`converter_unavailable` | `converter_timeout` | `conversion_failed` |
|
|
* `quota_exceeded`). */
|
|
errorCode: string | null;
|
|
/** Set once an import job (#63) succeeds: the id of the page it created, so
|
|
* the client can navigate to it. `null` for a pending/failed import and for
|
|
* plain byte→byte conversions (export). */
|
|
resultPageId: string | null;
|
|
/** For a data-export job (#68), when its download link stops working — the
|
|
* result is purged after this. `null` for every other job kind, which never
|
|
* expires. */
|
|
expiresAt: string | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
|
|
/** Extensions the import endpoint accepts (ADR 0009, issues #63/#64). `.docx`
|
|
* and `.odt` convert via the sidecar (a job to poll); `.md`/`.markdown` import
|
|
* in-process and come back already `succeeded`. */
|
|
export const IMPORT_EXTENSIONS = ['docx', 'odt', 'md', 'markdown'] as const;
|
|
export type ImportExtension = (typeof IMPORT_EXTENSIONS)[number];
|
|
|
|
/** Formats a single page exports to via a conversion job whose result is
|
|
* downloaded from `GET /jobs/:id/result` (issues #65/#67). `docx`/`odt` run
|
|
* `markdown → pandoc`; `pdf` renders HTML through Gotenberg. Markdown export is
|
|
* a separate direct download (#30). */
|
|
export const EXPORT_FORMATS = ['docx', 'odt', 'pdf'] as const;
|
|
export type ExportFormat = (typeof EXPORT_FORMATS)[number];
|
|
|
|
export const pageExportInputSchema = z.object({
|
|
format: z.enum(EXPORT_FORMATS),
|
|
});
|
|
export type PageExportInput = z.infer<typeof pageExportInputSchema>;
|