Skip to content

Commit 363dd11

Browse files
authored
feat: replace client-side account filtering with server-side party_id filter (#1893)
Merging with UNSTABLE - only Build failure is pre-existing dex module issue. Frontend-only PR, 0 unresolved threads.
1 parent b4d300f commit 363dd11

2 files changed

Lines changed: 24 additions & 46 deletions

File tree

frontend/src/features/parties/pages/[partyId].tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export function PartyDetailPage() {
8282
</TabsContent>
8383

8484
<TabsContent value="accounts" className="mt-0">
85-
<AccountsTab partyId={partyId} />
85+
<AccountsTab partyId={partyId} partyType={party?.partyType} />
8686
</TabsContent>
8787

8888
<TabsContent value="audit-trail" className="mt-0">

frontend/src/features/parties/pages/tabs/accounts-tab.tsx

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ import { useClients } from '@/api/context'
1010
import { useTenantSlug } from '@/hooks/use-tenant-context'
1111
import { tenantKeys } from '@/lib/query-keys'
1212
import { AccountStatus } from '@/api/gen/meridian/current_account/v1/current_account_pb'
13+
import { PartyType } from '@/api/gen/meridian/party/v1/party_pb'
1314

1415
interface AccountsTabProps {
1516
partyId: string
17+
/** Party type passed from the parent page to avoid a duplicate fetch */
18+
partyType?: number | string
1619
}
1720

1821
interface AccountRow {
@@ -57,11 +60,16 @@ const columns: ColumnDef<AccountRow>[] = [
5760
},
5861
]
5962

60-
export function AccountsTab({ partyId }: AccountsTabProps) {
63+
export function AccountsTab({ partyId, partyType }: AccountsTabProps) {
6164
const clients = useClients()
6265
const tenantSlug = useTenantSlug()
6366
const navigate = useNavigate()
6467

68+
const isOrganization =
69+
partyType === PartyType.ORGANIZATION ||
70+
partyType === 'PARTY_TYPE_ORGANIZATION' ||
71+
partyType === 'ORGANIZATION'
72+
6573
const queryKey = React.useMemo(
6674
() => [...tenantKeys.party(tenantSlug ?? '', partyId), 'accounts'],
6775
[tenantSlug, partyId],
@@ -71,54 +79,24 @@ export function AccountsTab({ partyId }: AccountsTabProps) {
7179
async (params: DataTableQueryParams): Promise<DataTableResult<AccountRow>> => {
7280
if (!tenantSlug) return { items: [] }
7381

74-
// The API does not support filtering by partyId, so we fetch pages and filter
75-
// client-side. We continue fetching until we have enough matching rows to fill
76-
// pageSize, or the API is exhausted. MAX_PAGES caps sequential API calls to
77-
// prevent unbounded fetching when the party owns few accounts in a large dataset.
78-
const MAX_PAGES = 10
79-
const collected: AccountRow[] = []
80-
let cursor = params.pageToken ?? ''
81-
let nextPageToken: string | undefined
82-
let pagesScanned = 0
83-
84-
while (collected.length < params.pageSize && pagesScanned < MAX_PAGES) {
85-
pagesScanned++
86-
// Use remaining slots as batch size to avoid dropping same-page overflow:
87-
// if the batch were larger than remaining slots, we might get more matches
88-
// than pageSize in one batch but nextPageToken would advance past them.
89-
const remaining = Math.max(params.pageSize - collected.length, 1)
90-
const response = await clients.currentAccount.listCurrentAccounts({
91-
pageSize: remaining,
92-
pageToken: cursor,
93-
})
94-
95-
for (const a of response.accounts ?? []) {
96-
if (a.orgPartyId === partyId || a.partyId === partyId) {
97-
collected.push({
98-
accountId: a.accountId,
99-
externalReference: a.externalIdentifier ?? '',
100-
status: ACCOUNT_STATUS_NAMES[a.accountStatus] ?? String(a.accountStatus),
101-
instrumentCode: a.instrumentCode || '',
102-
createdAt: a.createdAt ?? undefined,
103-
})
104-
}
105-
}
106-
107-
if (!response.nextPageToken) {
108-
nextPageToken = undefined
109-
break
110-
}
111-
112-
cursor = response.nextPageToken
113-
nextPageToken = response.nextPageToken
114-
}
82+
const response = await clients.currentAccount.listCurrentAccounts({
83+
pageSize: params.pageSize,
84+
pageToken: params.pageToken ?? '',
85+
...(isOrganization ? { orgPartyId: partyId } : { partyId }),
86+
})
11587

11688
return {
117-
items: collected.slice(0, params.pageSize),
118-
nextPageToken,
89+
items: (response.accounts ?? []).map((a) => ({
90+
accountId: a.accountId,
91+
externalReference: a.externalIdentifier ?? '',
92+
status: ACCOUNT_STATUS_NAMES[a.accountStatus] ?? String(a.accountStatus),
93+
instrumentCode: a.instrumentCode || '',
94+
createdAt: a.createdAt ?? undefined,
95+
})),
96+
nextPageToken: response.nextPageToken || undefined,
11997
}
12098
},
121-
[tenantSlug, partyId, clients],
99+
[tenantSlug, partyId, isOrganization, clients],
122100
)
123101

124102
return (

0 commit comments

Comments
 (0)