POWorkspaceagentic kit · product owner
← All runs

Client-facing invoice export

Author backlog · innovation-group · po-55545711

completedcost $0.73659225Jira: KAN-155, KAN-156, KAN-157, KAN-158, KAN-159, KAN-160
[po-ticket-author running] Pipeline started — https://github.com/N-iX-GenAI-Value-LAB/observability-server/actions/runs/30472954741
[po-ticket-author running] Phase: discovery — restating intent, resolving open decisions
[${PO_DEFAULT_PIPELINE} running] discovery: Restating intent and resolving all open decisions for client-facing invoice export
[po-ticket-author running] Phase: story — decomposing into epics and sprint-sized stories with typed Jira fields
[${PO_DEFAULT_PIPELINE} running] story: Decomposing intent into epics and sprint-sized stories with typed Jira fields
[po-ticket-author running] Phase: ac — writing Given/When/Then acceptance criteria, linting backlog
[${PO_DEFAULT_PIPELINE} running] ac: Writing Given/When/Then acceptance criteria and linting backlog JSON
[${PO_DEFAULT_PIPELINE} completed] Created 6 stories across 4 epics (KAN-155–KAN-160) for client-facing invoice export: CSV/XLSX download, filter UX, 50k-row performance budget, and scheduled email delivery with failure notifications. 23 Given/When/Then AC bullets. Linter: 0 errors.

Backlog

Epic: Invoice Export — CSV & XLSX Download2 stories
  1. Export filtered invoices as CSV
    • Given I am an authenticated account manager on the client invoice page with at least one filtered invoice, When I click Export CSV, Then a GET /api/invoices/export?format=csv request is made, the server responds with HTTP 200, the Content-Disposition header contains attachment filename invoices_date.csv, and the browser initiates a file download.
    • Given the CSV export request completes successfully, When the downloaded file is opened, Then it contains a header row with columns Invoice #, Date, Due Date, Amount, Status, Client Name, and one data row per filtered invoice record.
    • Given I am an authenticated account manager, When I click Export CSV and the server returns HTTP 429, Then the Export CSV button is re-enabled within 200 ms and an inline message reads Export limit reached — try again in 1 minute.
    • Given I am an unauthenticated user, When I attempt GET /api/invoices/export, Then the server returns HTTP 401 and no file download is initiated.
  2. Export filtered invoices as XLSX
    • Given I am an authenticated account manager on the client invoice page with at least one filtered invoice, When I click Export XLSX, Then a GET /api/invoices/export?format=xlsx request is made, the server responds with HTTP 200, the Content-Disposition header contains attachment filename invoices_date.xlsx, and the browser initiates a file download.
    • Given the XLSX export request completes successfully, When the downloaded file is opened in a spreadsheet application, Then it contains a worksheet named Invoices with a header row and one data row per filtered invoice record.
    • Given I am an authenticated account manager, When I click Export XLSX and the server returns HTTP 500, Then the Export XLSX button is re-enabled and a toast notification reads Export failed — please try again.
Epic: Invoice Filter UX1 story
  1. Filter invoices by date range, status, and invoice number
    • Given I am an account manager on the client invoice page, When I set the start date and end date filter inputs and click Apply, Then the invoice table updates within 300 ms and shows only invoices where issue_date is within the specified range.
    • Given I am an account manager on the client invoice page, When I select status filter value Unpaid from the status dropdown, Then the invoice table updates within 300 ms and shows only invoices where status equals Unpaid.
    • Given I am an account manager on the client invoice page, When I type a partial string into the invoice number search field, Then the invoice table updates within 300 ms and shows only invoices where invoice_number contains the search string with case-insensitive matching.
    • Given I am an account manager with at least one active filter applied, When I click Clear Filters, Then all filter inputs reset to their empty default state and the invoice table shows all invoices for the client within 300 ms.
Epic: High-volume Export Performance1 story
  1. Large-dataset export completes within 5 seconds for up to 50000 rows
    • Given a client with exactly 50000 invoices matching the current filter, When I click Export CSV, Then the server begins streaming the response and time-to-first-byte measured from click event to browser receipt is at most 5000 ms.
    • Given a client with exactly 50000 invoices matching the current filter, When I click Export XLSX, Then the file download begins and time-to-first-byte measured from click event to browser receipt is at most 5000 ms.
    • Given a filtered result set contains more than 50000 rows, When I click Export CSV or Export XLSX, Then the exported file contains exactly the first 50000 rows and a warning banner appears on the page reading Export limited to 50000 rows — refine your filters to export the full dataset.
    • Given the export server encounters a timeout after 5000 ms before completing a response for fewer than 50000 rows, When the timeout fires, Then the server returns HTTP 504 and the client UI displays an inline message reading Export timed out — please narrow your filter range.
Epic: Scheduled Email Export Delivery2 stories
  1. Configure and manage scheduled invoice export email delivery
    • Given I am an account manager on a client invoice page, When I click Schedule Export, select frequency Weekly, delivery day Monday, delivery time 08:00, format CSV, enter recipient email am@company.com, and click Save, Then a POST /api/invoice-schedules request returns HTTP 201 and a confirmation message reads Weekly CSV export scheduled for Mondays at 08:00.
    • Given a scheduled export is active for a client, When the scheduled delivery time arrives, Then the server generates an export file containing all invoices for that client with no ad-hoc filters applied and sends one email per configured recipient with the export file attached.
    • Given an active scheduled export exists for a client, When I view that client invoice page, Then a Scheduled Export indicator is visible showing the frequency, the next delivery date formatted as YYYY-MM-DD, and the full list of recipient email addresses.
    • Given I am an account manager with an existing scheduled export, When I click Edit Schedule, change frequency to Monthly, and click Save, Then a PATCH /api/invoice-schedules/{id} request returns HTTP 200 and the schedule indicator updates to display Monthly as the frequency.
    • Given I am an account manager, When I click Delete Schedule and confirm the deletion in the modal, Then a DELETE /api/invoice-schedules/{id} request returns HTTP 200 and the schedule indicator is no longer present on the client invoice page.
  2. Receive dashboard notification when scheduled export delivery fails
    • Given a scheduled export email fails to send, When 3 delivery attempts have all failed with exponential backoff, Then the system persists an error log record with fields schedule_id, client_id, attempted_at, and error_message, and creates a notification record visible in the account manager dashboard notification panel.
    • Given a failed scheduled export notification is present in the notification panel, When I view the notification panel, Then the entry reads Scheduled export for ClientName on YYYY-MM-DD failed to deliver and includes a Retry button and a Dismiss button.
    • Given I click the Retry button on a failed export notification, When the retry export action is triggered, Then a new export and email attempt is initiated immediately and the notification status updates to Retrying with the Retry button disabled until the attempt resolves.