Skip to content

✨ server: support many cards in the statement#893

Open
nfmelendez wants to merge 1 commit intomainfrom
statement
Open

✨ server: support many cards in the statement#893
nfmelendez wants to merge 1 commit intomainfrom
statement

Conversation

@nfmelendez
Copy link
Copy Markdown
Contributor

@nfmelendez nfmelendez commented Mar 16, 2026

closes #880

Summary by CodeRabbit

  • New Features

    • Statements now support multiple cards with per-card purchase lists, per-card totals, and a separate payments section; exports (JSON/PDF) group purchases by card and include card identifiers (last four).
  • UI

    • Redesigned statement layout: account header, period and due dates, summary totals, per-card purchase tables, Payments section, and overall due balance with formatted currency.
  • Tests

    • Updated tests to cover multiple cards, purchases, and payments scenarios.

Open with Devin

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 16, 2026

🦋 Changeset detected

Latest commit: a0e9a6c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@exactly/server Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Switches statement generation from a single-card, item-centric model to a purchases-by-card model: Activity API now queries credential cards, attaches cardId to items, groups purchases per card and separates payments; Statement component and tests updated to accept/render account, multiple cards with purchases, maturity, and payments for JSON/PDF output.

Changes

Cohort / File(s) Summary
Changeset Entry
.changeset/soft-trains-dig.md
Adds a patch changeset for @exactly/server noting "✨ support multiple cards in statement".
Activity API
server/api/activity.ts
Replaces card-centric flow with purchases-based aggregation: queries credential cards (id, lastFour), builds hash→cardId lookup, injects cardId into response items, groups purchases by card, and extracts payments for statement construction (JSON and PDF).
Statement Component
server/utils/Statement.tsx
Public signature changed to accept account, cards[] (each with lastFour and purchases[]), maturity, and payments[]; adds currency/date formatting, per-card purchase tables, totals (totalSpent, totalPayments, dueBalance), and layout updates for multi-card rendering.
Tests / Fixtures
server/test/api/activity.test.ts, server/test/utils/statement.test.ts
Test seeds adjusted to two-card fixtures, purchases moved under each card, payments added; assertions updated for per-card headers, purchases listing, payments section, summary totals, and due balance text.
Other / Internal
server/...
PDF construction and internal data querying/aggregation refactored to use purchases-by-card grouping; statement JSON kept compatible but now includes per-card purchases and payments.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant API as Activity API
    participant DB as Database
    participant Statement as Statement Component
    participant Output as PDF/JSON Output

    Client->>API: Request statement (account, format)
    API->>DB: Query credential cards (id, lastFour)
    DB-->>API: Cards list
    API->>DB: Fetch transactions/items for account
    DB-->>API: Transactions/items
    API->>API: Build purchases (attach cardId, group by card)
    API->>API: Extract payments
    API->>Statement: Send account, cards[{lastFour,purchases[]}], maturity, payments
    Statement->>Statement: Compute totals, format dates/currency
    Statement->>Output: Render/serialize PDF or return JSON
    Output-->>Client: Statement (PDF or JSON)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • cruzdanilo
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main change: adding support for multiple cards in statement rendering, which is the core objective of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch statement

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enables the generation of comprehensive user statements that can include transactions from multiple cards. The changes involve updating the data retrieval process in the API to fetch all relevant card data and refactoring the PDF rendering component to display this multi-card information in a structured and user-friendly format. This enhancement provides users with a more complete overview of their financial activity across all their associated cards.

Highlights

  • Multi-Card Statement Support: The server-side logic and PDF generation for user statements have been updated to support displaying transactions from multiple cards within a single statement.
  • API Refactoring: The activity.ts API endpoint was refactored to correctly query and aggregate transaction data for all cards associated with a credential, removing a previous limitation to a single card for PDF statements.
  • Enhanced PDF Statement Layout: The Statement.tsx component was significantly redesigned to present a clear, organized view of purchases grouped by individual cards, along with a summary of total spending and payments.
  • Comprehensive Testing: API and statement rendering tests were expanded to include scenarios with multiple cards, ensuring the new functionality works as expected.
Changelog
  • .changeset/soft-trains-dig.md
    • Added a new changeset entry for multi-card statement support.
  • server/api/activity.ts
    • Modified the cards query to explicitly select id and lastFour.
    • Refactored the logic for fetching card purchases to support multiple cards and their associated transactions.
    • Updated the PDF generation to process and group purchases by card.
    • Removed the restriction that prevented PDF generation for statements with more than one card.
  • server/test/api/activity.test.ts
    • Added a second card to the test setup.
    • Updated transaction assignments to distribute them across multiple cards for testing.
  • server/test/utils/statement.test.ts
    • Updated existing test cases to match the new statement data structure.
    • Added a new test case to verify rendering of statements with multiple cards.
    • Modified assertions to reflect changes in the rendered PDF text.
  • server/utils/Statement.tsx
    • Updated the Statement component's props to accept account, an array of cards, maturity, and payments.
    • Implemented new rendering logic to display purchases grouped by individual cards.
    • Introduced a summary section for total spent and due balance.
    • Refactored date formatting functions.
    • Updated styling for a more structured and multi-card friendly layout.
Activity
  • The pull request was created by nfmelendez.
  • A new changeset file was added, indicating a patch release for @exactly/server.
  • The core logic for generating activity statements was updated to handle multiple cards.
  • Corresponding test files were modified to reflect and validate the new multi-card statement functionality.
  • The UI component responsible for rendering PDF statements was significantly refactored to display the new multi-card data structure.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

gemini-code-assist[bot]

This comment was marked as resolved.

@sentry
Copy link
Copy Markdown

sentry bot commented Mar 16, 2026

✅ All tests passed.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
server/utils/Statement.tsx (2)

99-111: 🧹 Nitpick | 🔵 Trivial

Duplicate cardTotal calculation; consider extracting.

The same cardTotal reduction appears at lines 100-103 and 125-127. Pre-compute card totals once to avoid duplication and improve maintainability.

♻️ Suggested refactor
+  const cardsWithTotals = cards.map((card) => ({
+    ...card,
+    total: card.purchases.reduce((s, p) => s + p.installments.reduce((a, i) => a + i.amount, 0), 0),
+  }));
+  const totalSpent = cardsWithTotals.reduce((sum, card) => sum + card.total, 0);
-  const totalSpent = cards.reduce(
-    (sum, card) =>
-      sum +
-      card.purchases.reduce((s, p) => s + p.installments.reduce((a, installment) => a + installment.amount, 0), 0),
-    0,
-  );

Then use cardsWithTotals in both the summary and per-card sections, referencing card.total directly.

Also applies to: 124-128


105-105: ⚠️ Potential issue | 🟡 Minor

Consider a more unique React key.

Using card.lastFour as the key could cause issues if two cards share the same last four digits. Since the component doesn't receive a unique card ID, consider using the array index as a fallback:

-<View key={card.lastFour} style={styles.summaryRow}>
+<View key={`${card.lastFour}-${index}`} style={styles.summaryRow}>

Apply similarly at line 130.

Also applies to: 130-130


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 85ea069e-c24d-4dbc-919a-71cb4c2744bf

📥 Commits

Reviewing files that changed from the base of the PR and between cb5448d and ec562a5.

📒 Files selected for processing (5)
  • .changeset/soft-trains-dig.md
  • server/api/activity.ts
  • server/test/api/activity.test.ts
  • server/test/utils/statement.test.ts
  • server/utils/Statement.tsx

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
server/utils/Statement.tsx (1)

99-128: 🧹 Nitpick | 🔵 Trivial

Duplicate cardTotal calculation.

The same calculation appears at lines 100-103 (Summary section) and lines 125-128 (per-card section). Consider computing card totals once during initial data processing.

Additionally, using card.lastFour as the React key (lines 105, 130) could cause issues if two cards share the same last four digits.

♻️ Suggested refactor
+  const cardsWithTotals = cards.map((card) => ({
+    ...card,
+    total: card.purchases.reduce((s, p) => s + p.installments.reduce((a, i) => a + i.amount, 0), 0),
+  }));
+  const totalSpent = cardsWithTotals.reduce((sum, card) => sum + card.total, 0);
-  const totalSpent = cards.reduce(
-    (sum, card) =>
-      sum +
-      card.purchases.reduce((s, p) => s + p.installments.reduce((a, installment) => a + installment.amount, 0), 0),
-    0,
-  );

Then reference cardsWithTotals and card.total directly in both sections.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 17e1f6dc-adbd-449f-9f30-770174c13e19

📥 Commits

Reviewing files that changed from the base of the PR and between ec562a5 and a733910.

📒 Files selected for processing (5)
  • .changeset/soft-trains-dig.md
  • server/api/activity.ts
  • server/test/api/activity.test.ts
  • server/test/utils/statement.test.ts
  • server/utils/Statement.tsx

@cruzdanilo cruzdanilo marked this pull request as ready for review March 18, 2026 17:25
@cruzdanilo cruzdanilo self-requested a review as a code owner March 18, 2026 17:25
sentry[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

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.

server: uphold card statement

1 participant