Skip to content

Feat/1827 currency conversion implementation#2029

Open
DSanich wants to merge 4 commits intomainfrom
feat/1827-currency-conversion-implementation
Open

Feat/1827 currency conversion implementation#2029
DSanich wants to merge 4 commits intomainfrom
feat/1827-currency-conversion-implementation

Conversation

@DSanich
Copy link
Member

@DSanich DSanich commented Mar 20, 2026

Summary by CodeRabbit

  • New Features

    • Users can select and save a preferred currency in their profile.
    • Asset balances and portfolio totals display in the selected currency using live conversion rates (with safe fallback).
    • Token entries may show reference price and reference currency; token cards display a token price line when available.
    • Currency symbols and currency selector options are rendered dynamically.
  • Chores

    • Database schema updated to store user currency.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 20, 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

Walkthrough

Introduces multi-currency support: adds currency types/utilities, server-side USD→fiat conversion with caching, persists user currency, returns converted balances and token reference pricing in assets APIs, updates DB schema and UI/hooks to surface and format chosen currencies.

Changes

Cohort / File(s) Summary
Currency Core
packages/core/src/common/currency.ts, packages/core/src/common/index.ts
New currency constants, types, symbol lookup, helpers (isSupportedCurrency, resolveSupportedCurrency, getCurrencySymbol) and re-exported from common index.
Fiat Conversion Service
packages/core/src/common/server/get-fiat-conversion-rate.ts, packages/core/src/common/server/index.ts
New server utility to fetch USD→fiat rates from CoinGecko with in-memory caching; returns rate=1 for USD and falls back to USD on errors.
Assets APIs
apps/web/src/app/api/v1/people/[personSlug]/assets/route.ts, apps/web/src/app/api/v1/spaces/[spaceSlug]/assets/route.ts
Auth-aware currency selection, fetches user self when available, obtains USD→fiat rate, computes usdBalance and returns balance: usdBalance * rate plus currency; normalizes token referencePrice/referenceCurrency.
Token Metadata
packages/core/src/common/server/web3-rpc/get-token-meta.ts
Extended token metadata to include optional `referencePrice?: number
People Model & Validation
packages/core/src/people/types.ts, packages/core/src/people/validation.ts, packages/core/src/people/server/queries.ts
Added optional currency to Person and edit input types, added validation (z.enum(SUPPORTED_CURRENCIES)), included currency in DB selections/mapping; made address lookups case-insensitive.
Database Migration & Schema
packages/storage-postgres/migrations/0041_rainy_green_goblin.sql, packages/storage-postgres/migrations/meta/0041_snapshot.json, packages/storage-postgres/migrations/meta/_journal.json, packages/storage-postgres/src/schema/people.ts
Added currency text column to people table, updated schema file and migration metadata snapshot/journal.
Treasury UI & Types
packages/epics/src/treasury/components/assets/asset-card.tsx, packages/epics/src/treasury/components/assets/assets-list.tsx, packages/epics/src/treasury/components/common/reference-currency-field.tsx
Asset types extended with reference fields; AssetCard renders token reference price/currency when present; reference currency select sourced from CURRENCY_OPTIONS.
People UI
packages/epics/src/people/components/edit-person-section.tsx
Added Currency select field in edit-person form, initialized via resolveSupportedCurrency(person?.currency).
Assets Hooks & Formatting
packages/epics/src/treasury/hooks/use-assets.ts, packages/epics/src/treasury/hooks/use-user-assets.ts, packages/epics/src/treasury/hooks/use-assets-section.ts, packages/epics/src/treasury/hooks/use-user-assets-section.ts
Hooks now surface currency (defaults to 'USD'); balance formatting uses getCurrencySymbol(currency) instead of hardcoded $; asset types include optional reference fields.
DB Connection Resolution
packages/core/src/common/server/get-db.ts, .github/workflows/deploy-preview.yml
Branch-aware DB URL resolution added (prefers branch-specific env vars, selects auth vs anonymous URL based on token); CI deploy-preview exports branch DB URLs for preview deploys.

Sequence Diagram

sequenceDiagram
    participant UI as Frontend
    participant API as Assets API
    participant DB as Database
    participant Cache as NodeCache
    participant CG as CoinGecko

    UI->>API: GET /api/v1/spaces/[slug]/assets?currency=EUR
    activate API
    API->>DB: findSelf(authToken) (optional)
    DB-->>API: user { currency?: "USD" } (or undefined)
    API->>Cache: get usd_to_eur
    alt cache miss
        API->>CG: GET /simple/price?ids=usd&vs_currencies=eur,...
        CG-->>API: { usd: { eur: 0.92, ... } }
        API->>Cache: set usd_to_eur = 0.92
    else cache hit
        Cache-->>API: 0.92
    end
    API->>API: compute usdBalance = sum(assets.usdEqual)
    API->>API: converted = usdBalance * rate
    API-->>UI: { balance: converted, currency: "EUR", assets: [...] }
    deactivate API
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

new feature, BE API

Suggested reviewers

  • sergey3bv
  • evgenibir

"I'm a rabbit with a ledger and a hop,
Coins in many lands make my whiskers pop,
From USD to Yen, I fetch the rate,
Balances bloom and look first-rate,
Hooray — currencies dance atop!" 🐇💸

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 accurately reflects the main objective of the changeset, which implements currency conversion functionality across the application.

✏️ 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 feat/1827-currency-conversion-implementation

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.

@github-actions
Copy link

Neon logo Neon Schema Diff summary

Schema diff between the compare branch (preview/pr-2029-feat/1827-currency-conversion-implementation) and the base branch (main).

Index: neondb-schema.sql
===================================================================
--- neondb-schema.sql	Branch main
+++ neondb-schema.sql	Branch preview/pr-2029-feat/1827-currency-conversion-implementation
@@ -403,9 +403,10 @@
     nickname text,
     sub text DEFAULT auth.user_id(),
     lead_image_url text,
     web3_address text,
-    links jsonb DEFAULT '[]'::jsonb NOT NULL
+    links jsonb DEFAULT '[]'::jsonb NOT NULL,
+    currency text
 );
 
 
 ALTER TABLE public.people OWNER TO neondb_owner;

This comment was last updated at Fri, 20 Mar 2026 14:10:18 GMT

Copy link
Contributor

@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.

Actionable comments posted: 2

🧹 Nitpick comments (4)
packages/epics/src/treasury/hooks/use-user-assets.ts (1)

32-57: Extract the asset payload shape into a shared type.

AssetItem/UseAssetsReturn now mirror fields that are also being threaded through server token metadata and asset display props. Pulling this into a common type will make the new currency/reference fields much less likely to drift out of sync.

Based on learnings: DSanich prefers extracting repeated type declarations into shared modules for reusability and maintainability, particularly for token types that are used across multiple files in the codebase.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/epics/src/treasury/hooks/use-user-assets.ts` around lines 32 - 57,
The AssetItem and UseAssetsReturn types are duplicated elsewhere; extract their
shape into a shared exported type (e.g., export type AssetItem and export type
UseAssetsReturn) in a common module and replace the local declarations in
use-user-assets.ts by importing those shared types; update all other places that
currently mirror these fields (server token metadata, asset display props, etc.)
to import and use the shared types so the new currency/reference fields
(referencePrice, referenceCurrency) and optional space fields remain consistent
across the codebase.
packages/storage-postgres/src/schema/people.ts (1)

19-19: Constrain people.currency at the schema layer too.

The app now validates this field against SUPPORTED_CURRENCIES, but the column still accepts arbitrary text. A DB enum or check constraint here would keep non-validated write paths from persisting unsupported currency codes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/storage-postgres/src/schema/people.ts` at line 19, The people.schema
currently defines currency as text('currency') allowing any string; add a
database-level constraint so only SUPPORTED_CURRENCIES are persisted—modify the
schema definition for the people table (the currency column) to use a DB enum
type or a CHECK constraint referencing the allowed currency codes (instead of
text('currency')) so writes that bypass app validation are rejected; update any
migration/DDL for the people table and ensure the enum/check uses the same
SUPPORTED_CURRENCIES set and that the column symbol named currency is
altered/created accordingly.
packages/epics/src/treasury/hooks/use-assets.ts (1)

46-47: Reuse the shared currency union in this hook contract.

The new currency-bearing fields are still plain strings, so consumers lose the type safety that the rest of this PR just centralized. Threading SupportedCurrency through here keeps the hook/API boundary aligned and makes impossible currency values a compile-time error.

♻️ Proposed type-only cleanup
+import type { SupportedCurrency } from '@hypha-platform/core/client';
+
 type AssetItem = {
   icon: string;
   name: string;
   symbol: string;
@@
-  referenceCurrency?: string | null;
+  referenceCurrency?: SupportedCurrency | null;
 };
@@
-  currency?: string;
+  currency?: SupportedCurrency;
 };
@@
-  currency: string;
+  currency: SupportedCurrency;
 };

Based on learnings, DSanich prefers extracting repeated type declarations into shared modules for reusability and maintainability, particularly for token types that are used across multiple files in the codebase.

Also applies to: 54-55, 61-62, 126-126

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/epics/src/treasury/hooks/use-assets.ts` around lines 46 - 47, Update
the hook's asset/type contract to use the shared SupportedCurrency union instead
of plain strings: replace any occurrences of referenceCurrency?: string | null
(and other currency-bearing fields in the same type/hook at the other spots
mentioned) with referenceCurrency?: SupportedCurrency | null (and analogous
fields), and add an import for SupportedCurrency from the shared types module;
ensure all references in useAssets/use-assets types and return types are updated
to preserve nullability and compile-time currency safety.
packages/core/src/common/currency.ts (1)

17-42: Derive labels and symbols from one metadata map.

SUPPORTED_CURRENCIES, CURRENCY_OPTIONS, and CURRENCY_SYMBOLS now repeat the same codes in three places. A single Record<SupportedCurrency, { label: string; symbol: string }> would let you derive both exports and prevent the options list from drifting the next time a currency is added or removed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/common/currency.ts` around lines 17 - 42, Create a single
source-of-truth map (e.g., CURRENCY_META: Record<SupportedCurrency, { label:
string; symbol: string }>) and replace the duplicated definitions by deriving
CURRENCY_OPTIONS and CURRENCY_SYMBOLS from that map; update code that references
SUPPORTED_CURRENCIES (if present) to use Object.keys/values from CURRENCY_META
(or build a SUPPORTED_CURRENCIES array from it) so additions/removals only
happen in one place and both CURRENCY_OPTIONS and CURRENCY_SYMBOLS are generated
from CURRENCY_META.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/common/server/get-fiat-conversion-rate.ts`:
- Around line 33-48: The request is using `ids=usd` which is likely not a valid
CoinGecko coin id; change the implementation in get-fiat-conversion-rate (file:
get-fiat-conversion-rate.ts) to call the CoinGecko /exchange_rates endpoint
instead of simple/price, parse the returned data.rates to find rates for the
normalized target currency and for "usd" (e.g., data.rates[normalizedCurrency]
and data.rates.usd), compute the conversion as targetRate / usdRate, and use
that as the rate; also surface/log any fetch or parse errors instead of silently
falling back to `{ currency: 'USD', rate: 1 }`.

In `@packages/storage-postgres/migrations/meta/0041_snapshot.json`:
- Around line 358-398: The migration snapshot defines row-level policies for the
table public.people (crud-authenticated-policy-select, -insert, -update,
-delete) but isRLSEnabled is false and the paired SQL migration
(0041_rainy_green_goblin.sql) does not enable RLS; update the SQL migration to
run ALTER TABLE public.people ENABLE ROW LEVEL SECURITY and ensure the migration
creates the four policies (or leaves policy creation in sync), and update the
snapshot's isRLSEnabled flag to true so the policies become effective for
public.people.

---

Nitpick comments:
In `@packages/core/src/common/currency.ts`:
- Around line 17-42: Create a single source-of-truth map (e.g., CURRENCY_META:
Record<SupportedCurrency, { label: string; symbol: string }>) and replace the
duplicated definitions by deriving CURRENCY_OPTIONS and CURRENCY_SYMBOLS from
that map; update code that references SUPPORTED_CURRENCIES (if present) to use
Object.keys/values from CURRENCY_META (or build a SUPPORTED_CURRENCIES array
from it) so additions/removals only happen in one place and both
CURRENCY_OPTIONS and CURRENCY_SYMBOLS are generated from CURRENCY_META.

In `@packages/epics/src/treasury/hooks/use-assets.ts`:
- Around line 46-47: Update the hook's asset/type contract to use the shared
SupportedCurrency union instead of plain strings: replace any occurrences of
referenceCurrency?: string | null (and other currency-bearing fields in the same
type/hook at the other spots mentioned) with referenceCurrency?:
SupportedCurrency | null (and analogous fields), and add an import for
SupportedCurrency from the shared types module; ensure all references in
useAssets/use-assets types and return types are updated to preserve nullability
and compile-time currency safety.

In `@packages/epics/src/treasury/hooks/use-user-assets.ts`:
- Around line 32-57: The AssetItem and UseAssetsReturn types are duplicated
elsewhere; extract their shape into a shared exported type (e.g., export type
AssetItem and export type UseAssetsReturn) in a common module and replace the
local declarations in use-user-assets.ts by importing those shared types; update
all other places that currently mirror these fields (server token metadata,
asset display props, etc.) to import and use the shared types so the new
currency/reference fields (referencePrice, referenceCurrency) and optional space
fields remain consistent across the codebase.

In `@packages/storage-postgres/src/schema/people.ts`:
- Line 19: The people.schema currently defines currency as text('currency')
allowing any string; add a database-level constraint so only
SUPPORTED_CURRENCIES are persisted—modify the schema definition for the people
table (the currency column) to use a DB enum type or a CHECK constraint
referencing the allowed currency codes (instead of text('currency')) so writes
that bypass app validation are rejected; update any migration/DDL for the people
table and ensure the enum/check uses the same SUPPORTED_CURRENCIES set and that
the column symbol named currency is altered/created accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aa01ae66-e1bf-4a94-955e-f0f92400a769

📥 Commits

Reviewing files that changed from the base of the PR and between ce99d0d and 92ca59d.

📒 Files selected for processing (23)
  • apps/web/src/app/api/v1/people/[personSlug]/assets/route.ts
  • apps/web/src/app/api/v1/spaces/[spaceSlug]/assets/route.ts
  • packages/core/src/common/currency.ts
  • packages/core/src/common/index.ts
  • packages/core/src/common/server/get-fiat-conversion-rate.ts
  • packages/core/src/common/server/index.ts
  • packages/core/src/common/server/web3-rpc/get-token-meta.ts
  • packages/core/src/governance/types.ts
  • packages/core/src/people/server/queries.ts
  • packages/core/src/people/types.ts
  • packages/core/src/people/validation.ts
  • packages/epics/src/people/components/edit-person-section.tsx
  • packages/epics/src/treasury/components/assets/asset-card.tsx
  • packages/epics/src/treasury/components/assets/assets-list.tsx
  • packages/epics/src/treasury/components/common/reference-currency-field.tsx
  • packages/epics/src/treasury/hooks/use-assets-section.ts
  • packages/epics/src/treasury/hooks/use-assets.ts
  • packages/epics/src/treasury/hooks/use-user-assets-section.ts
  • packages/epics/src/treasury/hooks/use-user-assets.ts
  • packages/storage-postgres/migrations/0041_rainy_green_goblin.sql
  • packages/storage-postgres/migrations/meta/0041_snapshot.json
  • packages/storage-postgres/migrations/meta/_journal.json
  • packages/storage-postgres/src/schema/people.ts

@DSanich DSanich force-pushed the feat/1827-currency-conversion-implementation branch from 2ccf329 to 92ca59d Compare March 23, 2026 05:49
@DSanich DSanich force-pushed the feat/1827-currency-conversion-implementation branch from ef1cf3a to f1c540e Compare March 23, 2026 06:34
Copy link
Contributor

@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.

🧹 Nitpick comments (2)
packages/epics/src/treasury/hooks/use-user-assets.ts (1)

32-50: Consider extracting AssetItem type to a shared module.

The AssetItem type (including the new referencePrice and referenceCurrency fields) is now duplicated between this file and use-assets.ts. Extracting it to a shared types module would improve maintainability and ensure consistency.

Based on learnings: "DSanich prefers extracting repeated type declarations into shared modules for reusability and maintainability, particularly for token types that are used across multiple files in the codebase."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/epics/src/treasury/hooks/use-user-assets.ts` around lines 32 - 50,
Extract the duplicated AssetItem type into a shared types module and import it
where needed: create a new exported type (e.g., AssetItem) in a common types
file that includes icon, name, symbol, value, usdEqual, type, chartData:
OneChartPoint[], transactions: TransactionCardProps[], closeUrl, slug, address,
optional space, and the new referencePrice and referenceCurrency fields; then
remove the inline AssetItem declaration from both use-user-assets.ts and
use-assets.ts and update those files to import the shared AssetItem type (and
ensure OneChartPoint and TransactionCardProps are imported or re-exported as
needed).
packages/core/src/people/server/queries.ts (1)

110-125: Currency field added correctly; consider extracting shared field selection.

The currency field is correctly included. However, this field selection duplicates getDefaultFields() (minus total). Consider extracting a base field set to avoid maintaining two nearly-identical field lists.

♻️ Optional: Extract shared base fields
+const getBaseFields = () => ({
+  id: people.id,
+  slug: people.slug,
+  avatarUrl: people.avatarUrl,
+  description: people.description,
+  email: people.email,
+  location: people.location,
+  currency: people.currency,
+  name: people.name,
+  surname: people.surname,
+  nickname: people.nickname,
+  createdAt: people.createdAt,
+  updatedAt: people.updatedAt,
+  address: people.address,
+  leadImageUrl: people.leadImageUrl,
+});
+
 export const getDefaultFields = () => {
   return {
-    id: people.id,
-    slug: people.slug,
-    avatarUrl: people.avatarUrl,
-    description: people.description,
-    email: people.email,
-    location: people.location,
-    currency: people.currency,
-    name: people.name,
-    surname: people.surname,
-    nickname: people.nickname,
-    createdAt: people.createdAt,
-    updatedAt: people.updatedAt,
-    address: people.address,
-    leadImageUrl: people.leadImageUrl,
+    ...getBaseFields(),
     total: sql<number>`cast(count(*) over() as integer)`,
   };
 };

Then use getBaseFields() in findAllPeopleWithoutPagination.

Based on learnings, DSanich prefers extracting repeated declarations into shared modules for reusability and maintainability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/people/server/queries.ts` around lines 110 - 125, This
selection in the people.select block duplicates getDefaultFields() (except
total); extract the repeated field list into a shared helper (e.g.,
getBaseFields()) that returns the common field selection, then update
findAllPeopleWithoutPagination to call getBaseFields() (and have
getDefaultFields() reuse or extend getBaseFields() if needed); update references
to the explicit list in people.select to use that helper so the base fields are
maintained in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/core/src/people/server/queries.ts`:
- Around line 110-125: This selection in the people.select block duplicates
getDefaultFields() (except total); extract the repeated field list into a shared
helper (e.g., getBaseFields()) that returns the common field selection, then
update findAllPeopleWithoutPagination to call getBaseFields() (and have
getDefaultFields() reuse or extend getBaseFields() if needed); update references
to the explicit list in people.select to use that helper so the base fields are
maintained in one place.

In `@packages/epics/src/treasury/hooks/use-user-assets.ts`:
- Around line 32-50: Extract the duplicated AssetItem type into a shared types
module and import it where needed: create a new exported type (e.g., AssetItem)
in a common types file that includes icon, name, symbol, value, usdEqual, type,
chartData: OneChartPoint[], transactions: TransactionCardProps[], closeUrl,
slug, address, optional space, and the new referencePrice and referenceCurrency
fields; then remove the inline AssetItem declaration from both
use-user-assets.ts and use-assets.ts and update those files to import the shared
AssetItem type (and ensure OneChartPoint and TransactionCardProps are imported
or re-exported as needed).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 132bc0fc-00c5-4833-aa66-cbed6b671a05

📥 Commits

Reviewing files that changed from the base of the PR and between ef1cf3a and f1c540e.

📒 Files selected for processing (23)
  • apps/web/src/app/api/v1/people/[personSlug]/assets/route.ts
  • apps/web/src/app/api/v1/spaces/[spaceSlug]/assets/route.ts
  • packages/core/src/common/currency.ts
  • packages/core/src/common/index.ts
  • packages/core/src/common/server/get-fiat-conversion-rate.ts
  • packages/core/src/common/server/index.ts
  • packages/core/src/common/server/web3-rpc/get-token-meta.ts
  • packages/core/src/governance/types.ts
  • packages/core/src/people/server/queries.ts
  • packages/core/src/people/types.ts
  • packages/core/src/people/validation.ts
  • packages/epics/src/people/components/edit-person-section.tsx
  • packages/epics/src/treasury/components/assets/asset-card.tsx
  • packages/epics/src/treasury/components/assets/assets-list.tsx
  • packages/epics/src/treasury/components/common/reference-currency-field.tsx
  • packages/epics/src/treasury/hooks/use-assets-section.ts
  • packages/epics/src/treasury/hooks/use-assets.ts
  • packages/epics/src/treasury/hooks/use-user-assets-section.ts
  • packages/epics/src/treasury/hooks/use-user-assets.ts
  • packages/storage-postgres/migrations/0041_rainy_green_goblin.sql
  • packages/storage-postgres/migrations/meta/0041_snapshot.json
  • packages/storage-postgres/migrations/meta/_journal.json
  • packages/storage-postgres/src/schema/people.ts
✅ Files skipped from review due to trivial changes (10)
  • packages/core/src/common/index.ts
  • packages/core/src/common/server/index.ts
  • packages/storage-postgres/migrations/0041_rainy_green_goblin.sql
  • packages/core/src/people/types.ts
  • packages/epics/src/treasury/components/assets/assets-list.tsx
  • packages/epics/src/treasury/components/common/reference-currency-field.tsx
  • packages/storage-postgres/src/schema/people.ts
  • packages/storage-postgres/migrations/meta/_journal.json
  • packages/core/src/common/currency.ts
  • packages/storage-postgres/migrations/meta/0041_snapshot.json
🚧 Files skipped from review as they are similar to previous changes (10)
  • packages/epics/src/treasury/hooks/use-assets-section.ts
  • packages/core/src/common/server/web3-rpc/get-token-meta.ts
  • packages/epics/src/people/components/edit-person-section.tsx
  • packages/epics/src/treasury/components/assets/asset-card.tsx
  • packages/core/src/people/validation.ts
  • apps/web/src/app/api/v1/people/[personSlug]/assets/route.ts
  • packages/epics/src/treasury/hooks/use-assets.ts
  • packages/core/src/common/server/get-fiat-conversion-rate.ts
  • packages/epics/src/treasury/hooks/use-user-assets-section.ts
  • apps/web/src/app/api/v1/spaces/[spaceSlug]/assets/route.ts

Copy link
Contributor

@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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/deploy-preview.yml (1)

101-117: ⚠️ Potential issue | 🟠 Major

Prevent blank branch DB envs from being deployed when migrations are not run.

Line 103-Line 116 reads steps.create-branch.outputs.* even when create-branch is skipped; those values can be empty and still get pushed via vercel deploy --env ..., overriding runtime envs with blanks.

💡 Proposed fix
       - name: Build Project Artifacts
-        env:
-          BRANCH_DB_URL: ${{ steps.create-branch.outputs.db_url_with_pooler }}
-          BRANCH_DB_ANONYMOUS_URL: ${{ steps.create-branch.outputs.db_url_with_pooler }}
-          BRANCH_DB_AUTHENTICATED_URL: ${{ steps.create-branch.outputs.db_url }}
         run: |
           vercel env pull --environment=preview --token=${{ env.VERCEL_TOKEN }}
           vercel build --token=${{ env.VERCEL_TOKEN }}

       - name: Deploy Preview to Vercel
         id: deploy
-        env:
-          BRANCH_DB_URL: ${{ steps.create-branch.outputs.db_url_with_pooler }}
-          BRANCH_DB_ANONYMOUS_URL: ${{ steps.create-branch.outputs.db_url_with_pooler }}
-          BRANCH_DB_AUTHENTICATED_URL: ${{ steps.create-branch.outputs.db_url }}
-        run: echo preview_url=$(vercel deploy --prebuilt --token=${{ env.VERCEL_TOKEN }} --env BRANCH_DB_URL=${{ env.BRANCH_DB_URL }} --env BRANCH_DB_ANONYMOUS_URL=${{ env.BRANCH_DB_ANONYMOUS_URL }} --env BRANCH_DB_AUTHENTICATED_URL=${{ env.BRANCH_DB_AUTHENTICATED_URL }}) >> $GITHUB_OUTPUT
+        run: |
+          DEPLOY_ARGS=(--prebuilt --token=${{ env.VERCEL_TOKEN }})
+          [[ -n "${BRANCH_DB_URL:-}" ]] && DEPLOY_ARGS+=(--env "BRANCH_DB_URL=${BRANCH_DB_URL}")
+          [[ -n "${BRANCH_DB_ANONYMOUS_URL:-}" ]] && DEPLOY_ARGS+=(--env "BRANCH_DB_ANONYMOUS_URL=${BRANCH_DB_ANONYMOUS_URL}")
+          [[ -n "${BRANCH_DB_AUTHENTICATED_URL:-}" ]] && DEPLOY_ARGS+=(--env "BRANCH_DB_AUTHENTICATED_URL=${BRANCH_DB_AUTHENTICATED_URL}")
+          echo "preview_url=$(vercel deploy "${DEPLOY_ARGS[@]}")" >> "$GITHUB_OUTPUT"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/deploy-preview.yml around lines 101 - 117, The Deploy
Preview step is passing empty branch DB outputs (steps.create-branch.outputs.*)
into vercel deploy which can override runtime envs with blanks when
create-branch is skipped; modify the Deploy Preview "run" to construct the --env
arguments only when each output is non-empty (e.g., build a shell variable
env_args and append "--env BRANCH_DB_URL=…", "--env BRANCH_DB_ANONYMOUS_URL=…",
"--env BRANCH_DB_AUTHENTICATED_URL=…" only if the corresponding
steps.create-branch.outputs.* value is not empty), then call vercel deploy with
${env_args}; alternatively gate the whole step with a condition referencing
steps.create-branch.outcome or non-empty outputs so it doesn't pass blank
values. Ensure you update the "Deploy Preview to Vercel" step that references
BRANCH_DB_URL/ANONYMOUS/AUTHENTICATED to use the conditional env_args or
step-level if.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/common/server/get-db.ts`:
- Around line 16-23: The resolveDbUrl function returns BRANCH_AUTHENTICATED
using the nullish coalescing operator which allows an empty string to slip
through and it also omits the BRANCH fallback; update resolveDbUrl to treat
empty strings as missing (use truthiness checks instead of ??) and mirror the
anonymous branch logic by falling back to BRANCH when BRANCH_AUTHENTICATED is
not usable, ensuring the final value satisfies the invariant check (refer to
resolveDbUrl, BRANCH_AUTHENTICATED, DEFAULT_AUTHENTICATED, BRANCH,
BRANCH_ANONYMOUS, DEFAULT_ANONYMOUS and the invariant validation).

---

Outside diff comments:
In @.github/workflows/deploy-preview.yml:
- Around line 101-117: The Deploy Preview step is passing empty branch DB
outputs (steps.create-branch.outputs.*) into vercel deploy which can override
runtime envs with blanks when create-branch is skipped; modify the Deploy
Preview "run" to construct the --env arguments only when each output is
non-empty (e.g., build a shell variable env_args and append "--env
BRANCH_DB_URL=…", "--env BRANCH_DB_ANONYMOUS_URL=…", "--env
BRANCH_DB_AUTHENTICATED_URL=…" only if the corresponding
steps.create-branch.outputs.* value is not empty), then call vercel deploy with
${env_args}; alternatively gate the whole step with a condition referencing
steps.create-branch.outcome or non-empty outputs so it doesn't pass blank
values. Ensure you update the "Deploy Preview to Vercel" step that references
BRANCH_DB_URL/ANONYMOUS/AUTHENTICATED to use the conditional env_args or
step-level if.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84996a4f-895e-4c56-9f73-33fb053075b6

📥 Commits

Reviewing files that changed from the base of the PR and between f1c540e and af81ff7.

📒 Files selected for processing (2)
  • .github/workflows/deploy-preview.yml
  • packages/core/src/common/server/get-db.ts

@DSanich DSanich force-pushed the feat/1827-currency-conversion-implementation branch 2 times, most recently from ebf1a00 to 262626e Compare March 23, 2026 08:02
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.

1 participant