Skip to content

Commit aab4494

Browse files
committed
feat(frontend): centralize tenant-scoped query keys
Add missing query key factories (ledger, positions, starlark-config, account postings, market data observations, provisioning status) and update all feature hooks to use centralized keys instead of inline array construction.
1 parent 87c4620 commit aab4494

8 files changed

Lines changed: 50 additions & 19 deletions

File tree

frontend/src/features/accounts/hooks/use-accounts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export function useAccountPostings(accountId: string | undefined) {
141141
const tenantSlug = useTenantSlug()
142142

143143
return useQuery({
144-
queryKey: [...tenantKeys.account(tenantSlug ?? '', accountId ?? ''), 'postings'],
144+
queryKey: tenantKeys.accountPostings(tenantSlug ?? '', accountId ?? ''),
145145
queryFn: () =>
146146
clients.financialAccounting.listLedgerPostings({
147147
pagination: { pageSize: 50, pageToken: '' },

frontend/src/features/ledger/hooks/use-ledger.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function useBookingLogsTable() {
4646
const clients = useApiClients()
4747
const tenantSlug = useTenantSlug()
4848

49-
const queryKey = [...(tenantSlug ? tenantKeys.all(tenantSlug) : ['no-tenant']), 'ledger', 'bookingLogs'] as const
49+
const queryKey = tenantKeys.bookingLogs(tenantSlug ?? '')
5050

5151
async function queryFn(
5252
params: DataTableQueryParams,
@@ -95,7 +95,7 @@ export function useBookingLogDetail(bookingLogId: string | undefined) {
9595
const tenantSlug = useTenantSlug()
9696

9797
return useQuery({
98-
queryKey: [...tenantKeys.all(tenantSlug ?? ''), 'ledger', 'bookingLog', bookingLogId],
98+
queryKey: tenantKeys.bookingLog(tenantSlug ?? '', bookingLogId ?? ''),
9999
queryFn: async (): Promise<FinancialBookingLog | null> => {
100100
const response = await clients.financialAccounting.retrieveFinancialBookingLog({
101101
id: bookingLogId ?? '',
@@ -150,7 +150,7 @@ export function useLedgerPostings(accountId: string | undefined) {
150150
const tenantSlug = useTenantSlug()
151151

152152
return useQuery({
153-
queryKey: [...tenantKeys.all(tenantSlug ?? ''), 'ledger', 'postings', accountId],
153+
queryKey: tenantKeys.ledgerPostings(tenantSlug ?? '', accountId ?? ''),
154154
queryFn: () =>
155155
clients.financialAccounting.listLedgerPostings({
156156
pagination: { pageSize: 50, pageToken: '' },

frontend/src/features/mappings/pages/dialogs/mapping-mutations.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useMutation, useQueryClient } from '@tanstack/react-query'
22
import { useApiClients } from '@/api/context'
3+
import { referenceKeys } from '@/lib/query-keys'
34

45
export interface CreateMappingRequest {
56
name: string
@@ -25,7 +26,7 @@ export function useCreateMapping() {
2526
return response.mapping
2627
},
2728
onSuccess: () => {
28-
void queryClient.invalidateQueries({ queryKey: ['mappings'] })
29+
void queryClient.invalidateQueries({ queryKey: referenceKeys.mappings() })
2930
},
3031
})
3132
}

frontend/src/features/market-data/hooks/use-market-data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export function useDatasetObservations(datasetCode: string | undefined) {
8181
const tenantSlug = useTenantSlug()
8282

8383
return useQuery({
84-
queryKey: [...tenantKeys.marketDataSet(tenantSlug ?? '', datasetCode ?? ''), 'observations'],
84+
queryKey: tenantKeys.marketDataObservations(tenantSlug ?? '', datasetCode ?? ''),
8585
queryFn: () =>
8686
clients.marketInformation.listObservations({
8787
datasetCode: datasetCode!,

frontend/src/features/positions/hooks/use-positions.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ export function usePositionLogsTable() {
1313
const clients = useApiClients()
1414
const tenantSlug = useTenantSlug()
1515

16-
const queryKey = tenantSlug
17-
? [...tenantKeys.all(tenantSlug), 'positions']
18-
: ['positions']
16+
const queryKey = tenantKeys.positions(tenantSlug ?? '')
1917

2018
async function queryFn(
2119
params: DataTableQueryParams,
@@ -48,9 +46,7 @@ export function usePositionLogDetail(logId: string | undefined) {
4846
const tenantSlug = useTenantSlug()
4947

5048
return useQuery({
51-
queryKey: tenantSlug
52-
? [...tenantKeys.all(tenantSlug), 'positions', logId]
53-
: ['positions', logId],
49+
queryKey: tenantKeys.position(tenantSlug ?? '', logId ?? ''),
5450
queryFn: () =>
5551
clients.positionKeeping.retrieveFinancialPositionLog({ logId: logId! }),
5652
enabled: Boolean(tenantSlug && logId),

frontend/src/features/sagas/hooks/use-sagas.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query'
22
import { ConnectError, Code } from '@connectrpc/connect'
33
import { useApiClients } from '@/api/context'
44
import { useTenantSlug } from '@/hooks/use-tenant-context'
5-
import { tenantKeys } from '@/lib/query-keys'
5+
import { tenantKeys, referenceKeys } from '@/lib/query-keys'
66
import type { DataTableQueryParams, DataTableResult } from '@/shared/data-table'
77
import type { SagaDefinition } from '@/api/gen/meridian/saga/v1/saga_registry_pb'
88

@@ -39,9 +39,7 @@ export function useSagaDetail(definitionId: string | undefined) {
3939
const tenantSlug = useTenantSlug()
4040

4141
return useQuery({
42-
queryKey: tenantSlug
43-
? [...tenantKeys.sagas(tenantSlug), definitionId]
44-
: ['starlark-config', definitionId],
42+
queryKey: tenantKeys.saga(tenantSlug ?? '', definitionId ?? ''),
4543
queryFn: async () => {
4644
const response = await sagaRegistry.getSaga({ id: definitionId ?? '' })
4745
return response.saga
@@ -57,7 +55,7 @@ export function useActiveSaga(sagaName: string | undefined, enabled: boolean = t
5755
const { sagaRegistry } = useApiClients()
5856

5957
return useQuery({
60-
queryKey: ['starlark-config', 'active', sagaName],
58+
queryKey: referenceKeys.activeSaga(sagaName ?? ''),
6159
queryFn: async () => {
6260
if (!sagaName) return null
6361
try {

frontend/src/hooks/use-tenant.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function useTenantProvisioningStatus(tenantId: string, tenantStatus?: Ten
2626
const isProvisioning = tenantStatus !== undefined && PROVISIONING_STATUSES.has(tenantStatus)
2727

2828
return useQuery({
29-
queryKey: [...platformKeys.tenant(tenantId), 'provisioning-status'],
29+
queryKey: platformKeys.tenantProvisioningStatus(tenantId),
3030
queryFn: async () => {
3131
const response = await tenant.getTenantProvisioningStatus({ tenantId })
3232
return response
@@ -48,7 +48,7 @@ export function useUpdateTenantStatus(tenantId: string) {
4848
onSuccess: () => {
4949
void queryClient.invalidateQueries({ queryKey: platformKeys.tenant(tenantId) })
5050
void queryClient.invalidateQueries({
51-
queryKey: [...platformKeys.tenant(tenantId), 'provisioning-status'],
51+
queryKey: platformKeys.tenantProvisioningStatus(tenantId),
5252
})
5353
void queryClient.invalidateQueries({ queryKey: platformKeys.tenants() })
5454
},

frontend/src/lib/query-keys.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,45 @@
44
* Tenant-scoped keys include the tenantId to ensure cache isolation between tenants.
55
* Platform-scoped keys are for platform-level data not tied to a specific tenant.
66
* Reference keys are for non-tenant-scoped reference/configuration data.
7+
*
8+
* Key hierarchy follows the pattern: [scope, tenantId?, domain, entity?, id?]
9+
* so that invalidating a parent key cascades to all children.
710
*/
811

912
export const tenantKeys = {
1013
all: (tenantId: string) => ['tenants', tenantId] as const,
1114

15+
// Accounts
1216
accounts: (tenantId: string) =>
1317
[...tenantKeys.all(tenantId), 'accounts'] as const,
1418
account: (tenantId: string, accountId: string) =>
1519
[...tenantKeys.accounts(tenantId), accountId] as const,
20+
accountPostings: (tenantId: string, accountId: string) =>
21+
[...tenantKeys.account(tenantId, accountId), 'postings'] as const,
1622

23+
// Liens
1724
liens: (tenantId: string, accountId: string) =>
1825
[...tenantKeys.account(tenantId, accountId), 'liens'] as const,
1926

27+
// Transactions
2028
transactions: (tenantId: string) =>
2129
[...tenantKeys.all(tenantId), 'transactions'] as const,
2230
transaction: (tenantId: string, transactionId: string) =>
2331
[...tenantKeys.transactions(tenantId), transactionId] as const,
2432

33+
// Sagas
2534
sagas: (tenantId: string) =>
2635
[...tenantKeys.all(tenantId), 'sagas'] as const,
2736
saga: (tenantId: string, sagaId: string) =>
2837
[...tenantKeys.sagas(tenantId), sagaId] as const,
2938

39+
// Payments
3040
payments: (tenantId: string) =>
3141
[...tenantKeys.all(tenantId), 'payments'] as const,
3242
payment: (tenantId: string, paymentOrderId: string) =>
3343
[...tenantKeys.payments(tenantId), paymentOrderId] as const,
3444

45+
// Parties
3546
parties: (tenantId: string) =>
3647
[...tenantKeys.all(tenantId), 'parties'] as const,
3748
party: (tenantId: string, partyId: string) =>
@@ -42,6 +53,7 @@ export const tenantKeys = {
4253
partyTypes: (tenantId: string) =>
4354
[...tenantKeys.all(tenantId), 'party-types'] as const,
4455

56+
// Internal accounts
4557
internalAccounts: (tenantId: string) =>
4658
[...tenantKeys.all(tenantId), 'internal-accounts'] as const,
4759
internalAccount: (tenantId: string, accountId: string) =>
@@ -50,11 +62,31 @@ export const tenantKeys = {
5062
accountLiens: (tenantId: string, accountId: string) =>
5163
[...tenantKeys.all(tenantId), 'liens', accountId] as const,
5264

65+
// Ledger
66+
ledger: (tenantId: string) =>
67+
[...tenantKeys.all(tenantId), 'ledger'] as const,
68+
bookingLogs: (tenantId: string) =>
69+
[...tenantKeys.ledger(tenantId), 'bookingLogs'] as const,
70+
bookingLog: (tenantId: string, bookingLogId: string) =>
71+
[...tenantKeys.ledger(tenantId), 'bookingLog', bookingLogId] as const,
72+
ledgerPostings: (tenantId: string, accountId: string) =>
73+
[...tenantKeys.ledger(tenantId), 'postings', accountId] as const,
74+
75+
// Positions
76+
positions: (tenantId: string) =>
77+
[...tenantKeys.all(tenantId), 'positions'] as const,
78+
position: (tenantId: string, logId: string) =>
79+
[...tenantKeys.positions(tenantId), logId] as const,
80+
81+
// Market data
5382
marketDataSets: (tenantId: string) =>
5483
[...tenantKeys.all(tenantId), 'market-data', 'datasets'] as const,
5584
marketDataSet: (tenantId: string, datasetCode: string) =>
5685
[...tenantKeys.marketDataSets(tenantId), datasetCode] as const,
86+
marketDataObservations: (tenantId: string, datasetCode: string) =>
87+
[...tenantKeys.marketDataSet(tenantId, datasetCode), 'observations'] as const,
5788

89+
// Reconciliation
5890
reconciliationRuns: (tenantId: string) =>
5991
[...tenantKeys.all(tenantId), 'reconciliation-runs'] as const,
6092
reconciliationRun: (tenantId: string, runId: string) =>
@@ -66,6 +98,8 @@ export const platformKeys = {
6698

6799
tenants: () => [...platformKeys.all, 'tenants'] as const,
68100
tenant: (tenantId: string) => [...platformKeys.tenants(), tenantId] as const,
101+
tenantProvisioningStatus: (tenantId: string) =>
102+
[...platformKeys.tenant(tenantId), 'provisioning-status'] as const,
69103

70104
health: () => [...platformKeys.all, 'health'] as const,
71105

@@ -94,6 +128,8 @@ export const referenceKeys = {
94128

95129
sagas: () => [...referenceKeys.all, 'sagas'] as const,
96130
saga: (sagaId: string) => [...referenceKeys.sagas(), sagaId] as const,
131+
activeSaga: (sagaName: string) =>
132+
[...referenceKeys.sagas(), 'active', sagaName] as const,
97133

98134
mappings: () => [...referenceKeys.all, 'mappings'] as const,
99135
mapping: (mappingId: string) => [...referenceKeys.mappings(), mappingId] as const,

0 commit comments

Comments
 (0)