| name | pdf-invoicing-snapshots |
| description | Use this skill when you work on invoices or PDFs draft→finalize, immutable invoice snapshots, numbering, and PDF rendering/export. |
Invoice Finalization & PDF Skill
Use this skill for invoice creation, finalization, snapshots, and PDF export.
Rules
- Draft invoices are editable. Finalization creates immutable snapshot and locks edits.
- Snapshot must include: seller/workspace details, client details, line items (qty, unit price, tax), totals, currency, locale, template version, render hash (if cached).
- Finalized PDFs must render from snapshot only. Draft preview can render live state.
- Numbering: unique per workspace, generated at finalization.
Workflow (finalize)
- Guard: derive tenant/workspace server-side (via your tenant guard helper) and scope invoice to
workspace_id (or your equivalent tenant column).
- Compute/assign next invoice number (workspace-scoped).
- Build snapshot JSON from current invoice + items + client/workspace data.
- Persist snapshot in
invoice_snapshots tied to invoice_id.
- Mark invoice status
issued (or finalized), set finalizedAt.
- Revalidate invoice list/detail paths.
PDF route handler
- Your PDF export endpoint (often a Route Handler, e.g.,
GET /api/invoices/[id]/pdf) should authorize by tenant/workspace, then:
- If draft: render from current invoice state.
- If finalized: render from snapshot only.
- Mark route
dynamic = "force-dynamic" if needed.
Cost & performance notes
- Snapshots are not only correctness—they reduce render-time DB work. Prefer rendering finalized PDFs from a single snapshot read.
- Consider storing a deterministic
render_hash (snapshot + template version) to enable safe caching later.
- Stream PDFs and avoid loading/serializing unnecessary related data (client/workspace details should already be inside the snapshot).
For broader caching/invalidation guidance: nextjs-cost-performance skill
Money/time rules
- Store amounts in integer cents; include currency code.
- Store timestamps UTC; format per locale/timezone at render.
Edge cases
- Do not mutate snapshot after finalization; create new draft for changes.
- Handle missing snapshot gracefully (but should not occur after finalize).
- Ensure totals recompute before snapshot to avoid stale values.
Testing
- Add tests for: snapshot immutability, correct totals, numbering uniqueness per workspace, PDF stability after data changes.
References
- Product spec: your PRD/spec doc (if present)
- DB schema: your schema module(s)
- PDF endpoint: your PDF export route/handler