Skip to content

refactor(billing): extract transaction reporting into its own service - #3499

Merged
ygrishajev merged 1 commit into
mainfrom
refactor/billing-transaction-reporting-service
Jul 22, 2026
Merged

refactor(billing): extract transaction reporting into its own service#3499
ygrishajev merged 1 commit into
mainfrom
refactor/billing-transaction-reporting-service

Conversation

@ygrishajev

@ygrishajev ygrishajev commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Why

StripeService is still a god object — charging cards, coupons, customers, payment methods, and transaction reporting all live in one class. Reporting (listing a customer's charges for the UI, streaming the CSV export) is a self-contained concern with its own dependencies — csv-stringify, a paging generator, timezone/CSV formatting — that has nothing to do with taking a payment.

This PR carves reporting out into a dedicated TransactionReportingService. StripeService sheds ~200 lines and its CSV/stream imports; reporting gets a single-responsibility, independently testable home. It's a pure move — no behavior changes — and the next step in the layered StripeService split.

Closes CON-721 · Part of CON-718. Stacked on #3498 (the StripeService injected-client refactor) — review and merge that first; this PR's diff should be read on top of it.

What

apps/api — behavior-preserving, no new runtime behavior, no migrations.

  • Adds TransactionReportingService (injected STRIPE_CLIENT + StripeTransactionRepository + logger). It owns getCustomerTransactions and exportTransactionsCsvStream, plus their private helpers (paging generator, CSV-row transform, timezone normalization, CSV-injection sanitization) — all moved verbatim from StripeService.
  • StripeController now delegates the two reporting endpoints to TransactionReportingService; every other endpoint still goes through StripeService.
  • StripeService drops the six reporting methods and the now-dead csv-stringify / stream / Transaction / TransactionCsvRow imports.
  • The reporting tests move from stripe.service spec into a new transaction-reporting.service spec, unchanged.

Verification

  • Full billing unit suite green — 357 tests / 27 files (reporting tests relocated, not lost: the 15 moved tests now live in the new spec).
  • tsc: no new errors in the changed files (pre-existing apps/api baseline unchanged).
  • Prettier clean. Lint (ESLint v9 flat config) and integration tests run in CI.

Summary by CodeRabbit

  • New Features
    • Added transaction reporting service with pagination and date filtering.
    • Added streaming CSV export for customer transactions with timezone conversion, bonus amounts, receipt links, and status.
  • Bug Fixes
    • Improved payment-method normalization in transaction results (handles null/missing details) and safer CSV description formatting.
  • Tests
    • Added/updated coverage for transaction shaping, Stripe pagination/date wiring, bonus attachment, and CSV streaming (empty and error scenarios).

@ygrishajev
ygrishajev requested a review from a team as a code owner July 21, 2026 16:25
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 89a42b20-62d8-47d0-a095-5ac7825f094f

📥 Commits

Reviewing files that changed from the base of the PR and between 06f85e2 and 3de4313.

📒 Files selected for processing (6)
  • apps/api/src/billing/controllers/stripe/stripe.controller.spec.ts
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
  • apps/api/src/billing/services/stripe/stripe.service.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.spec.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.spec.ts
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
  • apps/api/src/billing/services/stripe/stripe.service.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.ts

📝 Walkthrough

Walkthrough

Transaction reporting is extracted from StripeService into TransactionReportingService. The controller delegates transaction listing and CSV export to the new service, which adds bonus enrichment, pagination, timezone handling, CSV sanitization, streaming, and dedicated tests.

Changes

Transaction reporting extraction

Layer / File(s) Summary
Transaction reporting service
apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.ts, apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.spec.ts
Adds paginated transaction retrieval, bonus enrichment, CSV streaming, timezone normalization, CSV sanitization, and comprehensive tests.
Controller delegation
apps/api/src/billing/controllers/stripe/stripe.controller.ts, apps/api/src/billing/controllers/stripe/stripe.controller.spec.ts
Injects TransactionReportingService and delegates transaction listing and CSV export endpoints to it.
Stripe service responsibility removal
apps/api/src/billing/services/stripe/stripe.service.ts, apps/api/src/billing/services/stripe/stripe.service.spec.ts
Removes transaction retrieval and CSV export methods, related imports, and their Stripe service tests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/billing-transaction-reporting-service

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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

Base automatically changed from refactor/billing-stripe-client-composition to main July 22, 2026 08:59
@ygrishajev
ygrishajev force-pushed the refactor/billing-transaction-reporting-service branch from 2911f99 to 402d42a Compare July 22, 2026 09:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/api/src/billing/services/stripe/stripe.service.ts (1)

13-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use a type-only import. PaymentIntentResult is only used in type positions here, so switch to import type to keep the import list consistent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/api/src/billing/services/stripe/stripe.service.ts` at line 13, Change
the PaymentIntentResult import in stripe.service.ts to a type-only import,
preserving its existing module and usage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.ts`:
- Around line 73-78: Update the transaction-reporting return object so nextPage
is null unless charges.has_more is true, and coalesce the selected cursor IDs to
null when charges.data is empty. Preserve prevPage’s existing startingAfter
condition while ensuring both pagination fields always satisfy the
string-or-null contract.
- Around line 146-162: Update the catch block in the transaction-reporting
generator to stop exposing `(error as Error).message` in the streamed CSV. Keep
detailed error logging in `loggerService.error`, and emit a generic error
identifier through `sanitizeForCsv` (or the established sanitized-row path) so
internal details are hidden and CSV formula injection is prevented; preserve the
existing empty fields and `hasMore = false` behavior.

---

Nitpick comments:
In `@apps/api/src/billing/services/stripe/stripe.service.ts`:
- Line 13: Change the PaymentIntentResult import in stripe.service.ts to a
type-only import, preserving its existing module and usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fc9bece9-55e7-4621-8d47-9b80fa3be916

📥 Commits

Reviewing files that changed from the base of the PR and between a874395 and 402d42a.

📒 Files selected for processing (6)
  • apps/api/src/billing/controllers/stripe/stripe.controller.spec.ts
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
  • apps/api/src/billing/services/stripe/stripe.service.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.spec.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.ts

@ygrishajev
ygrishajev force-pushed the refactor/billing-transaction-reporting-service branch from 402d42a to 06f85e2 Compare July 22, 2026 09:43
@ygrishajev
ygrishajev enabled auto-merge July 22, 2026 09:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/api/src/billing/controllers/stripe/stripe.controller.spec.ts`:
- Around line 405-406: Update setup() to include the existing
transactionReporting mock in its returned fixtures object, alongside the other
injected dependencies, so tests can configure
getCustomerTransactions/exportTransactionsCsvStream and verify calls.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ea2d7258-58e1-4fe0-8ae9-701baaf9ee6a

📥 Commits

Reviewing files that changed from the base of the PR and between 402d42a and 06f85e2.

📒 Files selected for processing (6)
  • apps/api/src/billing/controllers/stripe/stripe.controller.spec.ts
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
  • apps/api/src/billing/services/stripe/stripe.service.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.spec.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/api/src/billing/controllers/stripe/stripe.controller.ts
  • apps/api/src/billing/services/stripe/stripe.service.spec.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.spec.ts
  • apps/api/src/billing/services/stripe/stripe.service.ts
  • apps/api/src/billing/services/transaction-reporting/transaction-reporting.service.ts

Comment thread apps/api/src/billing/controllers/stripe/stripe.controller.spec.ts
@ygrishajev
ygrishajev disabled auto-merge July 22, 2026 11:48
@ygrishajev ygrishajev closed this Jul 22, 2026
@ygrishajev ygrishajev reopened this Jul 22, 2026
@ygrishajev
ygrishajev enabled auto-merge July 22, 2026 15:01
@ygrishajev
ygrishajev force-pushed the refactor/billing-transaction-reporting-service branch from 06f85e2 to 6098af3 Compare July 22, 2026 15:15
Move getCustomerTransactions and the CSV export stream out of StripeService
into a dedicated TransactionReportingService, and delegate to it from the
controller. Behavior-preserving: the reporting tests move alongside the new
service and StripeService sheds its CSV/reporting dependencies.
@ygrishajev
ygrishajev force-pushed the refactor/billing-transaction-reporting-service branch from 6098af3 to 3de4313 Compare July 22, 2026 15:16
@ygrishajev
ygrishajev disabled auto-merge July 22, 2026 15:44
@ygrishajev
ygrishajev merged commit 149413b into main Jul 22, 2026
126 of 130 checks passed
@ygrishajev
ygrishajev deleted the refactor/billing-transaction-reporting-service branch July 22, 2026 15:44
@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.89189% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.42%. Comparing base (1b87163) to head (3de4313).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...saction-reporting/transaction-reporting.service.ts 94.28% 4 Missing ⚠️
...rc/billing/controllers/stripe/stripe.controller.ts 50.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3499   +/-   ##
=======================================
  Coverage   72.41%   72.42%           
=======================================
  Files        1044     1045    +1     
  Lines       27257    27264    +7     
  Branches     6956     6957    +1     
=======================================
+ Hits        19739    19746    +7     
  Misses       6622     6622           
  Partials      896      896           
Flag Coverage Δ *Carryforward flag
api 86.44% <91.89%> (+0.01%) ⬆️
deploy-web 62.85% <ø> (ø) Carriedforward from 1b87163
notifications 93.84% <ø> (ø) Carriedforward from 1b87163
provider-console 81.38% <ø> (ø) Carriedforward from 1b87163
provider-proxy 88.17% <ø> (ø) Carriedforward from 1b87163

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
.../api/src/billing/services/stripe/stripe.service.ts 80.99% <ø> (-2.02%) ⬇️
...rc/billing/controllers/stripe/stripe.controller.ts 68.26% <50.00%> (+0.30%) ⬆️
...saction-reporting/transaction-reporting.service.ts 94.28% <94.28%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants