- Schema: add publicTokenExpiresAt to invoices table
- invoices.generatePublicToken: accepts optional ttlHours param; sets
expiry timestamp when provided
- invoices.getByPublicToken: returns 403 if token is expired
- New route GET /api/i/[token]/pdf: streams the invoice PDF publicly,
returns 410 Gone if expired; excluded from auth middleware
- MCP invoices_generate_public_token: exposes ttlHours, returns both
webUrl (/i/{token}) and pdfUrl (/api/i/{token}/pdf)
https://claude.ai/code/session_014126WHVRT8mftmqkU6dajG