PRD: Invoice Export for Finance Teams
Status: Draft v0.1 | Date: 2026-10-05
Items marked TBD or Assumption were not in your discovery answers. Please confirm or correct them.
1. Executive Summary
Problem Statement
Finance managers using our invoicing app can't export invoices to send to their accountants. This generates about 40 support tickets a month and forces manual workarounds.
Proposed Solution
Add a self-serve export to the web app. Users filter invoices, export them in accountant-friendly formats, and share the result with an external accountant without needing an account.
Success Criteria
| # | KPI | Target | Window |
|---|---|---|---|
| 1 | Export-related support tickets | Down 70%, from about 40/month to 12 or fewer/month | 90 days after launch |
| 2 | Active accounts that have run at least one export | 30% | 60 days after launch |
| 3 | Export success rate (completed / started) | 99% or higher | Ongoing from launch |
| 4 | Export completion time, p95, for up to 5,000 invoices | 30s or less | At launch |
- TBD: the definition of "active account". Suggestion: at least one invoice created or sent in the last 30 days.
- TBD: the ticket baseline. Confirm the 40/month figure comes from a tagged category, so the 70% reduction can be measured.
2. User Experience & Functionality
User Personas
- Finance Manager (primary): Works inside the app and owns invoicing. Needs to hand clean data to the accountant at month-end, quarter-end and year-end.
- External Accountant (secondary): Doesn't use the app. Needs a file they can import into their own tools, or one they can open directly.
User Stories and Acceptance Criteria
US-1. As a finance manager, I want to export invoices for a date range so that I can send them to my accountant.
- An "Export" action is available on the invoice list.
- The user can choose a date range and the export covers all matching invoices.
- The export includes at least these fields: invoice number, customer, issue date, due date, status, currency, subtotal, tax, total, amount paid, and line items. Assumption: the final field list is TBD with Finance.
- Export of 5,000 invoices or fewer completes in 30s or less at p95.
- Exports are limited to the requesting user's own account data. A cross-tenant test must confirm this.
US-2. As a finance manager, I want to filter what gets exported (status, customer, date) so that I send only what the accountant needs.
- The export respects the filters currently applied on the invoice list.
- The confirmation step shows the number of invoices to be exported before the user proceeds.
- An empty result shows a message and doesn't produce an empty file.
US-3. As a finance manager, I want to choose the file format so that it works with my accountant's tools.
- MVP formats (Assumption): CSV and PDF bundle (ZIP of invoice PDFs). TBD: confirm formats with 5 to 10 of the ticket requesters. Accounting-software formats such as QuickBooks or Xero are not in MVP.
- CSV is UTF-8 with a header row. Amounts use a fixed decimal format with an explicit currency column. It opens correctly in Excel and Google Sheets, including non-ASCII customer names.
- Every exported invoice PDF matches what the customer received.
US-4. As a finance manager, I want large exports to run in the background so that the app doesn't hang.
- Exports over 500 invoices (TBD threshold) run asynchronously.
- The user sees progress, and a download link appears in the app when the export is ready.
- A failed export shows a clear error and a retry option, and creates no partial download.
- Export files are available for 7 days (TBD), then deleted.
US-5. As a finance manager, I want to share an export with my accountant so that they don't need an account.
- The user can generate an expiring download link (default 7 days, revocable).
- The link requires no login but contains an unguessable token of at least 128 bits.
- The user can see and revoke active links.
- Each download via the link is logged with a timestamp.
US-6. As a finance manager, I want to see my past exports so that I can re-download without re-running them.
- An export history list shows date, filters, format, status and creator.
- Entries stay visible after the file expires, marked "Expired", with a "Re-run" action.
US-7. As an external accountant, I want a consistent, complete file so that I can reconcile without asking follow-up questions.
- Column names and order are identical across exports.
- Totals in the CSV reconcile to the sum of line items. This is checked by an automated test on a fixture set.
Non-Goals
- No AI features (per constraint).
- No direct integrations with accounting software (QuickBooks, Xero, etc.) or an accountant API.
- No accountant accounts or roles in MVP. Access is via expiring link only.
- No scheduled or recurring exports in MVP.
- No export of data other than invoices (customers, payments, reports).
- No custom column builder or templates.
- No native mobile experience beyond the responsive web UI.
3. AI System Requirements
Not applicable. This feature has no AI components.
4. Technical Specifications
Architecture Overview
Stack: Next.js web app, Postgres. Anything beyond that is TBD, including hosting, queue, and file storage.
Data flow
- The user selects filters and format in the UI, which calls an export API route.
- The API validates the request, checks authorization and tenant scope, and inserts a row into an
exportstable (statusqueued). - A background worker picks up the job, streams invoices from Postgres in batches (cursor-based, to bound memory), and writes the CSV or ZIP to object storage.
- The worker updates the row to
completeorfailed. The UI polls the status endpoint. - Download goes through an authenticated endpoint, or through a tokenized share link that resolves to a short-lived signed URL.
Components
exportstable: id, account_id, created_by, filters (JSONB), format, status, row_count, file_key, error, expires_at, created_at.export_share_linkstable: id, export_id, token_hash, expires_at, revoked_at, last_downloaded_at.- Worker: TBD on the mechanism. Options are a Postgres-backed job queue (for example
pg-boss) or the existing job system, if there is one. A Postgres-backed queue fits a two-engineer team with no new infrastructure. - Object storage for generated files: TBD on provider.
Integration Points
- Postgres: read from invoices and line-item tables, with indexes supporting account + date + status filters. Verify query plans against a realistic dataset.
- Auth: reuse existing session auth and role checks. TBD: which roles may export. Suggestion: finance manager and admin.
- PDF rendering: reuse the existing invoice PDF generator if one exists. TBD: confirm.
- Support tooling: the ticket category or tag for export requests must exist so KPI 1 can be measured.
- Analytics: events for
export_started,export_completed,export_failed,share_link_createdandshare_link_downloaded.
Security & Privacy
- Enforce tenant isolation on every query with
account_idscoping, and cover it with automated tests. - Share-link tokens are random, stored hashed, expiring and revocable. Files are served via signed URLs with short TTLs. Files are encrypted at rest.
- Invoices contain customer PII and financial data. Exports and downloads are audit-logged (who, when, which filters, which IP).
- Mitigate CSV formula injection: prefix cells starting with
=,+,-or@with a single quote. - Rate-limit export creation (TBD limit) to protect the database.
- TBD: compliance requirements (GDPR, SOC 2, regional tax-retention rules) and data residency for stored files. Legal or security review is needed before launch.
5. Risks & Roadmap
Phased Rollout
Plan assumes two engineers over 6 weeks.
MVP (weeks 1 to 4)
- CSV export with filters, synchronous for small sets and async for large ones.
- Export history and authenticated download.
- Analytics events and the ticket tag.
v1.1 (weeks 5 to 6, launch)
- PDF ZIP bundle.
- Expiring share links for accountants, with revoke and audit logging.
- Internal beta with 5 to 10 accounts from recent tickets, then staged rollout behind a feature flag.
- Support macro and help-center article.
v2.0 (post-launch, unscheduled)
- Accounting-software formats and integrations.
- Scheduled and recurring exports.
- Accountant accounts and roles.
- Export of payments and customers.
Rough week plan: week 1 covers spec lock, field and format confirmation, schema and queue. Weeks 2 to 3 cover the CSV pipeline and UI. Week 4 covers history and download. Week 5 covers PDF bundle and share links. Week 6 covers hardening, beta and rollout.
Technical Risks
| Risk | Impact | Mitigation |
|---|---|---|
| Formats and fields don't match what accountants need | Tickets don't drop; KPI 1 missed | Review ticket content and test a sample CSV with 3 to 5 accountants in week 1 |
| Large exports slow down the shared Postgres | Degraded app performance | Cursor batching, read replica if available (TBD), rate limits, load test at 50k invoices |
| PDF bundle generation is slow or memory-heavy | Timeouts, failed jobs | Stream into the ZIP, cap invoices per bundle (TBD), move to v1.1 or cut if behind schedule |
| Share links leak sensitive data | Security incident | Hashed tokens, short expiry, revocation, audit log, security review |
| Scope creep on formats or integrations | Missed 6-week deadline | Non-goals above. Share links and PDF are the first cuts if schedule slips |
| Unclear "active account" or ticket baseline | KPIs can't be measured | Define both before launch and instrument from day one |
| Worker infrastructure is unfamiliar to the team | Delays | Choose a Postgres-backed queue and prototype it in week 1 |
Open Questions
- Which export formats do accountants actually request in the tickets: CSV, PDF, or something else?
- How is "active account" defined?
- Is there an existing background-job system and PDF generator to reuse?
- Which roles may export, and are there compliance or retention requirements?
- Is the share-link flow essential for MVP, or acceptable at v1.1 as scheduled?
I'd like your feedback on three sections in particular: the format and field assumptions in US-1 and US-3, the share-link scope in US-5, and the week plan. Would you like me to save this to a file such as docs/prd-invoice-export.md once you've settled those?
Real run in an isolated folder with only this skill installed. Only the Skill and Read tools were enabled, so nothing was fetched from the web and no file was written. The example is fictional. The discovery answers were supplied in the request; the skill otherwise asks clarifying questions first.
它做什么
为软件功能和 AI 功能生成结构化的 PRD。它坚持先做需求访谈,再按严格结构撰写:执行摘要(问题、方案、三到五个可衡量的成功标准)、用户体验与功能(用户画像、用户故事、验收标准、非目标)、相关时的 AI 系统需求(工具、评估方法)、技术规格(架构、集成点、安全与隐私)以及风险和分阶段上线计划。它要求用具体、可测试的表述,而不是“很快”“很简单”。
工作方式
- 模型先就核心问题、成功指标和约束向你提问,写之前至少问两个澄清问题。
- 梳理用户流程、依赖关系和非目标。
- 起草文档,把你没说明的内容标为 TBD 或假设,并就具体章节征求反馈。
适合什么场景
启动新功能、把模糊的想法变成规格说明,以及给各方一份统一的事实依据。
纯指令文件:没有脚本,不联网、不写文件、不需要账号。Skill 要求先提澄清问题,并把没说明的约束标为 TBD 而不是自行编造,但草稿里仍可能含有假设,分享前请检查每一条需求、指标和技术选择。它自己不会保存任何东西,需要文件的话请告诉它存到哪里。