Skip to content

feat: invoice CRUD API with Puppeteer PDF generation & Cloudinary storage#123

Merged
0xdevcollins merged 1 commit intomainfrom
feat/invoice-crud-pdf-generation
Apr 4, 2026
Merged

feat: invoice CRUD API with Puppeteer PDF generation & Cloudinary storage#123
0xdevcollins merged 1 commit intomainfrom
feat/invoice-crud-pdf-generation

Conversation

@0xdevcollins
Copy link
Copy Markdown
Owner

@0xdevcollins 0xdevcollins commented Apr 4, 2026

closes: #66## Summary

  • Full invoice CRUD API (POST, GET, PATCH, DELETE) with Zod validation
  • Server-side PDF generation using Puppeteer rendering a branded HTML template (merchant logo, brand colour, line items, totals, partial payment balance)
  • PDF storage via Cloudinary (free tier — replaces Cloudflare R2)
  • Partial payment tracking with automatic status transitions
  • Invoice schema extended with invoiceNumber, amountPaid, customerPhone, customerAddress, notes, updatedAt + DB indexes

Endpoints

Method Path Auth
POST /v1/invoices API key or JWT
GET /v1/invoices JWT
GET /v1/invoices/:id API key or JWT
PATCH /v1/invoices/:id JWT (DRAFT only)
DELETE /v1/invoices/:id JWT (DRAFT only)
POST /v1/invoices/:id/send JWT
POST /v1/invoices/:id/cancel JWT
POST /v1/invoices/:id/payments JWT
GET /v1/invoices/:id/pdf API key or JWT
GET /v1/invoices/:id/pdf/download API key or JWT

Status lifecycle

DRAFT → SENT → VIEWED → PARTIALLY_PAID → PAID → OVERDUE → CANCELLED

Test plan

  • POST /v1/invoices creates invoice with correct computed totals (subtotal, tax, discount)
  • GET /v1/invoices returns paginated list filterable by status, currency, date range, search
  • PATCH /v1/invoices/:id rejects non-DRAFT invoices
  • DELETE /v1/invoices/:id rejects non-DRAFT invoices
  • POST /v1/invoices/:id/payments transitions status correctly (PARTIALLY_PAID → PAID)
  • GET /v1/invoices/:id/pdf generates PDF, uploads to Cloudinary, returns URL
  • GET /v1/invoices/:id/pdf/download streams PDF buffer directly
  • PDF renders merchant branding (logo, brand colour)
  • Set CLOUDINARY_CLOUD_NAME, CLOUDINARY_API_KEY, CLOUDINARY_API_SECRET in .env
  • Run migration: npx prisma migrate dev

🤖 Generated with Claude Code

- Add full CRUD endpoints: POST, GET (list + detail), PATCH, DELETE
- Add PDF generation via Puppeteer rendering a branded HTML template
- Add PDF storage via Cloudinary (free tier, replaces R2)
- Add partial payment tracking with automatic status transitions
- Add StorageService (Cloudinary) and PdfService modules
- Add Zod-validated DTOs for create, update, filters, and record-payment
- Extend Invoice schema: invoiceNumber, amountPaid, customerPhone,
  customerAddress, notes, updatedAt + DB indexes
- Add migration backfilling updatedAt for existing rows
- Update .env.example to replace R2 vars with Cloudinary vars

Status lifecycle: DRAFT → SENT → VIEWED → PARTIALLY_PAID → PAID → OVERDUE → CANCELLED
Endpoints: POST /v1/invoices, GET /v1/invoices, GET /v1/invoices/:id,
           PATCH /v1/invoices/:id, DELETE /v1/invoices/:id,
           GET /v1/invoices/:id/pdf, GET /v1/invoices/:id/pdf/download,
           POST /v1/invoices/:id/send, POST /v1/invoices/:id/cancel,
           POST /v1/invoices/:id/payments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@0xdevcollins 0xdevcollins merged commit 0a13598 into main Apr 4, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API: Invoice CRUD Endpoints & PDF Generation

1 participant