Skip to content

feat(kit): add reporting currency setting#136

Merged
hyochan merged 8 commits into
mainfrom
codex/feat-kit-reporting-currency
May 7, 2026
Merged

feat(kit): add reporting currency setting#136
hyochan merged 8 commits into
mainfrom
codex/feat-kit-reporting-currency

Conversation

@hyochan

@hyochan hyochan commented May 7, 2026

Copy link
Copy Markdown
Member

Summary

  • add a project-level reporting currency setting for IAPKit projects
  • pin MRR and Analytics revenue totals to the reporting currency without cross-currency summing
  • show non-reporting currencies as excluded/per-currency breakdowns and document that IAPKit does not do FX conversion or payout reconciliation

Closes #135

Test plan

  • bun run --filter @hyodotdev/openiap-kit lint
  • bun run --filter @hyodotdev/openiap-kit format:check
  • bun run --filter @hyodotdev/openiap-kit test
  • bun run --filter @hyodotdev/openiap-kit smoke:server
  • bun audit:docs (advisory warnings only; no hard failures)

Summary by CodeRabbit

  • New Features

    • Added reporting currency support for projects—users can now set a default currency for headline metrics, with other currencies listed separately for transparency.
    • Dashboard MRR and analytics now display using the project's reporting currency, with excluded currencies clearly visible.
    • Added reporting currency configuration option in Project Settings.
  • Documentation

    • Updated analytics documentation to clarify currency handling and reporting currency behavior.

Add a project-level reporting currency and keep MRR/revenue totals pinned to that currency unless explicit FX conversion exists. Non-reporting currencies stay visible as excluded per-currency breakdowns.\n\nCloses #135
@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Rate limit exceeded

@hyochan has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 23 minutes and 47 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fa282cf4-a69b-4755-b7e7-22cee6191e99

📥 Commits

Reviewing files that changed from the base of the PR and between ca96a60 and d0f93a4.

📒 Files selected for processing (5)
  • packages/kit/convex/subscriptions/query.ts
  • packages/kit/src/lib/utils.test.ts
  • packages/kit/src/lib/utils.ts
  • packages/kit/src/pages/auth/organization/project/analytics.tsx
  • packages/kit/src/pages/auth/organization/project/settings.tsx
📝 Walkthrough

Walkthrough

Adds project-level reporting currency configuration with USD default. Backend normalizes MRR/revenue to the configured currency while tracking excluded currencies. UI allows currency selection in settings and distinguishes headline revenue (reporting currency) from chart visualization (user-selected currency) with explanatory callouts.

Changes

Configurable Reporting Currency Feature

Layer / File(s) Summary
Database Schema & Type Definitions
packages/kit/convex/schema.ts, packages/kit/convex/utils/currency.ts, packages/kit/src/lib/utils.ts, packages/kit/convex/subscriptions/query.ts
Projects table adds optional reportingCurrency: v.optional(v.string()) field. Currency validation pattern ^[A-Z]{3}$ and type MrrCurrencyEntry are established. Metrics response schema extends with reportingCurrency and excludedMrrByCurrency.
Currency Normalization & Validation
packages/kit/convex/utils/currency.ts, packages/kit/src/lib/utils.ts
DEFAULT_REPORTING_CURRENCY = "USD". Validators: isValidCurrencyCode, normalizeReportingCurrency (strict, throws on invalid), normalizeReportingCurrencyOrDefault (fallback to default). Frontend normalizeCurrencyCode and formatMicros(micros, {currency, compact, emptyWhenZero}) utilities added.
Query Logic & MRR Selection
packages/kit/convex/subscriptions/query.ts
selectReportingMrr helper derives headline MRR from project's normalized reporting currency and collects excluded per-currency entries. metricsSummary replaces "most-popular currency" selection with reporting-currency-pinned headline; missing projects default to DEFAULT_REPORTING_CURRENCY with empty MRR arrays.
Project Mutations
packages/kit/convex/projects/mutation.ts
createProject inserts reportingCurrency: DEFAULT_REPORTING_CURRENCY. updateProject gains optional reportingCurrency argument; if provided, validates/normalizes and patches the projects table.
Settings UI Form
packages/kit/src/pages/auth/organization/project/settings.tsx
New "Reporting currency" section with 3-letter ISO code input, live validation, change detection, and dedicated save handler calling updateProject. Form state syncs on project refetch; button disabled when saving/invalid/unchanged.
Analytics Dashboard
packages/kit/src/pages/auth/organization/project/analytics.tsx
Revenue pipeline split: revenueRows filters to user-selected currency (chart visualization), reportingRevenueRows filters to reportingCurrency (headline totals). Currency selector UI renders only when multiple currencies exist. Explanation callout lists excluded currencies and clarifies that headline totals are pinned to reporting currency. Platform card and chart formatting use formatMicros with reporting-currency option.
Subscriptions Page
packages/kit/src/pages/auth/organization/project/subscriptions.tsx
MRR card label now shows MRR (${reportingCurrency}). Display derives currency from metrics.reportingCurrency and formats via formatMicros. Conditional "excluded MRR" alert appears when metrics.excludedMrrByCurrency has entries, listing per-currency values and marking reporting currency as "included".
Tests & Documentation
packages/kit/convex/subscriptions/query.test.ts, packages/kit/src/lib/utils.test.ts, packages/kit/src/pages/docs/sections/analytics.tsx
selectReportingMrr tests verify headline MRR selection, zero-value fallback, and invalid-code handling. normalizeCurrencyCode and formatMicros utility tests cover trimming, validation, compact formatting, and zero suppression. Analytics docs clarify currency-keyed rollup rows, reporting-currency totals excluded from other-currency slices, and absence of FX conversion.

Sequence Diagrams

sequenceDiagram
  participant User
  participant SettingsUI as Settings Form
  participant API as updateProject
  participant Query as metricsSummary Query
  participant UI as Analytics/MRR Display
  User->>SettingsUI: enter "EUR" as reporting currency
  SettingsUI->>SettingsUI: validate pattern, trim/uppercase
  User->>SettingsUI: click "Save currency"
  SettingsUI->>API: updateProject({reportingCurrency: "EUR"})
  API->>API: normalizeReportingCurrency("EUR")
  API->>Query: fetch metrics with updated project
  Query->>Query: selectReportingMrr(mrrByCurrency, "EUR")
  Query-->>UI: {reportingCurrency: "EUR", mrrMicros: <EUR-value>, excludedMrrByCurrency: [{currency: "USD", ...}]}
  UI->>UI: formatMicros(mrrMicros, {currency: "EUR"})
  UI-->>User: MRR (EUR) €X.XX + excluded currencies list
Loading
sequenceDiagram
  participant ChartCurrency as User-Selected<br/>Chart Currency
  participant ReportingCurrency as Reporting<br/>Currency (USD)
  participant Analytics as Analytics<br/>Dashboard
  ChartCurrency->>Analytics: revenueRows filtered to selected currency
  ReportingCurrency->>Analytics: reportingRevenueRows filtered to USD
  Analytics->>Analytics: merge revenueSeries from chart currency
  Analytics->>Analytics: merge totals from reportingRevenueSeries
  Analytics-->>ChartCurrency: chart shows selected currency revenue
  Analytics-->>ReportingCurrency: headline totals show USD revenue
  Analytics-->>User: callout explains USD is pinned, other currencies excluded
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • hyodotdev/openiap#131: Related — both PRs modify analytics dashboard, metrics queries, and related UI; this PR adds reporting-currency normalization and multi-currency headline display to the infrastructure added by that PR.

Suggested labels

🎯 feature, openiap-kit

Poem

🐰 A rabbit hops through currency lands,
USD, EUR held in gentle hands,
Now reports stay stable, currencies clear,
Multi-currency chaos ends here!
With dashboards bright and totals true,
Analytics finally make sense for you. 🌍

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main feature being added: a reporting currency setting for the kit. It directly matches the primary objective in the changeset.
Linked Issues check ✅ Passed The pull request comprehensively addresses all coding requirements from issue #135: adds configurable reporting currency at project level, pins MRR/revenue to selected currency, preserves raw transaction currencies, and prevents automatic switching based on incoming orders.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the reporting currency feature: database schema, mutation/query updates, currency utilities, UI for currency selection/settings, analytics display, and documentation. No unrelated code modifications detected.

✏️ 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 codex/feat-kit-reporting-currency

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 gemini-code-assist 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.

Code Review

This pull request introduces a per-project 'reporting currency' setting to improve MRR and revenue analytics, ensuring that totals are calculated for a specific currency rather than summing across different currencies without FX conversion. The changes include schema updates, new validation logic, UI components for configuration and display, and updated documentation. The reviewer suggested consolidating redundant 'formatMicros' utility functions across the codebase to improve maintainability and address a minor formatting bug.

Comment thread packages/kit/src/pages/auth/organization/project/subscriptions.tsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a project-level “reporting currency” to stabilize how Kit presents MRR and revenue analytics in multi-currency projects, avoiding cross-currency summing and making excluded currencies explicit.

Changes:

  • Introduces projects.reportingCurrency (schema + create/update mutations) and normalizes/validates it on write.
  • Updates subscription metrics aggregation to compute headline MRR strictly in the reporting currency and return excluded per-currency MRR.
  • Updates Kit UI + docs to surface the reporting currency setting and communicate excluded-currency behavior.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/kit/src/pages/docs/sections/analytics.tsx Updates analytics docs to describe reporting currency behavior and lack of FX conversion.
packages/kit/src/pages/auth/organization/project/subscriptions.tsx Displays MRR labeled by reporting currency and shows an excluded-currency breakdown.
packages/kit/src/pages/auth/organization/project/settings.tsx Adds a Project Settings form to set/report the reporting currency (ISO 4217).
packages/kit/src/pages/auth/organization/project/analytics.tsx Defaults analytics currency selection to reporting currency and shows excluded-currency messaging.
packages/kit/convex/subscriptions/query.ts Computes headline MRR in reporting currency; returns excluded per-currency MRR.
packages/kit/convex/subscriptions/query.test.ts Adds unit tests for reporting-currency MRR selection logic.
packages/kit/convex/schema.ts Adds optional reportingCurrency to the projects table and updates currency-related commentary.
packages/kit/convex/projects/mutation.ts Sets default reporting currency on project creation and validates it on update.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/kit/src/pages/auth/organization/project/analytics.tsx Outdated
Comment thread packages/kit/src/pages/auth/organization/project/subscriptions.tsx Outdated
@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a reporting currency setting for projects to ensure MRR and revenue totals are pinned to a specific currency, avoiding automatic FX conversion. Changes span the schema, backend validation, and UI, including new utility functions for currency formatting. Reviewers recommended removing redundant normalization logic in the subscription query and centralizing duplicated currency constants into a shared utility file to improve maintainability.

Comment thread packages/kit/convex/subscriptions/query.ts
Comment thread packages/kit/src/pages/auth/organization/project/settings.tsx Outdated
@hyochan hyochan requested a review from Copilot May 7, 2026 14:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Comment thread packages/kit/src/pages/auth/organization/project/analytics.tsx Outdated
Comment thread packages/kit/src/pages/auth/organization/project/analytics.tsx
Comment thread packages/kit/convex/subscriptions/query.ts
Comment thread packages/kit/src/pages/auth/organization/project/settings.tsx
Comment thread packages/kit/convex/subscriptions/query.ts Outdated
Comment thread packages/kit/convex/subscriptions/query.ts Outdated
@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a 'reporting currency' feature, allowing projects to specify a primary currency for dashboard analytics. Key changes include schema updates to the projects table, new validation and normalization utilities for currency codes, and UI enhancements in the analytics, subscriptions, and settings pages to handle and display reporting-specific totals. The feedback suggests extracting the currency validation regex into a shared utility function within the Convex backend to reduce code duplication.

Comment thread packages/kit/convex/subscriptions/query.ts Outdated
@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a project-level reporting currency setting to ensure consistent MRR and revenue displays in the dashboard. It moves currency normalization and formatting logic into shared utilities, adds a new configuration UI in the project settings, and updates the analytics and subscription views to explicitly separate reporting currency totals from other currency slices. Feedback includes a suggestion to improve rounding in compact currency formatting and a recommendation to avoid positional indexing when joining metrics series to ensure data integrity.

Comment thread packages/kit/src/lib/utils.ts
Comment thread packages/kit/src/pages/auth/organization/project/analytics.tsx Outdated
@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a reporting currency configuration for projects, allowing users to specify a primary currency for MRR and revenue reporting. The changes include backend updates to handle currency normalization and filtering, new UI components in project settings for configuration, and updates to the analytics and subscription dashboards to display metrics pinned to the project's reporting currency. Documentation has also been updated to reflect these changes. I have no feedback to provide as there were no review comments.

@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 (5)
packages/kit/src/lib/utils.ts (1)

23-34: ⚡ Quick win

Extract the formatMicros options to a named interface per coding guidelines.

The inline anonymous object type for the options parameter doesn't comply with the project-wide rule to prefer named interfaces for object shapes.

♻️ Proposed refactor
+export interface FormatMicrosOptions {
+  currency?: string | null;
+  compact?: boolean;
+  emptyWhenZero?: boolean;
+}
+
 export function formatMicros(
   micros: number,
-  {
-    currency,
-    compact = false,
-    emptyWhenZero = false,
-  }: {
-    currency?: string | null;
-    compact?: boolean;
-    emptyWhenZero?: boolean;
-  } = {},
+  {
+    currency,
+    compact = false,
+    emptyWhenZero = false,
+  }: FormatMicrosOptions = {},
 ): string {

As per coding guidelines: "Prefer interface for defining object shapes in TypeScript".

🤖 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 `@packages/kit/src/lib/utils.ts` around lines 23 - 34, The options object type
for formatMicros is currently an inline anonymous type; extract it to a named
exported interface (e.g., FormatMicrosOptions) and replace the inline type in
the formatMicros signature with that interface, preserving the same optional
properties (currency?: string | null, compact?: boolean, emptyWhenZero?:
boolean) and default parameter value handling; update any imports/exports so the
new interface is exported if used externally and ensure callers continue to work
without code changes.
packages/kit/src/lib/utils.test.ts (1)

5-13: ⚡ Quick win

Add coverage for null and undefined inputs to normalizeCurrencyCode.

The function signature explicitly accepts string | null | undefined, but neither branch is exercised by the current tests. The fallback-without-explicit-argument path (relying on DEFAULT_REPORTING_CURRENCY) is also untested.

✅ Suggested additional test cases
   it("falls back when the currency code is invalid", () => {
     expect(normalizeCurrencyCode("usdollar", "EUR")).toBe("EUR");
   });
+
+  it("falls back to DEFAULT_REPORTING_CURRENCY when input is null", () => {
+    expect(normalizeCurrencyCode(null)).toBe("USD");
+  });
+
+  it("falls back to DEFAULT_REPORTING_CURRENCY when input is undefined", () => {
+    expect(normalizeCurrencyCode(undefined)).toBe("USD");
+  });
 });

As per coding guidelines: "Write unit tests for all utility functions and business logic".

🤖 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 `@packages/kit/src/lib/utils.test.ts` around lines 5 - 13, Add unit tests for
normalizeCurrencyCode to cover null and undefined inputs and the
default-fallback path: write tests that call normalizeCurrencyCode(null) and
normalizeCurrencyCode(undefined) asserting they return the provided fallback or
DEFAULT_REPORTING_CURRENCY when no fallback arg is passed, and add a test that
calls normalizeCurrencyCode(undefined, "GBP") to verify explicit fallback
behavior; reference the normalizeCurrencyCode function and
DEFAULT_REPORTING_CURRENCY constant in your new test cases.
packages/kit/src/pages/auth/organization/project/analytics.tsx (2)

570-579: 💤 Low value

Minor: callout copy can be confusing when the chart currency equals the reporting currency.

When currency === reportingCurrency, the callout reads roughly: "Headline revenue totals are pinned to USD. EUR, JPY are excluded from headline totals…". That reads fine. But when the user picks a non-reporting currency (e.g. EUR) for the chart, EUR is the chart currency yet still appears in excludedReportingCurrencies — so the message says "The revenue chart is showing EUR. EUR, JPY are excluded from headline totals…", which is technically accurate but feels self-contradictory at a glance.

Consider listing only currencies other than both reportingCurrency and the active chart currency in the excluded label, or rewording to "headline totals only include {reportingCurrency}; EUR and JPY are not converted" so the chart currency call-out and the excluded list don't appear to fight.

🤖 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 `@packages/kit/src/pages/auth/organization/project/analytics.tsx` around lines
570 - 579, The callout should not list the active chart currency as an
"excluded" currency; update the JSX block that references
excludedReportingCurrencies/currency/reportingCurrency so it computes a filtered
list (e.g., filteredExcluded = excludedReportingCurrencies.filter(c => c !==
reportingCurrency && c !== currency)) and use filteredExcluded for the displayed
list and pluralization logic, while keeping the existing conditional that shows
"The revenue chart is showing {currency}." only when currency !==
reportingCurrency; this ensures the excluded list and the chart-currency
sentence don't contradict each other.

614-640: 💤 Low value

Minor: dead-falsy branches now that currency always resolves.

currency is now always a truthy string (it falls back to reportingCurrency), so currency ? · ${currency} : "" (Line 617) and currency || undefined (Line 558) can never take the empty path. Not a functional bug — just leftover defensiveness from the earlier nullable model that adds a bit of noise.

🤖 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 `@packages/kit/src/pages/auth/organization/project/analytics.tsx` around lines
614 - 640, The subtitle string construction on ChartCard (title "Revenue") still
uses a redundant ternary `currency ? \` · ${currency}\` : ""`; replace it with a
simple interpolation that always appends ` · ${currency}` (or build the subtitle
using currency directly) since currency is always a truthy string; likewise
simplify any other redundant guards like `currency || undefined` elsewhere in
this file (e.g., where passed into Tooltip/formatters or props) to just pass
`currency` to remove dead-falsy branches while preserving the same runtime
behavior.
packages/kit/convex/subscriptions/query.ts (1)

335-335: 💤 Low value

Minor: double normalization of reportingCurrency.

reportingCurrencyForProject(project) (Line 335) already calls normalizeReportingCurrencyOrDefault, and selectReportingMrr re-normalizes its reportingCurrency argument internally (Line 90-91). The work is idempotent, so this is purely cosmetic. If selectReportingMrr is intended as a standalone exported API (as the test file suggests), the inner normalization is the right place to keep it — at which point the redundant reportingCurrencyForProject helper inside this file mostly exists to give the local variable a name. Worth considering inlining or dropping the helper.

Also applies to: 466-466

🤖 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 `@packages/kit/convex/subscriptions/query.ts` at line 335, The code
double-normalizes reportingCurrency: reportingCurrencyForProject(project)
already calls normalizeReportingCurrencyOrDefault and selectReportingMrr also
normalizes its input; keep normalization inside selectReportingMrr and remove
the redundant outer normalization at the call sites (replace uses of
reportingCurrencyForProject(project) with the raw project.reportingCurrency or
pass project.reportingCurrency directly into selectReportingMrr), and make the
same change for the other occurrence mentioned; adjust or remove the
reportingCurrency local variable so callers no longer pre-normalize before
calling selectReportingMrr.
🤖 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 `@packages/kit/convex/subscriptions/query.ts`:
- Around line 80-103: Convert the exported MrrCurrencyEntry type alias to an
exported interface (interface MrrCurrencyEntry { currency: string; mrrMicros:
number; }) and add JSDoc above the exported selectReportingMrr function
documenting parameters and return shape, including that reportingCurrency is
normalized via normalizeReportingCurrencyOrDefault, that a missing match yields
mrrMicros = 0, and that non-reporting entries are returned in
excludedMrrByCurrency; ensure the JSDoc names the returned fields (currency,
mrrMicros, excludedMrrByCurrency) and describes their semantics.

In `@packages/kit/src/pages/auth/organization/project/settings.tsx`:
- Around line 718-734: The input lacks an aria-describedby linking it to the
error message, so add an id for the error node (e.g., reportingCurrencyErrorId)
and set the input's aria-describedby to that id only when
isReportingCurrencyValid is false; update the <p> error element to include that
id and ensure the input retains aria-invalid={!isReportingCurrencyValid} and
other props (use the existing reportingCurrency state, setReportingCurrency
handler, and isReportingCurrencyValid flag to control when the aria-describedby
is present).

---

Nitpick comments:
In `@packages/kit/convex/subscriptions/query.ts`:
- Line 335: The code double-normalizes reportingCurrency:
reportingCurrencyForProject(project) already calls
normalizeReportingCurrencyOrDefault and selectReportingMrr also normalizes its
input; keep normalization inside selectReportingMrr and remove the redundant
outer normalization at the call sites (replace uses of
reportingCurrencyForProject(project) with the raw project.reportingCurrency or
pass project.reportingCurrency directly into selectReportingMrr), and make the
same change for the other occurrence mentioned; adjust or remove the
reportingCurrency local variable so callers no longer pre-normalize before
calling selectReportingMrr.

In `@packages/kit/src/lib/utils.test.ts`:
- Around line 5-13: Add unit tests for normalizeCurrencyCode to cover null and
undefined inputs and the default-fallback path: write tests that call
normalizeCurrencyCode(null) and normalizeCurrencyCode(undefined) asserting they
return the provided fallback or DEFAULT_REPORTING_CURRENCY when no fallback arg
is passed, and add a test that calls normalizeCurrencyCode(undefined, "GBP") to
verify explicit fallback behavior; reference the normalizeCurrencyCode function
and DEFAULT_REPORTING_CURRENCY constant in your new test cases.

In `@packages/kit/src/lib/utils.ts`:
- Around line 23-34: The options object type for formatMicros is currently an
inline anonymous type; extract it to a named exported interface (e.g.,
FormatMicrosOptions) and replace the inline type in the formatMicros signature
with that interface, preserving the same optional properties (currency?: string
| null, compact?: boolean, emptyWhenZero?: boolean) and default parameter value
handling; update any imports/exports so the new interface is exported if used
externally and ensure callers continue to work without code changes.

In `@packages/kit/src/pages/auth/organization/project/analytics.tsx`:
- Around line 570-579: The callout should not list the active chart currency as
an "excluded" currency; update the JSX block that references
excludedReportingCurrencies/currency/reportingCurrency so it computes a filtered
list (e.g., filteredExcluded = excludedReportingCurrencies.filter(c => c !==
reportingCurrency && c !== currency)) and use filteredExcluded for the displayed
list and pluralization logic, while keeping the existing conditional that shows
"The revenue chart is showing {currency}." only when currency !==
reportingCurrency; this ensures the excluded list and the chart-currency
sentence don't contradict each other.
- Around line 614-640: The subtitle string construction on ChartCard (title
"Revenue") still uses a redundant ternary `currency ? \` · ${currency}\` : ""`;
replace it with a simple interpolation that always appends ` · ${currency}` (or
build the subtitle using currency directly) since currency is always a truthy
string; likewise simplify any other redundant guards like `currency ||
undefined` elsewhere in this file (e.g., where passed into Tooltip/formatters or
props) to just pass `currency` to remove dead-falsy branches while preserving
the same runtime behavior.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3582773c-b131-47f3-925c-65671e26fbf6

📥 Commits

Reviewing files that changed from the base of the PR and between 2f2548a and ca96a60.

📒 Files selected for processing (11)
  • packages/kit/convex/projects/mutation.ts
  • packages/kit/convex/schema.ts
  • packages/kit/convex/subscriptions/query.test.ts
  • packages/kit/convex/subscriptions/query.ts
  • packages/kit/convex/utils/currency.ts
  • packages/kit/src/lib/utils.test.ts
  • packages/kit/src/lib/utils.ts
  • packages/kit/src/pages/auth/organization/project/analytics.tsx
  • packages/kit/src/pages/auth/organization/project/settings.tsx
  • packages/kit/src/pages/auth/organization/project/subscriptions.tsx
  • packages/kit/src/pages/docs/sections/analytics.tsx

Comment thread packages/kit/convex/subscriptions/query.ts Outdated
Comment thread packages/kit/src/pages/auth/organization/project/settings.tsx
@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a project-level reporting currency setting to ensure consistent MRR and revenue totals in the dashboard without performing automatic FX conversion. It includes updates to the Convex schema, mutations for project creation and updates, and utility functions for currency normalization and formatting. The analytics and subscription pages now default to the reporting currency while allowing users to explore other currency slices. A review comment suggests expanding the test coverage for the formatMicros utility to include values between 10 and 1000 when using compact formatting.

Comment thread packages/kit/src/lib/utils.test.ts
@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@hyochan

hyochan commented May 7, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini is experiencing higher than usual traffic and was unable to create the review. Please try again in a few hours by commenting /gemini review.

@hyochan hyochan merged commit 6bb94e3 into main May 7, 2026
10 checks passed
@hyochan hyochan deleted the codex/feat-kit-reporting-currency branch May 7, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🥺 feature request Request a new feature kit IAPKit (receipt-validation SaaS) 🧑‍🔬 analytics

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Add configurable reporting currency for MRR and revenue analytics

2 participants