| 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 (Freelancerino)
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:
requireWorkspaceCached() and scope invoice to workspace_id.
- 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
GET /api/invoices/[id]/pdf should authorize by 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: .github/skills/nextjs-cost-performance/SKILL.md
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
- PRD:
docs/PRD.md
- DB schema:
db/schema.ts
- Route handler:
app/api/invoices/[id]/pdf/route.ts