@burdenoff/microfe-subscriberbot 2026.1023.1 → 2026.1023.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"useSubscriberBotApi.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/hooks/useSubscriberBotApi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useSubscriberBotApi.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/hooks/useSubscriberBotApi.ts"],"names":[],"mappings":"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"}
@@ -116,6 +116,15 @@ var c = async (e, t, n) => {
116
116
  id name type relationshipId secretRef expiresAt workspaceId
117
117
  createdAt updatedAt file { id }
118
118
  }
119
+ # BOFF-8659 - invoices linked via SubInvoice.relationshipId,
120
+ # shown in the Assets section alongside file-based assets so
121
+ # users don't have to leave the relationship page to discover
122
+ # they have an outstanding invoice tied to it.
123
+ invoices {
124
+ id number relationshipId status currency subtotal taxAmount
125
+ total issueDate dueDate paidAt paymentInstrumentId workspaceId
126
+ createdAt updatedAt
127
+ }
119
128
  renewalEvents {
120
129
  id relationshipId eventType occursAt amount currency detail
121
130
  notified workspaceId createdAt updatedAt
@@ -1 +1 @@
1
- {"version":3,"file":"useSubscriberBotApi.js","names":[],"sources":["../../../src/subscriberbot/hooks/useSubscriberBotApi.ts"],"sourcesContent":["/**\n * SubscriberBot API hooks\n * @module subscriberbot/hooks\n *\n * React-Query hooks wired DIRECTLY to the real `wspace-subscriberbot-svc`\n * federated GraphQL contract (the `Sub*` operations). Every query/mutation\n * below uses an inline gql string whose fields match the svc\n * `.hive-schema.graphql` exactly. No mock data.\n *\n * Transport: `graphqlFetch({ gateway: 'workspace', workspaceToken: true })`\n * — the same pattern the workspace MFEs use; the host shell supplies the\n * gateway base URL + a workspace-scoped token.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n// clearGraphqlFetchResponseCache is re-exported from the barrel only in newer\n// fe-libs; import it from its defining module so this works on the pinned\n// 2026.625.5 without forcing a risky fe-libs major bump.\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useSubscriberBot } from '../context';\nimport type {\n PaginationInput,\n SubAdapterSubmission,\n SubAgentKind,\n SubAgentStatus,\n SubAiAgent,\n SubAsset,\n SubBenchmarkDataPoint,\n SubBenchmarkFilterInput,\n SubCommunicationChannel,\n SubConnection,\n SubCreateAgentInput,\n SubCreateAssetInput,\n SubCreateChannelInput,\n SubCreateEntitlementInput,\n SubCreateInvoiceInput,\n SubCreatePaymentInstrumentInput,\n SubCreatePlanInput,\n SubCreatePolicyInput,\n SubCreateProviderInput,\n SubCreateRelationshipInput,\n SubCreateWorkflowInput,\n SubEntitlement,\n SubInboxMessage,\n SubIngestMessageInput,\n SubInvoice,\n SubInvoiceStatus,\n SubMarketplaceReport,\n SubMessageCategory,\n SubModerationAction,\n SubPaymentInstrument,\n SubPlan,\n SubPolicy,\n SubProvider,\n SubProviderCategory,\n SubProviderStatus,\n SubRelationship,\n SubRelationshipKind,\n SubRelationshipStatus,\n SubRenewalEvent,\n SubReportStatus,\n SubSubmissionStatus,\n SubUpdateProviderInput,\n SubUpdateRelationshipInput,\n SubWorkflow,\n SubWorkflowStatus,\n} from '../types';\n\n// ============================================================================\n// Transport\n// ============================================================================\n\nconst subQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n // A mutation just changed server state. fe-libs' graphqlFetch keeps a ~15s\n // global response micro-cache keyed by query+vars, so the react-query refetch\n // that an onSuccess triggers would otherwise be served the STALE pre-write\n // response (a newly created provider/relationship/agent wouldn't appear, a\n // just-marked-read message would still show unread) until the TTL expires.\n // Drop that cache here — centralized so no mutation call site can forget it.\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n};\n\n// React-Query key roots (one namespace per domain entity).\nconst KEY = {\n relationships: ['subscriberbot', 'relationships'] as const,\n relationship: (id: string) => ['subscriberbot', 'relationship', id] as const,\n providers: ['subscriberbot', 'providers'] as const,\n provider: (id: string) => ['subscriberbot', 'provider', id] as const,\n plans: ['subscriberbot', 'plans'] as const,\n benchmarks: (providerSlug: string) => ['subscriberbot', 'benchmarks', providerSlug] as const,\n inbox: ['subscriberbot', 'inbox'] as const,\n invoices: ['subscriberbot', 'invoices'] as const,\n paymentInstruments: ['subscriberbot', 'payment-instruments'] as const,\n channels: ['subscriberbot', 'channels'] as const,\n agents: ['subscriberbot', 'agents'] as const,\n agent: (id: string) => ['subscriberbot', 'agent', id] as const,\n workflows: ['subscriberbot', 'workflows'] as const,\n renewals: ['subscriberbot', 'renewals'] as const,\n assets: ['subscriberbot', 'assets'] as const,\n entitlements: ['subscriberbot', 'entitlements'] as const,\n adapterSubmissions: ['subscriberbot', 'admin', 'adapter-submissions'] as const,\n marketplaceReports: ['subscriberbot', 'admin', 'marketplace-reports'] as const,\n} as const;\n\n// ============================================================================\n// Reusable gql field selections (kept inline-string for codegen-free strictness)\n// ============================================================================\n\nconst PROVIDER_FIELDS = `\n id name slug category status description industry region language websiteUrl\n logoFileId tags churnRiskScore vendorHealthScore workspaceId createdAt updatedAt\n`;\n\nconst PLAN_FIELDS = `\n id name description providerId amount currency interval features isActive\n workspaceId createdAt updatedAt\n`;\n\nconst RELATIONSHIP_FIELDS = `\n id label kind status amount currency interval autoRenew discoverySource notes\n tags healthScore ownerId providerId planId startedAt renewsAt trialEndsAt\n cancelledAt workspaceId createdAt updatedAt\n`;\n\nconst INBOX_FIELDS = `\n id subject preview category categoryConfidence channelId relationshipId\n externalId actionRequired isRead receivedAt workspaceId createdAt updatedAt\n`;\n\nconst INVOICE_FIELDS = `\n id number relationshipId status currency subtotal taxAmount total issueDate\n dueDate paidAt paymentInstrumentId workspaceId createdAt updatedAt\n`;\n\nconst AGENT_FIELDS = `\n id name description kind status ownerId lastRunAt workspaceId createdAt updatedAt\n`;\n\nconst WORKFLOW_FIELDS = `\n id name description triggerEvent status runCount lastRunAt workspaceId\n createdAt updatedAt\n`;\n\nconst ENTITLEMENT_FIELDS = `\n id name description type relationshipId quota used unit isActive\n workspaceId createdAt updatedAt\n`;\n\nconst ASSET_FIELDS = `\n id name type relationshipId secretRef expiresAt workspaceId createdAt\n updatedAt file { id }\n`;\n\nconst PAYMENT_INSTRUMENT_FIELDS = `\n id label type status brand last4 expiryMonth expiryYear isDefault ownerId\n workspaceId createdAt updatedAt\n`;\n\nconst CHANNEL_FIELDS = `\n id label type status address ingestEnabled ownerId verifiedAt workspaceId\n createdAt updatedAt\n`;\n\nconst POLICY_FIELDS = `\n id name description action agentId condition isEnabled triggerCount\n lastTriggeredAt workspaceId createdAt updatedAt\n`;\n\nconst BENCHMARK_DATA_POINT_FIELDS = `\n id providerSlug providerName planName region currency interval amount\n contractSizeSeats sourceKind sourceLabel notes observedAt createdAt\n`;\n\nconst ADAPTER_SUBMISSION_FIELDS = `\n id workspaceId adapterId submitterWorkspaceId status notes createdAt updatedAt\n`;\n\nconst MARKETPLACE_REPORT_FIELDS = `\n id workspaceId listingId reporterWorkspaceId reason status resolutionReason\n createdAt updatedAt\n`;\n\n// ============================================================================\n// Relationships (the core domain object)\n// ============================================================================\n\nexport interface RelationshipListFilters {\n kind?: SubRelationshipKind;\n status?: SubRelationshipStatus;\n providerId?: string;\n ownerId?: string;\n /** Case-insensitive substring match on the relationship label (server-side). */\n search?: string;\n pagination?: PaginationInput;\n}\n\nexport const useRelationships = (filters: RelationshipListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.relationships, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListRelationships: SubConnection<SubRelationship>;\n }>(\n `query SubRelationships(\n $kind: SubRelationshipKind\n $status: SubRelationshipStatus\n $providerId: ID\n $ownerId: ID\n $search: String\n $pagination: PaginationInput\n ) {\n subListRelationships(\n kind: $kind\n status: $status\n providerId: $providerId\n ownerId: $ownerId\n search: $search\n pagination: $pagination\n ) {\n items {\n ${RELATIONSHIP_FIELDS}\n provider { id name category status logoFileId }\n plan { id name amount currency interval }\n }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n kind: filters.kind,\n status: filters.status,\n providerId: filters.providerId,\n ownerId: filters.ownerId,\n search: filters.search,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListRelationships;\n },\n });\n};\n\nexport const useRelationship = (id: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.relationship(id ?? ''),\n enabled: Boolean(id),\n queryFn: async () => {\n const result = await subQuery<{ subRelationship: SubRelationship | null }>(\n `query SubRelationship($id: ID!) {\n subRelationship(id: $id) {\n ${RELATIONSHIP_FIELDS}\n provider { ${PROVIDER_FIELDS} }\n plan { ${PLAN_FIELDS} }\n entitlements {\n id name description type relationshipId quota used unit isActive\n workspaceId createdAt updatedAt\n }\n assets {\n id name type relationshipId secretRef expiresAt workspaceId\n createdAt updatedAt file { id }\n }\n renewalEvents {\n id relationshipId eventType occursAt amount currency detail\n notified workspaceId createdAt updatedAt\n }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subRelationship;\n },\n });\n};\n\nexport const useCreateRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateRelationshipInput) => {\n const result = await subQuery<{ subCreateRelationship: SubRelationship }>(\n `mutation SubCreateRelationship($input: SubCreateRelationshipInput!) {\n subCreateRelationship(input: $input) { ${RELATIONSHIP_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateRelationship;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n },\n });\n};\n\nexport const useTransitionRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: SubRelationshipStatus }) => {\n const result = await subQuery<{ subTransitionRelationship: SubRelationship }>(\n `mutation SubTransitionRelationship($id: ID!, $status: SubRelationshipStatus!) {\n subTransitionRelationship(id: $id, status: $status) { ${RELATIONSHIP_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.subTransitionRelationship;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.id) });\n },\n });\n};\n\nexport const useCancelRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subCancelRelationship: SubRelationship }>(\n `mutation SubCancelRelationship($id: ID!) {\n subCancelRelationship(id: $id) { ${RELATIONSHIP_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subCancelRelationship;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.id) });\n },\n });\n};\n\nexport const useUpdateRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: SubUpdateRelationshipInput }) => {\n const result = await subQuery<{ subUpdateRelationship: SubRelationship }>(\n `mutation SubUpdateRelationship($id: ID!, $input: SubUpdateRelationshipInput!) {\n subUpdateRelationship(id: $id, input: $input) { ${RELATIONSHIP_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.subUpdateRelationship;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.id) });\n },\n });\n};\n\nexport const useRenewalEvents = (\n args: { relationshipId?: string; upcomingOnly?: boolean } = {}\n) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.renewals, args],\n queryFn: async () => {\n // subListRenewalEvents returns SubRenewalEventConnection (items/pageInfo),\n // not a bare list — matching every other subList* root field in this\n // schema (see useRelationships above). Selecting event fields directly\n // fails GraphQL validation server-side (`Cannot query field \"id\" on type\n // \"SubRenewalEventConnection\"`).\n const result = await subQuery<{\n subListRenewalEvents: SubConnection<SubRenewalEvent>;\n }>(\n `query SubRenewalEvents($relationshipId: ID, $upcomingOnly: Boolean) {\n subListRenewalEvents(relationshipId: $relationshipId, upcomingOnly: $upcomingOnly) {\n items {\n id relationshipId eventType occursAt amount currency detail notified\n workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { relationshipId: args.relationshipId, upcomingOnly: args.upcomingOnly },\n apiGatewayUrl\n );\n return result.subListRenewalEvents.items;\n },\n });\n};\n\nexport const useEntitlements = (relationshipId: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.entitlements, relationshipId],\n enabled: Boolean(relationshipId),\n queryFn: async () => {\n const result = await subQuery<{\n subListEntitlements: SubConnection<SubEntitlement>;\n }>(\n `query SubEntitlements($relationshipId: ID!) {\n subListEntitlements(relationshipId: $relationshipId) {\n items {\n id name description type relationshipId quota used unit isActive\n workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { relationshipId },\n apiGatewayUrl\n );\n return result.subListEntitlements.items;\n },\n });\n};\n\nexport const useCreateEntitlement = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateEntitlementInput) => {\n const result = await subQuery<{ subCreateEntitlement: SubEntitlement }>(\n `mutation SubCreateEntitlement($input: SubCreateEntitlementInput!) {\n subCreateEntitlement(input: $input) { ${ENTITLEMENT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateEntitlement;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.entitlements });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.relationshipId) });\n },\n });\n};\n\nexport const useAssets = (relationshipId: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.assets, relationshipId],\n enabled: Boolean(relationshipId),\n queryFn: async () => {\n const result = await subQuery<{ subListAssets: SubConnection<SubAsset> }>(\n `query SubAssets($relationshipId: ID!) {\n subListAssets(relationshipId: $relationshipId) {\n items {\n id name type relationshipId secretRef expiresAt workspaceId\n createdAt updatedAt file { id }\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { relationshipId },\n apiGatewayUrl\n );\n return result.subListAssets.items;\n },\n });\n};\n\n/** Every asset in the workspace (Digital Asset Vault) — omits relationshipId. */\nexport const useAllAssets = () => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.assets, 'all'],\n queryFn: async () => {\n const result = await subQuery<{ subListAssets: SubConnection<SubAsset> }>(\n `query SubAllAssets {\n subListAssets { items { ${ASSET_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n {},\n apiGatewayUrl\n );\n return result.subListAssets.items;\n },\n });\n};\n\nexport const useCreateAsset = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateAssetInput) => {\n const result = await subQuery<{ subCreateAsset: SubAsset }>(\n `mutation SubCreateAsset($input: SubCreateAssetInput!) {\n subCreateAsset(input: $input) { ${ASSET_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateAsset;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.assets });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.relationshipId) });\n },\n });\n};\n\n/**\n * Upload a file to `wspace-files-svc` and return its File id, using the\n * platform-standard 3-step flow (initiateUpload → presigned PUT → completeUpload)\n * over the same `graphqlFetch` transport the rest of this MFE uses. Assets store\n * only the returned `fileId` on `SubCreateAssetInput`; blobs live in files-svc.\n *\n * `CompleteUploadInput.fileSize` is a REQUIRED BigInt (quota tracking) and must\n * match the value given to `initiateUpload` — we pass `String(file.size)` to both.\n */\nconst ASSET_FOLDER_PATH = '/SubscriberBot/Assets';\n\nexport const useUploadFile = () => {\n const { apiGatewayUrl } = useSubscriberBot();\n const [progress, setProgress] = useState(0);\n const [isUploading, setIsUploading] = useState(false);\n\n const uploadFile = useCallback(\n async (file: File): Promise<{ fileId: string; fileName: string }> => {\n setIsUploading(true);\n setProgress(0);\n try {\n // 1. Resolve (or create) the destination folder — File.folderId is a real FK.\n const folderRes = await subQuery<{ ensureFolderByPath: { id: string } | null }>(\n `mutation SubEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }`,\n { path: ASSET_FOLDER_PATH },\n apiGatewayUrl\n );\n const folderId = folderRes.ensureFolderByPath?.id;\n if (!folderId) throw new Error('Could not resolve the upload folder.');\n\n const mimeType = file.type || 'application/octet-stream';\n const dotIndex = file.name.lastIndexOf('.');\n const extension = dotIndex > -1 ? file.name.slice(dotIndex + 1) : 'bin';\n\n // 2. Open a presigned upload session.\n const initiated = await subQuery<{\n initiateUpload: { uploadUrl: string | null; session: { id: string } } | null;\n }>(\n `mutation SubInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }`,\n {\n input: {\n fileName: file.name,\n extension,\n mimeType,\n fileSize: String(file.size),\n folderId,\n },\n },\n apiGatewayUrl\n );\n const uploadUrl = initiated.initiateUpload?.uploadUrl;\n const sessionId = initiated.initiateUpload?.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('The files service did not return an upload URL.');\n }\n\n // 3. PUT the raw bytes to storage. Content-Type must match what was signed.\n await new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', mimeType);\n xhr.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n setProgress(Math.round((event.loaded / event.total) * 100));\n }\n };\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) resolve();\n else reject(new Error(`Upload to storage failed (${xhr.status}).`));\n };\n xhr.onerror = () => reject(new Error('Upload to storage failed.'));\n xhr.send(file);\n });\n\n // 4. Finalize — creates the File record. fileSize must match initiateUpload.\n const completed = await subQuery<{\n completeUpload: { fileId: string; file: { id: string; name: string } | null } | null;\n }>(\n `mutation SubCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }`,\n { input: { sessionId, fileSize: String(file.size), folderId } },\n apiGatewayUrl\n );\n const fileId = completed.completeUpload?.file?.id ?? completed.completeUpload?.fileId;\n if (!fileId) throw new Error('The upload could not be finalized.');\n return { fileId, fileName: completed.completeUpload?.file?.name ?? file.name };\n } finally {\n setIsUploading(false);\n }\n },\n [apiGatewayUrl]\n );\n\n return { uploadFile, progress, isUploading };\n};\n\n/**\n * Resolve a short-lived presigned download URL for a `wspace-files-svc` File id.\n * Never select the federated arg-less `File.downloadUrl` (it mints a URL beyond\n * S3's 7-day cap and 500s the response) — use the root `getFileDownloadUrl`\n * query with a TTL under 604800s instead.\n */\nexport const useFileDownloadUrl = () => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useCallback(\n async (fileId: string): Promise<string> => {\n const result = await subQuery<{ getFileDownloadUrl: string }>(\n `query SubFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }`,\n { id: fileId, expiresIn: 21600 },\n apiGatewayUrl\n );\n return result.getFileDownloadUrl;\n },\n [apiGatewayUrl]\n );\n};\n\n// ============================================================================\n// Providers (the global discovery registry)\n// ============================================================================\n\nexport interface ProviderListFilters {\n category?: SubProviderCategory;\n status?: SubProviderStatus;\n search?: string;\n pagination?: PaginationInput;\n}\n\nexport const useProviders = (filters: ProviderListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.providers, filters],\n queryFn: async () => {\n const result = await subQuery<{ subListProviders: SubConnection<SubProvider> }>(\n `query SubProviders(\n $category: SubProviderCategory\n $status: SubProviderStatus\n $search: String\n $pagination: PaginationInput\n ) {\n subListProviders(\n category: $category\n status: $status\n search: $search\n pagination: $pagination\n ) {\n items { ${PROVIDER_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n category: filters.category,\n status: filters.status,\n search: filters.search,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListProviders;\n },\n });\n};\n\nexport const useProvider = (id: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.provider(id ?? ''),\n enabled: Boolean(id),\n queryFn: async () => {\n const result = await subQuery<{ subProvider: SubProvider | null }>(\n `query SubProvider($id: ID!) {\n subProvider(id: $id) {\n ${PROVIDER_FIELDS}\n plans { ${PLAN_FIELDS} }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subProvider;\n },\n });\n};\n\nexport const useCreateProvider = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateProviderInput) => {\n const result = await subQuery<{ subCreateProvider: SubProvider }>(\n `mutation SubCreateProvider($input: SubCreateProviderInput!) {\n subCreateProvider(input: $input) { ${PROVIDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateProvider;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.providers });\n },\n });\n};\n\nexport const useUpdateProvider = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: SubUpdateProviderInput }) => {\n const result = await subQuery<{ subUpdateProvider: SubProvider }>(\n `mutation SubUpdateProvider($id: ID!, $input: SubUpdateProviderInput!) {\n subUpdateProvider(id: $id, input: $input) { ${PROVIDER_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.subUpdateProvider;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.providers });\n void queryClient.invalidateQueries({ queryKey: KEY.provider(data.id) });\n },\n });\n};\n\nexport const useArchiveProvider = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subArchiveProvider: boolean }>(\n `mutation SubArchiveProvider($id: ID!) {\n subArchiveProvider(id: $id)\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subArchiveProvider;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.providers });\n },\n });\n};\n\nexport const usePlans = (providerId: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.plans, providerId],\n enabled: Boolean(providerId),\n queryFn: async () => {\n const result = await subQuery<{ subListPlans: SubConnection<SubPlan> }>(\n `query SubPlans($providerId: ID) {\n subListPlans(providerId: $providerId) { items { ${PLAN_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n { providerId },\n apiGatewayUrl\n );\n return result.subListPlans.items;\n },\n });\n};\n\nexport const useCreatePlan = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreatePlanInput) => {\n const result = await subQuery<{ subCreatePlan: SubPlan }>(\n `mutation SubCreatePlan($input: SubCreatePlanInput!) {\n subCreatePlan(input: $input) { ${PLAN_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreatePlan;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.plans });\n void queryClient.invalidateQueries({ queryKey: KEY.provider(data.providerId) });\n },\n });\n};\n\n/**\n * Observed price points for one provider, newest first from the server.\n *\n * Backs the provider \"Price history\" card. The benchmark dataset is read\n * GLOBALLY (`@rbac(..., public: true)` on the svc) — it is the same for every\n * workspace — so nothing here is workspace scoped. Matching is by\n * `providerSlug`, which is an exact match server-side; `providerName` is a\n * fuzzy `contains` match and would risk attributing another vendor's prices to\n * this provider, so the query stays disabled until a slug exists.\n */\nexport const useBenchmarkDataPoints = (providerSlug: string | null | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.benchmarks(providerSlug ?? ''),\n enabled: Boolean(providerSlug),\n queryFn: async () => {\n const filter: SubBenchmarkFilterInput = { providerSlug: providerSlug ?? undefined };\n const result = await subQuery<{\n subListBenchmarkDataPoints: SubConnection<SubBenchmarkDataPoint>;\n }>(\n `query SubBenchmarkDataPoints(\n $filter: SubBenchmarkFilterInput\n $pagination: PaginationInput\n ) {\n subListBenchmarkDataPoints(filter: $filter, pagination: $pagination) {\n items { ${BENCHMARK_DATA_POINT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { filter, pagination: { limit: 100, offset: 0 } },\n apiGatewayUrl\n );\n return result.subListBenchmarkDataPoints.items;\n },\n });\n};\n\n// ============================================================================\n// Universal Inbox\n// ============================================================================\n\nexport interface InboxListFilters {\n category?: SubMessageCategory;\n channelId?: string;\n relationshipId?: string;\n unreadOnly?: boolean;\n pagination?: PaginationInput;\n}\n\nexport const useInboxMessages = (filters: InboxListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.inbox, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListInboxMessages: SubConnection<SubInboxMessage>;\n }>(\n `query SubInboxMessages(\n $category: SubMessageCategory\n $channelId: ID\n $relationshipId: ID\n $unreadOnly: Boolean\n $pagination: PaginationInput\n ) {\n subListInboxMessages(\n category: $category\n channelId: $channelId\n relationshipId: $relationshipId\n unreadOnly: $unreadOnly\n pagination: $pagination\n ) {\n items { ${INBOX_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n category: filters.category,\n channelId: filters.channelId,\n relationshipId: filters.relationshipId,\n unreadOnly: filters.unreadOnly,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListInboxMessages;\n },\n });\n};\n\nexport const useMarkMessageRead = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subMarkMessageRead: SubInboxMessage }>(\n `mutation SubMarkMessageRead($id: ID!) {\n subMarkMessageRead(id: $id) { ${INBOX_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subMarkMessageRead;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.inbox });\n },\n });\n};\n\nexport const useIngestMessage = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubIngestMessageInput) => {\n const result = await subQuery<{ subIngestMessage: SubInboxMessage }>(\n `mutation SubIngestMessage($input: SubIngestMessageInput!) {\n subIngestMessage(input: $input) { ${INBOX_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subIngestMessage;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.inbox });\n },\n });\n};\n\n// ============================================================================\n// Invoices (Universal Billing Layer)\n// ============================================================================\n\nexport interface InvoiceListFilters {\n status?: SubInvoiceStatus;\n relationshipId?: string;\n pagination?: PaginationInput;\n}\n\nexport const useInvoices = (filters: InvoiceListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.invoices, filters],\n queryFn: async () => {\n const result = await subQuery<{ subListInvoices: SubConnection<SubInvoice> }>(\n `query SubInvoices(\n $status: SubInvoiceStatus\n $relationshipId: ID\n $pagination: PaginationInput\n ) {\n subListInvoices(\n status: $status\n relationshipId: $relationshipId\n pagination: $pagination\n ) {\n items { ${INVOICE_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n relationshipId: filters.relationshipId,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListInvoices;\n },\n });\n};\n\nexport const useMarkInvoicePaid = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subMarkInvoicePaid: SubInvoice }>(\n `mutation SubMarkInvoicePaid($id: ID!) {\n subMarkInvoicePaid(id: $id) { ${INVOICE_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subMarkInvoicePaid;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.invoices });\n },\n });\n};\n\nexport const useCreateInvoice = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateInvoiceInput) => {\n const result = await subQuery<{ subCreateInvoice: SubInvoice }>(\n `mutation SubCreateInvoice($input: SubCreateInvoiceInput!) {\n subCreateInvoice(input: $input) { ${INVOICE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateInvoice;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.invoices });\n },\n });\n};\n\n// ============================================================================\n// Payment instruments & communication channels\n// ============================================================================\n\nexport const usePaymentInstruments = (ownerId?: string) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.paymentInstruments, ownerId],\n queryFn: async () => {\n const result = await subQuery<{\n subListPaymentInstruments: SubConnection<SubPaymentInstrument>;\n }>(\n `query SubPaymentInstruments($ownerId: ID) {\n subListPaymentInstruments(ownerId: $ownerId) {\n items {\n id label type status brand last4 expiryMonth expiryYear isDefault\n ownerId workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return result.subListPaymentInstruments.items;\n },\n });\n};\n\nexport const useCreatePaymentInstrument = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreatePaymentInstrumentInput) => {\n const result = await subQuery<{ subCreatePaymentInstrument: SubPaymentInstrument }>(\n `mutation SubCreatePaymentInstrument($input: SubCreatePaymentInstrumentInput!) {\n subCreatePaymentInstrument(input: $input) { ${PAYMENT_INSTRUMENT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreatePaymentInstrument;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.paymentInstruments });\n },\n });\n};\n\nexport const useRemovePaymentInstrument = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subRemovePaymentInstrument: boolean }>(\n `mutation SubRemovePaymentInstrument($id: ID!) {\n subRemovePaymentInstrument(id: $id)\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subRemovePaymentInstrument;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.paymentInstruments });\n },\n });\n};\n\nexport const useChannels = (ownerId?: string) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.channels, ownerId],\n queryFn: async () => {\n const result = await subQuery<{\n subListChannels: SubConnection<SubCommunicationChannel>;\n }>(\n `query SubChannels($ownerId: ID) {\n subListChannels(ownerId: $ownerId) {\n items {\n id label type status address ingestEnabled ownerId verifiedAt\n workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return result.subListChannels.items;\n },\n });\n};\n\nexport const useCreateChannel = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateChannelInput) => {\n const result = await subQuery<{ subCreateChannel: SubCommunicationChannel }>(\n `mutation SubCreateChannel($input: SubCreateChannelInput!) {\n subCreateChannel(input: $input) { ${CHANNEL_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateChannel;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.channels });\n },\n });\n};\n\nexport const useVerifyChannel = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subVerifyChannel: SubCommunicationChannel }>(\n `mutation SubVerifyChannel($id: ID!) {\n subVerifyChannel(id: $id) { ${CHANNEL_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subVerifyChannel;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.channels });\n },\n });\n};\n\n// ============================================================================\n// AI Agents & workflows (automation)\n// ============================================================================\n\nexport interface AgentListFilters {\n kind?: SubAgentKind;\n status?: SubAgentStatus;\n ownerId?: string;\n}\n\nexport const useAgents = (filters: AgentListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.agents, filters],\n queryFn: async () => {\n const result = await subQuery<{ subListAgents: SubConnection<SubAiAgent> }>(\n `query SubAgents($kind: SubAgentKind, $status: SubAgentStatus, $ownerId: ID) {\n subListAgents(kind: $kind, status: $status, ownerId: $ownerId) {\n items { ${AGENT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { kind: filters.kind, status: filters.status, ownerId: filters.ownerId },\n apiGatewayUrl\n );\n return result.subListAgents.items;\n },\n });\n};\n\nexport const useAgent = (id: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.agent(id ?? ''),\n enabled: Boolean(id),\n queryFn: async () => {\n const result = await subQuery<{ subAgent: SubAiAgent | null }>(\n `query SubAgent($id: ID!) {\n subAgent(id: $id) {\n ${AGENT_FIELDS}\n policies { ${POLICY_FIELDS} }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subAgent;\n },\n });\n};\n\nexport const useCreateAgent = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateAgentInput) => {\n const result = await subQuery<{ subCreateAgent: SubAiAgent }>(\n `mutation SubCreateAgent($input: SubCreateAgentInput!) {\n subCreateAgent(input: $input) { ${AGENT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateAgent;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.agents });\n },\n });\n};\n\nexport const useSetAgentStatus = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: SubAgentStatus }) => {\n const result = await subQuery<{ subSetAgentStatus: SubAiAgent }>(\n `mutation SubSetAgentStatus($id: ID!, $status: SubAgentStatus!) {\n subSetAgentStatus(id: $id, status: $status) { ${AGENT_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.subSetAgentStatus;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.agents });\n void queryClient.invalidateQueries({ queryKey: KEY.agent(data.id) });\n },\n });\n};\n\nexport const useCreatePolicy = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreatePolicyInput) => {\n const result = await subQuery<{ subCreatePolicy: SubPolicy }>(\n `mutation SubCreatePolicy($input: SubCreatePolicyInput!) {\n subCreatePolicy(input: $input) { ${POLICY_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreatePolicy;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.agents });\n void queryClient.invalidateQueries({ queryKey: KEY.agent(data.agentId) });\n },\n });\n};\n\nexport const useWorkflows = (status?: SubWorkflowStatus) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.workflows, status],\n queryFn: async () => {\n const result = await subQuery<{ subListWorkflows: SubConnection<SubWorkflow> }>(\n `query SubWorkflows($status: SubWorkflowStatus) {\n subListWorkflows(status: $status) { items { ${WORKFLOW_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n { status },\n apiGatewayUrl\n );\n return result.subListWorkflows.items;\n },\n });\n};\n\nexport const useCreateWorkflow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateWorkflowInput) => {\n const result = await subQuery<{ subCreateWorkflow: SubWorkflow }>(\n `mutation SubCreateWorkflow($input: SubCreateWorkflowInput!) {\n subCreateWorkflow(input: $input) { ${WORKFLOW_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateWorkflow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.workflows });\n },\n });\n};\n\nexport const useActivateWorkflow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subActivateWorkflow: SubWorkflow }>(\n `mutation SubActivateWorkflow($id: ID!) {\n subActivateWorkflow(id: $id) { ${WORKFLOW_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subActivateWorkflow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.workflows });\n },\n });\n};\n\n// ============================================================================\n// Admin governance (adapter approvals + marketplace moderation)\n// ============================================================================\n\nexport interface AdapterSubmissionListFilters {\n status?: SubSubmissionStatus;\n pagination?: PaginationInput;\n}\n\nexport const useAdapterSubmissions = (filters: AdapterSubmissionListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.adapterSubmissions, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListAdapterSubmissions: SubConnection<SubAdapterSubmission>;\n }>(\n `query SubAdapterSubmissions($status: SubSubmissionStatus, $pagination: PaginationInput) {\n subListAdapterSubmissions(status: $status, pagination: $pagination) {\n items { ${ADAPTER_SUBMISSION_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListAdapterSubmissions;\n },\n });\n};\n\nexport const useApproveAdapter = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, notes }: { id: string; notes?: string }) => {\n const result = await subQuery<{ subApproveAdapter: SubAdapterSubmission }>(\n `mutation SubApproveAdapter($id: ID!, $notes: String) {\n subApproveAdapter(id: $id, notes: $notes) { ${ADAPTER_SUBMISSION_FIELDS} }\n }`,\n { id, notes },\n apiGatewayUrl\n );\n return result.subApproveAdapter;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.adapterSubmissions });\n },\n });\n};\n\nexport const useRejectAdapter = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, reason }: { id: string; reason: string }) => {\n const result = await subQuery<{ subRejectAdapter: SubAdapterSubmission }>(\n `mutation SubRejectAdapter($id: ID!, $reason: String!) {\n subRejectAdapter(id: $id, reason: $reason) { ${ADAPTER_SUBMISSION_FIELDS} }\n }`,\n { id, reason },\n apiGatewayUrl\n );\n return result.subRejectAdapter;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.adapterSubmissions });\n },\n });\n};\n\nexport interface MarketplaceReportListFilters {\n status?: SubReportStatus;\n pagination?: PaginationInput;\n}\n\nexport const useMarketplaceReports = (filters: MarketplaceReportListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.marketplaceReports, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListMarketplaceReports: SubConnection<SubMarketplaceReport>;\n }>(\n `query SubMarketplaceReports($status: SubReportStatus, $pagination: PaginationInput) {\n subListMarketplaceReports(status: $status, pagination: $pagination) {\n items { ${MARKETPLACE_REPORT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListMarketplaceReports;\n },\n });\n};\n\nexport const useModerateListing = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({\n id,\n action,\n reason,\n }: {\n id: string;\n action: SubModerationAction;\n reason: string;\n }) => {\n const result = await subQuery<{ subModerateListing: SubMarketplaceReport }>(\n `mutation SubModerateListing($id: ID!, $action: SubModerationAction!, $reason: String!) {\n subModerateListing(id: $id, action: $action, reason: $reason) { ${MARKETPLACE_REPORT_FIELDS} }\n }`,\n { id, action, reason },\n apiGatewayUrl\n );\n return result.subModerateListing;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.marketplaceReports });\n },\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useSubscriberBotApi.js","names":[],"sources":["../../../src/subscriberbot/hooks/useSubscriberBotApi.ts"],"sourcesContent":["/**\n * SubscriberBot API hooks\n * @module subscriberbot/hooks\n *\n * React-Query hooks wired DIRECTLY to the real `wspace-subscriberbot-svc`\n * federated GraphQL contract (the `Sub*` operations). Every query/mutation\n * below uses an inline gql string whose fields match the svc\n * `.hive-schema.graphql` exactly. No mock data.\n *\n * Transport: `graphqlFetch({ gateway: 'workspace', workspaceToken: true })`\n * — the same pattern the workspace MFEs use; the host shell supplies the\n * gateway base URL + a workspace-scoped token.\n */\n\nimport { useCallback, useState } from 'react';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n// clearGraphqlFetchResponseCache is re-exported from the barrel only in newer\n// fe-libs; import it from its defining module so this works on the pinned\n// 2026.625.5 without forcing a risky fe-libs major bump.\nimport { clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql/fetch';\n\nimport { useSubscriberBot } from '../context';\nimport type {\n PaginationInput,\n SubAdapterSubmission,\n SubAgentKind,\n SubAgentStatus,\n SubAiAgent,\n SubAsset,\n SubBenchmarkDataPoint,\n SubBenchmarkFilterInput,\n SubCommunicationChannel,\n SubConnection,\n SubCreateAgentInput,\n SubCreateAssetInput,\n SubCreateChannelInput,\n SubCreateEntitlementInput,\n SubCreateInvoiceInput,\n SubCreatePaymentInstrumentInput,\n SubCreatePlanInput,\n SubCreatePolicyInput,\n SubCreateProviderInput,\n SubCreateRelationshipInput,\n SubCreateWorkflowInput,\n SubEntitlement,\n SubInboxMessage,\n SubIngestMessageInput,\n SubInvoice,\n SubInvoiceStatus,\n SubMarketplaceReport,\n SubMessageCategory,\n SubModerationAction,\n SubPaymentInstrument,\n SubPlan,\n SubPolicy,\n SubProvider,\n SubProviderCategory,\n SubProviderStatus,\n SubRelationship,\n SubRelationshipKind,\n SubRelationshipStatus,\n SubRenewalEvent,\n SubReportStatus,\n SubSubmissionStatus,\n SubUpdateProviderInput,\n SubUpdateRelationshipInput,\n SubWorkflow,\n SubWorkflowStatus,\n} from '../types';\n\n// ============================================================================\n// Transport\n// ============================================================================\n\nconst subQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'GraphQL request failed');\n }\n if (!response.data) {\n throw new Error('GraphQL response did not include data');\n }\n // A mutation just changed server state. fe-libs' graphqlFetch keeps a ~15s\n // global response micro-cache keyed by query+vars, so the react-query refetch\n // that an onSuccess triggers would otherwise be served the STALE pre-write\n // response (a newly created provider/relationship/agent wouldn't appear, a\n // just-marked-read message would still show unread) until the TTL expires.\n // Drop that cache here — centralized so no mutation call site can forget it.\n if (/^\\s*mutation\\b/.test(query)) {\n clearGraphqlFetchResponseCache();\n }\n return response.data;\n};\n\n// React-Query key roots (one namespace per domain entity).\nconst KEY = {\n relationships: ['subscriberbot', 'relationships'] as const,\n relationship: (id: string) => ['subscriberbot', 'relationship', id] as const,\n providers: ['subscriberbot', 'providers'] as const,\n provider: (id: string) => ['subscriberbot', 'provider', id] as const,\n plans: ['subscriberbot', 'plans'] as const,\n benchmarks: (providerSlug: string) => ['subscriberbot', 'benchmarks', providerSlug] as const,\n inbox: ['subscriberbot', 'inbox'] as const,\n invoices: ['subscriberbot', 'invoices'] as const,\n paymentInstruments: ['subscriberbot', 'payment-instruments'] as const,\n channels: ['subscriberbot', 'channels'] as const,\n agents: ['subscriberbot', 'agents'] as const,\n agent: (id: string) => ['subscriberbot', 'agent', id] as const,\n workflows: ['subscriberbot', 'workflows'] as const,\n renewals: ['subscriberbot', 'renewals'] as const,\n assets: ['subscriberbot', 'assets'] as const,\n entitlements: ['subscriberbot', 'entitlements'] as const,\n adapterSubmissions: ['subscriberbot', 'admin', 'adapter-submissions'] as const,\n marketplaceReports: ['subscriberbot', 'admin', 'marketplace-reports'] as const,\n} as const;\n\n// ============================================================================\n// Reusable gql field selections (kept inline-string for codegen-free strictness)\n// ============================================================================\n\nconst PROVIDER_FIELDS = `\n id name slug category status description industry region language websiteUrl\n logoFileId tags churnRiskScore vendorHealthScore workspaceId createdAt updatedAt\n`;\n\nconst PLAN_FIELDS = `\n id name description providerId amount currency interval features isActive\n workspaceId createdAt updatedAt\n`;\n\nconst RELATIONSHIP_FIELDS = `\n id label kind status amount currency interval autoRenew discoverySource notes\n tags healthScore ownerId providerId planId startedAt renewsAt trialEndsAt\n cancelledAt workspaceId createdAt updatedAt\n`;\n\nconst INBOX_FIELDS = `\n id subject preview category categoryConfidence channelId relationshipId\n externalId actionRequired isRead receivedAt workspaceId createdAt updatedAt\n`;\n\nconst INVOICE_FIELDS = `\n id number relationshipId status currency subtotal taxAmount total issueDate\n dueDate paidAt paymentInstrumentId workspaceId createdAt updatedAt\n`;\n\nconst AGENT_FIELDS = `\n id name description kind status ownerId lastRunAt workspaceId createdAt updatedAt\n`;\n\nconst WORKFLOW_FIELDS = `\n id name description triggerEvent status runCount lastRunAt workspaceId\n createdAt updatedAt\n`;\n\nconst ENTITLEMENT_FIELDS = `\n id name description type relationshipId quota used unit isActive\n workspaceId createdAt updatedAt\n`;\n\nconst ASSET_FIELDS = `\n id name type relationshipId secretRef expiresAt workspaceId createdAt\n updatedAt file { id }\n`;\n\nconst PAYMENT_INSTRUMENT_FIELDS = `\n id label type status brand last4 expiryMonth expiryYear isDefault ownerId\n workspaceId createdAt updatedAt\n`;\n\nconst CHANNEL_FIELDS = `\n id label type status address ingestEnabled ownerId verifiedAt workspaceId\n createdAt updatedAt\n`;\n\nconst POLICY_FIELDS = `\n id name description action agentId condition isEnabled triggerCount\n lastTriggeredAt workspaceId createdAt updatedAt\n`;\n\nconst BENCHMARK_DATA_POINT_FIELDS = `\n id providerSlug providerName planName region currency interval amount\n contractSizeSeats sourceKind sourceLabel notes observedAt createdAt\n`;\n\nconst ADAPTER_SUBMISSION_FIELDS = `\n id workspaceId adapterId submitterWorkspaceId status notes createdAt updatedAt\n`;\n\nconst MARKETPLACE_REPORT_FIELDS = `\n id workspaceId listingId reporterWorkspaceId reason status resolutionReason\n createdAt updatedAt\n`;\n\n// ============================================================================\n// Relationships (the core domain object)\n// ============================================================================\n\nexport interface RelationshipListFilters {\n kind?: SubRelationshipKind;\n status?: SubRelationshipStatus;\n providerId?: string;\n ownerId?: string;\n /** Case-insensitive substring match on the relationship label (server-side). */\n search?: string;\n pagination?: PaginationInput;\n}\n\nexport const useRelationships = (filters: RelationshipListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.relationships, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListRelationships: SubConnection<SubRelationship>;\n }>(\n `query SubRelationships(\n $kind: SubRelationshipKind\n $status: SubRelationshipStatus\n $providerId: ID\n $ownerId: ID\n $search: String\n $pagination: PaginationInput\n ) {\n subListRelationships(\n kind: $kind\n status: $status\n providerId: $providerId\n ownerId: $ownerId\n search: $search\n pagination: $pagination\n ) {\n items {\n ${RELATIONSHIP_FIELDS}\n provider { id name category status logoFileId }\n plan { id name amount currency interval }\n }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n kind: filters.kind,\n status: filters.status,\n providerId: filters.providerId,\n ownerId: filters.ownerId,\n search: filters.search,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListRelationships;\n },\n });\n};\n\nexport const useRelationship = (id: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.relationship(id ?? ''),\n enabled: Boolean(id),\n queryFn: async () => {\n const result = await subQuery<{ subRelationship: SubRelationship | null }>(\n `query SubRelationship($id: ID!) {\n subRelationship(id: $id) {\n ${RELATIONSHIP_FIELDS}\n provider { ${PROVIDER_FIELDS} }\n plan { ${PLAN_FIELDS} }\n entitlements {\n id name description type relationshipId quota used unit isActive\n workspaceId createdAt updatedAt\n }\n assets {\n id name type relationshipId secretRef expiresAt workspaceId\n createdAt updatedAt file { id }\n }\n # BOFF-8659 - invoices linked via SubInvoice.relationshipId,\n # shown in the Assets section alongside file-based assets so\n # users don't have to leave the relationship page to discover\n # they have an outstanding invoice tied to it.\n invoices {\n id number relationshipId status currency subtotal taxAmount\n total issueDate dueDate paidAt paymentInstrumentId workspaceId\n createdAt updatedAt\n }\n renewalEvents {\n id relationshipId eventType occursAt amount currency detail\n notified workspaceId createdAt updatedAt\n }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subRelationship;\n },\n });\n};\n\nexport const useCreateRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateRelationshipInput) => {\n const result = await subQuery<{ subCreateRelationship: SubRelationship }>(\n `mutation SubCreateRelationship($input: SubCreateRelationshipInput!) {\n subCreateRelationship(input: $input) { ${RELATIONSHIP_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateRelationship;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n },\n });\n};\n\nexport const useTransitionRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: SubRelationshipStatus }) => {\n const result = await subQuery<{ subTransitionRelationship: SubRelationship }>(\n `mutation SubTransitionRelationship($id: ID!, $status: SubRelationshipStatus!) {\n subTransitionRelationship(id: $id, status: $status) { ${RELATIONSHIP_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.subTransitionRelationship;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.id) });\n },\n });\n};\n\nexport const useCancelRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subCancelRelationship: SubRelationship }>(\n `mutation SubCancelRelationship($id: ID!) {\n subCancelRelationship(id: $id) { ${RELATIONSHIP_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subCancelRelationship;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.id) });\n },\n });\n};\n\nexport const useUpdateRelationship = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: SubUpdateRelationshipInput }) => {\n const result = await subQuery<{ subUpdateRelationship: SubRelationship }>(\n `mutation SubUpdateRelationship($id: ID!, $input: SubUpdateRelationshipInput!) {\n subUpdateRelationship(id: $id, input: $input) { ${RELATIONSHIP_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.subUpdateRelationship;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.relationships });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.id) });\n },\n });\n};\n\nexport const useRenewalEvents = (\n args: { relationshipId?: string; upcomingOnly?: boolean } = {}\n) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.renewals, args],\n queryFn: async () => {\n // subListRenewalEvents returns SubRenewalEventConnection (items/pageInfo),\n // not a bare list — matching every other subList* root field in this\n // schema (see useRelationships above). Selecting event fields directly\n // fails GraphQL validation server-side (`Cannot query field \"id\" on type\n // \"SubRenewalEventConnection\"`).\n const result = await subQuery<{\n subListRenewalEvents: SubConnection<SubRenewalEvent>;\n }>(\n `query SubRenewalEvents($relationshipId: ID, $upcomingOnly: Boolean) {\n subListRenewalEvents(relationshipId: $relationshipId, upcomingOnly: $upcomingOnly) {\n items {\n id relationshipId eventType occursAt amount currency detail notified\n workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { relationshipId: args.relationshipId, upcomingOnly: args.upcomingOnly },\n apiGatewayUrl\n );\n return result.subListRenewalEvents.items;\n },\n });\n};\n\nexport const useEntitlements = (relationshipId: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.entitlements, relationshipId],\n enabled: Boolean(relationshipId),\n queryFn: async () => {\n const result = await subQuery<{\n subListEntitlements: SubConnection<SubEntitlement>;\n }>(\n `query SubEntitlements($relationshipId: ID!) {\n subListEntitlements(relationshipId: $relationshipId) {\n items {\n id name description type relationshipId quota used unit isActive\n workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { relationshipId },\n apiGatewayUrl\n );\n return result.subListEntitlements.items;\n },\n });\n};\n\nexport const useCreateEntitlement = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateEntitlementInput) => {\n const result = await subQuery<{ subCreateEntitlement: SubEntitlement }>(\n `mutation SubCreateEntitlement($input: SubCreateEntitlementInput!) {\n subCreateEntitlement(input: $input) { ${ENTITLEMENT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateEntitlement;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.entitlements });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.relationshipId) });\n },\n });\n};\n\nexport const useAssets = (relationshipId: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.assets, relationshipId],\n enabled: Boolean(relationshipId),\n queryFn: async () => {\n const result = await subQuery<{ subListAssets: SubConnection<SubAsset> }>(\n `query SubAssets($relationshipId: ID!) {\n subListAssets(relationshipId: $relationshipId) {\n items {\n id name type relationshipId secretRef expiresAt workspaceId\n createdAt updatedAt file { id }\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { relationshipId },\n apiGatewayUrl\n );\n return result.subListAssets.items;\n },\n });\n};\n\n/** Every asset in the workspace (Digital Asset Vault) — omits relationshipId. */\nexport const useAllAssets = () => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.assets, 'all'],\n queryFn: async () => {\n const result = await subQuery<{ subListAssets: SubConnection<SubAsset> }>(\n `query SubAllAssets {\n subListAssets { items { ${ASSET_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n {},\n apiGatewayUrl\n );\n return result.subListAssets.items;\n },\n });\n};\n\nexport const useCreateAsset = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateAssetInput) => {\n const result = await subQuery<{ subCreateAsset: SubAsset }>(\n `mutation SubCreateAsset($input: SubCreateAssetInput!) {\n subCreateAsset(input: $input) { ${ASSET_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateAsset;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.assets });\n void queryClient.invalidateQueries({ queryKey: KEY.relationship(data.relationshipId) });\n },\n });\n};\n\n/**\n * Upload a file to `wspace-files-svc` and return its File id, using the\n * platform-standard 3-step flow (initiateUpload → presigned PUT → completeUpload)\n * over the same `graphqlFetch` transport the rest of this MFE uses. Assets store\n * only the returned `fileId` on `SubCreateAssetInput`; blobs live in files-svc.\n *\n * `CompleteUploadInput.fileSize` is a REQUIRED BigInt (quota tracking) and must\n * match the value given to `initiateUpload` — we pass `String(file.size)` to both.\n */\nconst ASSET_FOLDER_PATH = '/SubscriberBot/Assets';\n\nexport const useUploadFile = () => {\n const { apiGatewayUrl } = useSubscriberBot();\n const [progress, setProgress] = useState(0);\n const [isUploading, setIsUploading] = useState(false);\n\n const uploadFile = useCallback(\n async (file: File): Promise<{ fileId: string; fileName: string }> => {\n setIsUploading(true);\n setProgress(0);\n try {\n // 1. Resolve (or create) the destination folder — File.folderId is a real FK.\n const folderRes = await subQuery<{ ensureFolderByPath: { id: string } | null }>(\n `mutation SubEnsureFolder($path: String!) {\n ensureFolderByPath(path: $path) { id }\n }`,\n { path: ASSET_FOLDER_PATH },\n apiGatewayUrl\n );\n const folderId = folderRes.ensureFolderByPath?.id;\n if (!folderId) throw new Error('Could not resolve the upload folder.');\n\n const mimeType = file.type || 'application/octet-stream';\n const dotIndex = file.name.lastIndexOf('.');\n const extension = dotIndex > -1 ? file.name.slice(dotIndex + 1) : 'bin';\n\n // 2. Open a presigned upload session.\n const initiated = await subQuery<{\n initiateUpload: { uploadUrl: string | null; session: { id: string } } | null;\n }>(\n `mutation SubInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) {\n uploadUrl\n session { id }\n }\n }`,\n {\n input: {\n fileName: file.name,\n extension,\n mimeType,\n fileSize: String(file.size),\n folderId,\n },\n },\n apiGatewayUrl\n );\n const uploadUrl = initiated.initiateUpload?.uploadUrl;\n const sessionId = initiated.initiateUpload?.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('The files service did not return an upload URL.');\n }\n\n // 3. PUT the raw bytes to storage. Content-Type must match what was signed.\n await new Promise<void>((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('PUT', uploadUrl);\n xhr.setRequestHeader('Content-Type', mimeType);\n xhr.upload.onprogress = (event) => {\n if (event.lengthComputable) {\n setProgress(Math.round((event.loaded / event.total) * 100));\n }\n };\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) resolve();\n else reject(new Error(`Upload to storage failed (${xhr.status}).`));\n };\n xhr.onerror = () => reject(new Error('Upload to storage failed.'));\n xhr.send(file);\n });\n\n // 4. Finalize — creates the File record. fileSize must match initiateUpload.\n const completed = await subQuery<{\n completeUpload: { fileId: string; file: { id: string; name: string } | null } | null;\n }>(\n `mutation SubCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) {\n fileId\n file { id name }\n }\n }`,\n { input: { sessionId, fileSize: String(file.size), folderId } },\n apiGatewayUrl\n );\n const fileId = completed.completeUpload?.file?.id ?? completed.completeUpload?.fileId;\n if (!fileId) throw new Error('The upload could not be finalized.');\n return { fileId, fileName: completed.completeUpload?.file?.name ?? file.name };\n } finally {\n setIsUploading(false);\n }\n },\n [apiGatewayUrl]\n );\n\n return { uploadFile, progress, isUploading };\n};\n\n/**\n * Resolve a short-lived presigned download URL for a `wspace-files-svc` File id.\n * Never select the federated arg-less `File.downloadUrl` (it mints a URL beyond\n * S3's 7-day cap and 500s the response) — use the root `getFileDownloadUrl`\n * query with a TTL under 604800s instead.\n */\nexport const useFileDownloadUrl = () => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useCallback(\n async (fileId: string): Promise<string> => {\n const result = await subQuery<{ getFileDownloadUrl: string }>(\n `query SubFileDownloadUrl($id: ID!, $expiresIn: Int) {\n getFileDownloadUrl(id: $id, expiresIn: $expiresIn)\n }`,\n { id: fileId, expiresIn: 21600 },\n apiGatewayUrl\n );\n return result.getFileDownloadUrl;\n },\n [apiGatewayUrl]\n );\n};\n\n// ============================================================================\n// Providers (the global discovery registry)\n// ============================================================================\n\nexport interface ProviderListFilters {\n category?: SubProviderCategory;\n status?: SubProviderStatus;\n search?: string;\n pagination?: PaginationInput;\n}\n\nexport const useProviders = (filters: ProviderListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.providers, filters],\n queryFn: async () => {\n const result = await subQuery<{ subListProviders: SubConnection<SubProvider> }>(\n `query SubProviders(\n $category: SubProviderCategory\n $status: SubProviderStatus\n $search: String\n $pagination: PaginationInput\n ) {\n subListProviders(\n category: $category\n status: $status\n search: $search\n pagination: $pagination\n ) {\n items { ${PROVIDER_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n category: filters.category,\n status: filters.status,\n search: filters.search,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListProviders;\n },\n });\n};\n\nexport const useProvider = (id: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.provider(id ?? ''),\n enabled: Boolean(id),\n queryFn: async () => {\n const result = await subQuery<{ subProvider: SubProvider | null }>(\n `query SubProvider($id: ID!) {\n subProvider(id: $id) {\n ${PROVIDER_FIELDS}\n plans { ${PLAN_FIELDS} }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subProvider;\n },\n });\n};\n\nexport const useCreateProvider = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateProviderInput) => {\n const result = await subQuery<{ subCreateProvider: SubProvider }>(\n `mutation SubCreateProvider($input: SubCreateProviderInput!) {\n subCreateProvider(input: $input) { ${PROVIDER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateProvider;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.providers });\n },\n });\n};\n\nexport const useUpdateProvider = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: SubUpdateProviderInput }) => {\n const result = await subQuery<{ subUpdateProvider: SubProvider }>(\n `mutation SubUpdateProvider($id: ID!, $input: SubUpdateProviderInput!) {\n subUpdateProvider(id: $id, input: $input) { ${PROVIDER_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.subUpdateProvider;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.providers });\n void queryClient.invalidateQueries({ queryKey: KEY.provider(data.id) });\n },\n });\n};\n\nexport const useArchiveProvider = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subArchiveProvider: boolean }>(\n `mutation SubArchiveProvider($id: ID!) {\n subArchiveProvider(id: $id)\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subArchiveProvider;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.providers });\n },\n });\n};\n\nexport const usePlans = (providerId: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.plans, providerId],\n enabled: Boolean(providerId),\n queryFn: async () => {\n const result = await subQuery<{ subListPlans: SubConnection<SubPlan> }>(\n `query SubPlans($providerId: ID) {\n subListPlans(providerId: $providerId) { items { ${PLAN_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n { providerId },\n apiGatewayUrl\n );\n return result.subListPlans.items;\n },\n });\n};\n\nexport const useCreatePlan = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreatePlanInput) => {\n const result = await subQuery<{ subCreatePlan: SubPlan }>(\n `mutation SubCreatePlan($input: SubCreatePlanInput!) {\n subCreatePlan(input: $input) { ${PLAN_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreatePlan;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.plans });\n void queryClient.invalidateQueries({ queryKey: KEY.provider(data.providerId) });\n },\n });\n};\n\n/**\n * Observed price points for one provider, newest first from the server.\n *\n * Backs the provider \"Price history\" card. The benchmark dataset is read\n * GLOBALLY (`@rbac(..., public: true)` on the svc) — it is the same for every\n * workspace — so nothing here is workspace scoped. Matching is by\n * `providerSlug`, which is an exact match server-side; `providerName` is a\n * fuzzy `contains` match and would risk attributing another vendor's prices to\n * this provider, so the query stays disabled until a slug exists.\n */\nexport const useBenchmarkDataPoints = (providerSlug: string | null | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.benchmarks(providerSlug ?? ''),\n enabled: Boolean(providerSlug),\n queryFn: async () => {\n const filter: SubBenchmarkFilterInput = { providerSlug: providerSlug ?? undefined };\n const result = await subQuery<{\n subListBenchmarkDataPoints: SubConnection<SubBenchmarkDataPoint>;\n }>(\n `query SubBenchmarkDataPoints(\n $filter: SubBenchmarkFilterInput\n $pagination: PaginationInput\n ) {\n subListBenchmarkDataPoints(filter: $filter, pagination: $pagination) {\n items { ${BENCHMARK_DATA_POINT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { filter, pagination: { limit: 100, offset: 0 } },\n apiGatewayUrl\n );\n return result.subListBenchmarkDataPoints.items;\n },\n });\n};\n\n// ============================================================================\n// Universal Inbox\n// ============================================================================\n\nexport interface InboxListFilters {\n category?: SubMessageCategory;\n channelId?: string;\n relationshipId?: string;\n unreadOnly?: boolean;\n pagination?: PaginationInput;\n}\n\nexport const useInboxMessages = (filters: InboxListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.inbox, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListInboxMessages: SubConnection<SubInboxMessage>;\n }>(\n `query SubInboxMessages(\n $category: SubMessageCategory\n $channelId: ID\n $relationshipId: ID\n $unreadOnly: Boolean\n $pagination: PaginationInput\n ) {\n subListInboxMessages(\n category: $category\n channelId: $channelId\n relationshipId: $relationshipId\n unreadOnly: $unreadOnly\n pagination: $pagination\n ) {\n items { ${INBOX_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n category: filters.category,\n channelId: filters.channelId,\n relationshipId: filters.relationshipId,\n unreadOnly: filters.unreadOnly,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListInboxMessages;\n },\n });\n};\n\nexport const useMarkMessageRead = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subMarkMessageRead: SubInboxMessage }>(\n `mutation SubMarkMessageRead($id: ID!) {\n subMarkMessageRead(id: $id) { ${INBOX_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subMarkMessageRead;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.inbox });\n },\n });\n};\n\nexport const useIngestMessage = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubIngestMessageInput) => {\n const result = await subQuery<{ subIngestMessage: SubInboxMessage }>(\n `mutation SubIngestMessage($input: SubIngestMessageInput!) {\n subIngestMessage(input: $input) { ${INBOX_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subIngestMessage;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.inbox });\n },\n });\n};\n\n// ============================================================================\n// Invoices (Universal Billing Layer)\n// ============================================================================\n\nexport interface InvoiceListFilters {\n status?: SubInvoiceStatus;\n relationshipId?: string;\n pagination?: PaginationInput;\n}\n\nexport const useInvoices = (filters: InvoiceListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.invoices, filters],\n queryFn: async () => {\n const result = await subQuery<{ subListInvoices: SubConnection<SubInvoice> }>(\n `query SubInvoices(\n $status: SubInvoiceStatus\n $relationshipId: ID\n $pagination: PaginationInput\n ) {\n subListInvoices(\n status: $status\n relationshipId: $relationshipId\n pagination: $pagination\n ) {\n items { ${INVOICE_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n relationshipId: filters.relationshipId,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListInvoices;\n },\n });\n};\n\nexport const useMarkInvoicePaid = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subMarkInvoicePaid: SubInvoice }>(\n `mutation SubMarkInvoicePaid($id: ID!) {\n subMarkInvoicePaid(id: $id) { ${INVOICE_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subMarkInvoicePaid;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.invoices });\n },\n });\n};\n\nexport const useCreateInvoice = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateInvoiceInput) => {\n const result = await subQuery<{ subCreateInvoice: SubInvoice }>(\n `mutation SubCreateInvoice($input: SubCreateInvoiceInput!) {\n subCreateInvoice(input: $input) { ${INVOICE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateInvoice;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.invoices });\n },\n });\n};\n\n// ============================================================================\n// Payment instruments & communication channels\n// ============================================================================\n\nexport const usePaymentInstruments = (ownerId?: string) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.paymentInstruments, ownerId],\n queryFn: async () => {\n const result = await subQuery<{\n subListPaymentInstruments: SubConnection<SubPaymentInstrument>;\n }>(\n `query SubPaymentInstruments($ownerId: ID) {\n subListPaymentInstruments(ownerId: $ownerId) {\n items {\n id label type status brand last4 expiryMonth expiryYear isDefault\n ownerId workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return result.subListPaymentInstruments.items;\n },\n });\n};\n\nexport const useCreatePaymentInstrument = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreatePaymentInstrumentInput) => {\n const result = await subQuery<{ subCreatePaymentInstrument: SubPaymentInstrument }>(\n `mutation SubCreatePaymentInstrument($input: SubCreatePaymentInstrumentInput!) {\n subCreatePaymentInstrument(input: $input) { ${PAYMENT_INSTRUMENT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreatePaymentInstrument;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.paymentInstruments });\n },\n });\n};\n\nexport const useRemovePaymentInstrument = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subRemovePaymentInstrument: boolean }>(\n `mutation SubRemovePaymentInstrument($id: ID!) {\n subRemovePaymentInstrument(id: $id)\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subRemovePaymentInstrument;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.paymentInstruments });\n },\n });\n};\n\nexport const useChannels = (ownerId?: string) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.channels, ownerId],\n queryFn: async () => {\n const result = await subQuery<{\n subListChannels: SubConnection<SubCommunicationChannel>;\n }>(\n `query SubChannels($ownerId: ID) {\n subListChannels(ownerId: $ownerId) {\n items {\n id label type status address ingestEnabled ownerId verifiedAt\n workspaceId createdAt updatedAt\n }\n pageInfo { cursor hasMore }\n }\n }`,\n { ownerId },\n apiGatewayUrl\n );\n return result.subListChannels.items;\n },\n });\n};\n\nexport const useCreateChannel = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateChannelInput) => {\n const result = await subQuery<{ subCreateChannel: SubCommunicationChannel }>(\n `mutation SubCreateChannel($input: SubCreateChannelInput!) {\n subCreateChannel(input: $input) { ${CHANNEL_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateChannel;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.channels });\n },\n });\n};\n\nexport const useVerifyChannel = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subVerifyChannel: SubCommunicationChannel }>(\n `mutation SubVerifyChannel($id: ID!) {\n subVerifyChannel(id: $id) { ${CHANNEL_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subVerifyChannel;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.channels });\n },\n });\n};\n\n// ============================================================================\n// AI Agents & workflows (automation)\n// ============================================================================\n\nexport interface AgentListFilters {\n kind?: SubAgentKind;\n status?: SubAgentStatus;\n ownerId?: string;\n}\n\nexport const useAgents = (filters: AgentListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.agents, filters],\n queryFn: async () => {\n const result = await subQuery<{ subListAgents: SubConnection<SubAiAgent> }>(\n `query SubAgents($kind: SubAgentKind, $status: SubAgentStatus, $ownerId: ID) {\n subListAgents(kind: $kind, status: $status, ownerId: $ownerId) {\n items { ${AGENT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { kind: filters.kind, status: filters.status, ownerId: filters.ownerId },\n apiGatewayUrl\n );\n return result.subListAgents.items;\n },\n });\n};\n\nexport const useAgent = (id: string | undefined) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: KEY.agent(id ?? ''),\n enabled: Boolean(id),\n queryFn: async () => {\n const result = await subQuery<{ subAgent: SubAiAgent | null }>(\n `query SubAgent($id: ID!) {\n subAgent(id: $id) {\n ${AGENT_FIELDS}\n policies { ${POLICY_FIELDS} }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subAgent;\n },\n });\n};\n\nexport const useCreateAgent = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateAgentInput) => {\n const result = await subQuery<{ subCreateAgent: SubAiAgent }>(\n `mutation SubCreateAgent($input: SubCreateAgentInput!) {\n subCreateAgent(input: $input) { ${AGENT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateAgent;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.agents });\n },\n });\n};\n\nexport const useSetAgentStatus = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: SubAgentStatus }) => {\n const result = await subQuery<{ subSetAgentStatus: SubAiAgent }>(\n `mutation SubSetAgentStatus($id: ID!, $status: SubAgentStatus!) {\n subSetAgentStatus(id: $id, status: $status) { ${AGENT_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.subSetAgentStatus;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.agents });\n void queryClient.invalidateQueries({ queryKey: KEY.agent(data.id) });\n },\n });\n};\n\nexport const useCreatePolicy = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreatePolicyInput) => {\n const result = await subQuery<{ subCreatePolicy: SubPolicy }>(\n `mutation SubCreatePolicy($input: SubCreatePolicyInput!) {\n subCreatePolicy(input: $input) { ${POLICY_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreatePolicy;\n },\n onSuccess: (data) => {\n void queryClient.invalidateQueries({ queryKey: KEY.agents });\n void queryClient.invalidateQueries({ queryKey: KEY.agent(data.agentId) });\n },\n });\n};\n\nexport const useWorkflows = (status?: SubWorkflowStatus) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.workflows, status],\n queryFn: async () => {\n const result = await subQuery<{ subListWorkflows: SubConnection<SubWorkflow> }>(\n `query SubWorkflows($status: SubWorkflowStatus) {\n subListWorkflows(status: $status) { items { ${WORKFLOW_FIELDS} } pageInfo { cursor hasMore } }\n }`,\n { status },\n apiGatewayUrl\n );\n return result.subListWorkflows.items;\n },\n });\n};\n\nexport const useCreateWorkflow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (input: SubCreateWorkflowInput) => {\n const result = await subQuery<{ subCreateWorkflow: SubWorkflow }>(\n `mutation SubCreateWorkflow($input: SubCreateWorkflowInput!) {\n subCreateWorkflow(input: $input) { ${WORKFLOW_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.subCreateWorkflow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.workflows });\n },\n });\n};\n\nexport const useActivateWorkflow = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await subQuery<{ subActivateWorkflow: SubWorkflow }>(\n `mutation SubActivateWorkflow($id: ID!) {\n subActivateWorkflow(id: $id) { ${WORKFLOW_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.subActivateWorkflow;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.workflows });\n },\n });\n};\n\n// ============================================================================\n// Admin governance (adapter approvals + marketplace moderation)\n// ============================================================================\n\nexport interface AdapterSubmissionListFilters {\n status?: SubSubmissionStatus;\n pagination?: PaginationInput;\n}\n\nexport const useAdapterSubmissions = (filters: AdapterSubmissionListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.adapterSubmissions, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListAdapterSubmissions: SubConnection<SubAdapterSubmission>;\n }>(\n `query SubAdapterSubmissions($status: SubSubmissionStatus, $pagination: PaginationInput) {\n subListAdapterSubmissions(status: $status, pagination: $pagination) {\n items { ${ADAPTER_SUBMISSION_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListAdapterSubmissions;\n },\n });\n};\n\nexport const useApproveAdapter = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, notes }: { id: string; notes?: string }) => {\n const result = await subQuery<{ subApproveAdapter: SubAdapterSubmission }>(\n `mutation SubApproveAdapter($id: ID!, $notes: String) {\n subApproveAdapter(id: $id, notes: $notes) { ${ADAPTER_SUBMISSION_FIELDS} }\n }`,\n { id, notes },\n apiGatewayUrl\n );\n return result.subApproveAdapter;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.adapterSubmissions });\n },\n });\n};\n\nexport const useRejectAdapter = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({ id, reason }: { id: string; reason: string }) => {\n const result = await subQuery<{ subRejectAdapter: SubAdapterSubmission }>(\n `mutation SubRejectAdapter($id: ID!, $reason: String!) {\n subRejectAdapter(id: $id, reason: $reason) { ${ADAPTER_SUBMISSION_FIELDS} }\n }`,\n { id, reason },\n apiGatewayUrl\n );\n return result.subRejectAdapter;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.adapterSubmissions });\n },\n });\n};\n\nexport interface MarketplaceReportListFilters {\n status?: SubReportStatus;\n pagination?: PaginationInput;\n}\n\nexport const useMarketplaceReports = (filters: MarketplaceReportListFilters = {}) => {\n const { apiGatewayUrl } = useSubscriberBot();\n return useQuery({\n queryKey: [...KEY.marketplaceReports, filters],\n queryFn: async () => {\n const result = await subQuery<{\n subListMarketplaceReports: SubConnection<SubMarketplaceReport>;\n }>(\n `query SubMarketplaceReports($status: SubReportStatus, $pagination: PaginationInput) {\n subListMarketplaceReports(status: $status, pagination: $pagination) {\n items { ${MARKETPLACE_REPORT_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n pagination: filters.pagination ?? { limit: 50, offset: 0 },\n },\n apiGatewayUrl\n );\n return result.subListMarketplaceReports;\n },\n });\n};\n\nexport const useModerateListing = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useSubscriberBot();\n return useMutation({\n mutationFn: async ({\n id,\n action,\n reason,\n }: {\n id: string;\n action: SubModerationAction;\n reason: string;\n }) => {\n const result = await subQuery<{ subModerateListing: SubMarketplaceReport }>(\n `mutation SubModerateListing($id: ID!, $action: SubModerationAction!, $reason: String!) {\n subModerateListing(id: $id, action: $action, reason: $reason) { ${MARKETPLACE_REPORT_FIELDS} }\n }`,\n { id, action, reason },\n apiGatewayUrl\n );\n return result.subModerateListing;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: KEY.marketplaceReports });\n },\n });\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/subscriberbot/pages/relationships/RelationshipDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkzBH,wBAAgB,sBAAsB,gCA0erC"}
1
+ {"version":3,"file":"RelationshipDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/subscriberbot/pages/relationships/RelationshipDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAy1BH,wBAAgB,sBAAsB,gCAqhBrC"}
@@ -590,6 +590,28 @@ function le({ asset: e }) {
590
590
  })]
591
591
  });
592
592
  }
593
+ function ue({ invoice: e }) {
594
+ let t = T(), a = e.number ?? t("relationships.detail.invoiceRow.unnumbered", "Unnumbered invoice");
595
+ return /* @__PURE__ */ B("div", {
596
+ className: "flex items-center justify-between gap-3 p-3",
597
+ children: [/* @__PURE__ */ B("div", {
598
+ className: "flex min-w-0 items-center gap-2",
599
+ children: [/* @__PURE__ */ z(j, { className: "h-4 w-4 shrink-0 text-text-secondary" }), /* @__PURE__ */ B("div", {
600
+ className: "min-w-0",
601
+ children: [/* @__PURE__ */ z("p", {
602
+ className: "truncate text-sm font-medium text-text-primary",
603
+ children: a
604
+ }), /* @__PURE__ */ B("p", {
605
+ className: "text-xs text-text-secondary",
606
+ children: [i(e.status), e.dueDate ? ` · ${t("relationships.detail.invoiceRow.due", "due {{date}}", { date: r(e.dueDate) })}` : e.issueDate ? ` · ${r(e.issueDate)}` : ""]
607
+ })]
608
+ })]
609
+ }), /* @__PURE__ */ z("span", {
610
+ className: "shrink-0 text-sm font-medium tabular-nums text-text-primary",
611
+ children: n(e.total, e.currency)
612
+ })]
613
+ });
614
+ }
593
615
  function X() {
594
616
  let c = T(), { id: g } = ne(), { navigateTo: _ } = e(), { data: v, isLoading: y, isError: b, refetch: C } = x(g), w = S(), M = h(), [N, P] = E(null), [I, H] = E(!1), [U, W] = E(!1), [G, K] = E(!1);
595
617
  if (y) return /* @__PURE__ */ z(t, {
@@ -617,12 +639,12 @@ function X() {
617
639
  })
618
640
  })
619
641
  });
620
- let Y = v, X = w.isPending || M.isPending, ue = (e) => {
642
+ let Y = v, X = w.isPending || M.isPending, de = (e) => {
621
643
  P(null), w.mutate({
622
644
  id: Y.id,
623
645
  status: e
624
646
  }, { onError: (e) => P(e instanceof Error ? e.message : c("relationships.detail.transitionError", "Transition failed")) });
625
- }, de = () => {
647
+ }, fe = () => {
626
648
  P(null), M.mutate(Y.id, { onError: (e) => P(e instanceof Error ? e.message : c("relationships.detail.cancelError", "Cancel failed")) });
627
649
  }, Z = [...Y.renewalEvents ?? []].sort((e, t) => new Date(e.occursAt).getTime() - new Date(t.occursAt).getTime()).map((e) => {
628
650
  let t = new Date(e.occursAt).getTime(), a = !Number.isNaN(t) && t > Date.now();
@@ -638,7 +660,7 @@ function X() {
638
660
  }) : /* @__PURE__ */ z("span", {
639
661
  className: "inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
640
662
  children: c("relationships.detail.autoRenewOff", "Off")
641
- }), fe = ie.filter((e) => e.status !== Y.status), $ = Y.plan?.features ?? [];
663
+ }), pe = ie.filter((e) => e.status !== Y.status), $ = Y.plan?.features ?? [];
642
664
  return /* @__PURE__ */ B(t, {
643
665
  title: Y.label,
644
666
  description: Y.provider?.name ?? c(q[Y.kind], i(Y.kind)),
@@ -719,12 +741,12 @@ function X() {
719
741
  ]
720
742
  }), /* @__PURE__ */ B("div", {
721
743
  className: "flex shrink-0 flex-wrap gap-2 lg:flex-col lg:items-stretch",
722
- children: [fe.map((e) => {
744
+ children: [pe.map((e) => {
723
745
  let t = e.icon;
724
746
  return /* @__PURE__ */ B("button", {
725
747
  type: "button",
726
748
  disabled: X,
727
- onClick: () => ue(e.status),
749
+ onClick: () => de(e.status),
728
750
  className: "inline-flex items-center justify-center gap-1.5 rounded-lg border border-border-subtle bg-bg-surface px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50",
729
751
  children: [
730
752
  /* @__PURE__ */ z(t, { className: "h-3.5 w-3.5" }),
@@ -735,7 +757,7 @@ function X() {
735
757
  }), Y.status !== "CANCELLED" && /* @__PURE__ */ B("button", {
736
758
  type: "button",
737
759
  disabled: X,
738
- onClick: de,
760
+ onClick: fe,
739
761
  className: "inline-flex items-center justify-center gap-1.5 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-3 py-1.5 text-xs font-medium text-status-error-text hover:opacity-90 disabled:opacity-50",
740
762
  children: [
741
763
  /* @__PURE__ */ z(k, { className: "h-3.5 w-3.5" }),
@@ -914,15 +936,26 @@ function X() {
914
936
  c("relationships.detail.sections.attachAsset", "Attach asset")
915
937
  ]
916
938
  }),
917
- children: !Y.assets || Y.assets.length === 0 ? /* @__PURE__ */ z(s, {
918
- illustration: "empty-data",
919
- title: c("relationships.detail.empty.noAssetsTitle", "No assets attached"),
920
- description: c("relationships.detail.empty.noAssetsDescription", "Attach invoices, contracts, licenses or receipts to this relationship.")
921
- }) : /* @__PURE__ */ z(V, {
922
- treatment: "plain",
923
- className: "divide-y divide-border-subtle p-0",
924
- children: Y.assets.map((e) => /* @__PURE__ */ z(le, { asset: e }, e.id))
925
- })
939
+ children: (() => {
940
+ let e = Y.assets ?? [], t = Y.invoices ?? [];
941
+ return e.length > 0 || t.length > 0 ? /* @__PURE__ */ z(V, {
942
+ treatment: "plain",
943
+ className: "divide-y divide-border-subtle p-0",
944
+ children: [...e.map((e) => ({
945
+ kind: "asset",
946
+ sort: new Date(e.createdAt).getTime() || 0,
947
+ asset: e
948
+ })), ...t.map((e) => ({
949
+ kind: "invoice",
950
+ sort: new Date(e.createdAt).getTime() || 0,
951
+ invoice: e
952
+ }))].sort((e, t) => t.sort - e.sort).map((e) => e.kind === "asset" ? /* @__PURE__ */ z(le, { asset: e.asset }, `a-${e.asset.id}`) : /* @__PURE__ */ z(ue, { invoice: e.invoice }, `i-${e.invoice.id}`))
953
+ }) : /* @__PURE__ */ z(s, {
954
+ illustration: "empty-data",
955
+ title: c("relationships.detail.empty.noAssetsTitle", "No assets attached"),
956
+ description: c("relationships.detail.empty.noAssetsDescription", "Attach invoices, contracts, licenses or receipts to this relationship.")
957
+ });
958
+ })()
926
959
  }),
927
960
  Y.notes && /* @__PURE__ */ B(V, {
928
961
  treatment: "plain",
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipDetailPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/relationships/RelationshipDetailPage.tsx"],"sourcesContent":["/**\n * Relationship detail\n * @module subscriberbot/pages/relationships\n *\n * Full per-relationship view: plan, price, billing period, next renewal,\n * health score, entitlements, attached assets and renewal events — plus\n * lifecycle transitions (validated server-side), edit, and cancel.\n * Reads `subRelationship(id)`; writes `subTransitionRelationship`,\n * `subCancelRelationship`, `subUpdateRelationship`, `subCreateEntitlement`,\n * `subCreateAsset`.\n */\n\nimport { useState, type ReactNode } from 'react';\nimport { useParams } from 'react-router';\nimport {\n ArrowLeft,\n CreditCard,\n Wallet,\n ShieldCheck,\n CalendarClock,\n Paperclip,\n Activity,\n Tag,\n Pencil,\n Plus,\n Pause,\n Play,\n Ban,\n Download,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Modal } from '../../components/Modal';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { Gauge, Timeline, MiniProgress } from '../../components';\nimport type { TimelineItem } from '../../components';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport {\n useRelationship,\n useTransitionRelationship,\n useCancelRelationship,\n useUpdateRelationship,\n useCreateEntitlement,\n useCreateAsset,\n useUploadFile,\n useFileDownloadUrl,\n useProviders,\n usePlans,\n} from '../../hooks/useSubscriberBotApi';\nimport {\n formatCurrency,\n formatDate,\n formatEnumLabel,\n formatIntervalSuffix,\n} from '../../utils/formatters';\nimport { useTr } from '../../hooks/useTr';\nimport type {\n SubAssetType,\n SubBillingInterval,\n SubEntitlementType,\n SubRelationship,\n SubRelationshipKind,\n SubRelationshipStatus,\n SubUpdateRelationshipInput,\n} from '../../types';\n\nconst inputCls =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelCls = 'mb-1 block text-xs font-medium text-text-secondary';\n\nconst INTERVALS: SubBillingInterval[] = [\n 'MONTHLY',\n 'YEARLY',\n 'QUARTERLY',\n 'WEEKLY',\n 'DAILY',\n 'USAGE_BASED',\n 'LIFETIME',\n 'FREE',\n];\n\nconst ENTITLEMENT_TYPES: SubEntitlementType[] = [\n 'FEATURE_ACCESS',\n 'SEAT',\n 'USAGE_QUOTA',\n 'CONTENT',\n 'DISCOUNT',\n 'SUPPORT_TIER',\n];\n\nconst ASSET_TYPES: SubAssetType[] = [\n 'RECEIPT',\n 'INVOICE',\n 'CONTRACT',\n 'LICENSE_KEY',\n 'CREDENTIAL',\n 'CERTIFICATE',\n 'WARRANTY',\n 'DOMAIN',\n];\n\nconst KIND_KEY: Record<SubRelationshipKind, string> = {\n SUBSCRIPTION: 'relationships.kinds.subscription',\n MEMBERSHIP: 'relationships.kinds.membership',\n LICENSE: 'relationships.kinds.license',\n CONTRACT: 'relationships.kinds.contract',\n NEWSLETTER: 'relationships.kinds.newsletter',\n RECURRING_PAYMENT: 'relationships.kinds.recurringPayment',\n ENROLLMENT: 'relationships.kinds.enrollment',\n TRIAL: 'relationships.kinds.trial',\n};\n\n// Lifecycle actions surfaced as buttons; the server validates the transition.\nconst TRANSITIONS: Array<{\n status: SubRelationshipStatus;\n labelKey: string;\n defaultLabel: string;\n icon: typeof Play;\n}> = [\n {\n status: 'ACTIVE',\n labelKey: 'relationships.detail.actions.activate',\n defaultLabel: 'Activate',\n icon: Play,\n },\n {\n status: 'PAUSED',\n labelKey: 'relationships.detail.actions.pause',\n defaultLabel: 'Pause',\n icon: Pause,\n },\n {\n status: 'EXPIRED',\n labelKey: 'relationships.detail.actions.markExpired',\n defaultLabel: 'Mark expired',\n icon: Ban,\n },\n];\n\n/** Compact label/value row for the detail info cards. */\nfunction InfoRow({ label, value }: { label: string; value: ReactNode }) {\n return (\n <div className=\"flex items-center justify-between gap-3 border-b border-border-subtle/60 py-2.5 last:border-0 last:pb-0\">\n <span className=\"shrink-0 text-sm text-text-secondary\">{label}</span>\n <span className=\"min-w-0 truncate text-right text-sm font-medium text-text-primary\">\n {value}\n </span>\n </div>\n );\n}\n\n/** Map a 0–100 health score onto a MiniProgress tone. */\nfunction healthTone(\n score: number | null | undefined\n): 'positive' | 'accent' | 'warning' | 'negative' {\n if (score == null) return 'accent';\n if (score >= 66) return 'positive';\n if (score >= 33) return 'warning';\n return 'negative';\n}\n\n/** ISO string → yyyy-mm-dd for a native <input type=\"date\">. */\nfunction toDateInputValue(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toISOString().slice(0, 10);\n}\n\n// ---------------------------------------------------------------------------\n// Edit relationship modal → subUpdateRelationship\n// ---------------------------------------------------------------------------\n\nfunction RelationshipEditModal({\n relationship,\n onClose,\n}: {\n relationship: SubRelationship;\n onClose: () => void;\n}) {\n const tr = useTr();\n const update = useUpdateRelationship();\n const providersQ = useProviders({ pagination: { limit: 100, offset: 0 } });\n\n const [label, setLabel] = useState(relationship.label);\n const [providerId, setProviderId] = useState(relationship.providerId ?? '');\n const [planId, setPlanId] = useState(relationship.planId ?? '');\n const [amount, setAmount] = useState(String(relationship.amount ?? ''));\n const [currency, setCurrency] = useState(relationship.currency);\n const [interval, setInterval] = useState<SubBillingInterval>(relationship.interval);\n const [renewsAt, setRenewsAt] = useState(toDateInputValue(relationship.renewsAt));\n const [autoRenew, setAutoRenew] = useState(relationship.autoRenew);\n const [healthScore, setHealthScore] = useState(\n relationship.healthScore != null ? String(relationship.healthScore) : ''\n );\n const [notes, setNotes] = useState(relationship.notes ?? '');\n const [formError, setFormError] = useState<string | null>(null);\n\n const plansQ = usePlans(providerId || undefined);\n\n // Ensure the currently-linked provider is always selectable even if it isn't\n // in the first page of the registry.\n const providerOptions = (() => {\n const list = providersQ.data?.items ?? [];\n if (relationship.provider && !list.some((p) => p.id === relationship.provider?.id)) {\n return [relationship.provider, ...list];\n }\n return list;\n })();\n const plans = plansQ.data ?? [];\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!label.trim()) {\n setFormError(tr('relationships.detail.editModal.labelRequired', 'A label is required.'));\n return;\n }\n const input: SubUpdateRelationshipInput = {\n label: label.trim(),\n interval,\n autoRenew,\n currency: currency.trim() || 'USD',\n notes: notes.trim(),\n ...(providerId ? { providerId } : {}),\n ...(planId ? { planId } : {}),\n ...(amount.trim() ? { amount: Number(amount) } : {}),\n ...(healthScore.trim() ? { healthScore: Number(healthScore) } : {}),\n ...(renewsAt ? { renewsAt: new Date(renewsAt).toISOString() } : {}),\n };\n update.mutate(\n { id: relationship.id, input },\n {\n onSuccess: () => onClose(),\n onError: (err) =>\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.detail.editModal.error', 'Could not update relationship.')\n ),\n }\n );\n };\n\n return (\n <Modal\n title={tr('relationships.detail.editModal.title', 'Edit relationship')}\n onClose={onClose}\n maxWidthClassName=\"max-w-2xl\"\n >\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n\n <div>\n <label htmlFor=\"edit-label\" className={labelCls}>\n {tr('relationships.detail.editModal.labelLabel', 'Label')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"edit-label\"\n type=\"text\"\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n className={inputCls}\n required\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"edit-provider\" className={labelCls}>\n {tr('relationships.detail.editModal.providerLabel', 'Provider')}\n </label>\n <select\n id=\"edit-provider\"\n value={providerId}\n onChange={(e) => {\n setProviderId(e.target.value);\n setPlanId('');\n }}\n className={inputCls}\n >\n <option value=\"\">\n {tr('relationships.detail.editModal.providerNone', '— None —')}\n </option>\n {providerOptions.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"edit-plan\" className={labelCls}>\n {tr('relationships.detail.editModal.planLabel', 'Plan')}\n </label>\n <select\n id=\"edit-plan\"\n value={planId}\n onChange={(e) => setPlanId(e.target.value)}\n className={inputCls}\n disabled={!providerId || plans.length === 0}\n >\n <option value=\"\">{tr('relationships.detail.editModal.planNone', '— None —')}</option>\n {plans.map((pl) => (\n <option key={pl.id} value={pl.id}>\n {pl.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"edit-amount\" className={labelCls}>\n {tr('relationships.detail.editModal.amountLabel', 'Amount')}\n </label>\n <input\n id=\"edit-amount\"\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n value={amount}\n onChange={(e) => setAmount(e.target.value)}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"edit-currency\" className={labelCls}>\n {tr('relationships.detail.editModal.currencyLabel', 'Currency')}\n </label>\n <input\n id=\"edit-currency\"\n type=\"text\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n maxLength={3}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"edit-interval\" className={labelCls}>\n {tr('relationships.detail.editModal.intervalLabel', 'Billing interval')}\n </label>\n <select\n id=\"edit-interval\"\n value={interval}\n onChange={(e) => setInterval(e.target.value as SubBillingInterval)}\n className={inputCls}\n >\n {INTERVALS.map((i) => (\n <option key={i} value={i}>\n {i.replace(/_/g, ' ')}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"edit-renews\" className={labelCls}>\n {tr('relationships.detail.editModal.renewsOnLabel', 'Renews on')}\n </label>\n <input\n id=\"edit-renews\"\n type=\"date\"\n value={renewsAt}\n onChange={(e) => setRenewsAt(e.target.value)}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"edit-health\" className={labelCls}>\n {tr('relationships.detail.editModal.healthScoreLabel', 'Health score (0–100)')}\n </label>\n <input\n id=\"edit-health\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n value={healthScore}\n onChange={(e) => setHealthScore(e.target.value)}\n className={inputCls}\n />\n </div>\n <div className=\"flex items-end\">\n <label className=\"flex items-center gap-2 text-sm text-text-primary\">\n <input\n type=\"checkbox\"\n checked={autoRenew}\n onChange={(e) => setAutoRenew(e.target.checked)}\n className=\"size-4 rounded border-border-subtle\"\n />\n {tr('relationships.detail.editModal.autoRenews', 'Auto-renews')}\n </label>\n </div>\n </div>\n\n <div>\n <label htmlFor=\"edit-notes\" className={labelCls}>\n {tr('relationships.detail.editModal.notesLabel', 'Notes')}\n </label>\n <textarea\n id=\"edit-notes\"\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n rows={3}\n className={inputCls}\n />\n </div>\n\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.detail.editModal.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={update.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {update.isPending\n ? tr('relationships.detail.editModal.saving', 'Saving…')\n : tr('relationships.detail.editModal.submit', 'Save changes')}\n </button>\n </div>\n </form>\n </Modal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Add entitlement modal → subCreateEntitlement\n// ---------------------------------------------------------------------------\n\nfunction AddEntitlementModal({\n relationshipId,\n onClose,\n}: {\n relationshipId: string;\n onClose: () => void;\n}) {\n const tr = useTr();\n const create = useCreateEntitlement();\n const [name, setName] = useState('');\n const [type, setType] = useState<SubEntitlementType>('FEATURE_ACCESS');\n const [quota, setQuota] = useState('');\n const [unit, setUnit] = useState('');\n const [description, setDescription] = useState('');\n const [formError, setFormError] = useState<string | null>(null);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!name.trim()) {\n setFormError(\n tr(\n 'relationships.detail.addEntitlementModal.nameRequired',\n 'An entitlement name is required.'\n )\n );\n return;\n }\n create.mutate(\n {\n relationshipId,\n name: name.trim(),\n type,\n ...(quota.trim() ? { quota: Number(quota) } : {}),\n ...(unit.trim() ? { unit: unit.trim() } : {}),\n ...(description.trim() ? { description: description.trim() } : {}),\n },\n {\n onSuccess: () => onClose(),\n onError: (err) =>\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.detail.addEntitlementModal.error', 'Could not add entitlement.')\n ),\n }\n );\n };\n\n return (\n <Modal\n title={tr('relationships.detail.addEntitlementModal.title', 'Add entitlement')}\n onClose={onClose}\n >\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n <div>\n <label htmlFor=\"ent-name\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.nameLabel', 'Name')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"ent-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n 'relationships.detail.addEntitlementModal.namePlaceholder',\n 'e.g. Seats, API calls, Priority support'\n )}\n className={inputCls}\n required\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"ent-type\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.typeLabel', 'Type')}\n </label>\n <select\n id=\"ent-type\"\n value={type}\n onChange={(e) => setType(e.target.value as SubEntitlementType)}\n className={inputCls}\n >\n {ENTITLEMENT_TYPES.map((t) => (\n <option key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"ent-quota\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.quotaLabel', 'Quota')}\n </label>\n <input\n id=\"ent-quota\"\n type=\"number\"\n min=\"0\"\n value={quota}\n onChange={(e) => setQuota(e.target.value)}\n placeholder={tr(\n 'relationships.detail.addEntitlementModal.quotaPlaceholder',\n 'e.g. 5'\n )}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"ent-unit\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.unitLabel', 'Unit')}\n </label>\n <input\n id=\"ent-unit\"\n type=\"text\"\n value={unit}\n onChange={(e) => setUnit(e.target.value)}\n placeholder={tr(\n 'relationships.detail.addEntitlementModal.unitPlaceholder',\n 'e.g. seats, GB'\n )}\n className={inputCls}\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"ent-desc\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.descriptionLabel', 'Description')}\n </label>\n <textarea\n id=\"ent-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n className={inputCls}\n />\n </div>\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.detail.addEntitlementModal.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={create.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {create.isPending\n ? tr('relationships.detail.addEntitlementModal.adding', 'Adding…')\n : tr('relationships.detail.addEntitlementModal.submit', 'Add entitlement')}\n </button>\n </div>\n </form>\n </Modal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Attach asset modal → upload to files-svc, then subCreateAsset\n// ---------------------------------------------------------------------------\n\nfunction AttachAssetModal({\n relationshipId,\n onClose,\n}: {\n relationshipId: string;\n onClose: () => void;\n}) {\n const tr = useTr();\n const create = useCreateAsset();\n const { uploadFile, progress, isUploading } = useUploadFile();\n const [name, setName] = useState('');\n const [type, setType] = useState<SubAssetType>('RECEIPT');\n const [file, setFile] = useState<File | null>(null);\n const [expiresAt, setExpiresAt] = useState('');\n const [formError, setFormError] = useState<string | null>(null);\n\n const busy = isUploading || create.isPending;\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!file) {\n setFormError(\n tr('relationships.detail.attachAssetModal.chooseFile', 'Choose a file to attach.')\n );\n return;\n }\n try {\n const { fileId, fileName } = await uploadFile(file);\n await create.mutateAsync({\n relationshipId,\n name: name.trim() || fileName,\n type,\n fileId,\n ...(expiresAt ? { expiresAt: new Date(expiresAt).toISOString() } : {}),\n });\n onClose();\n } catch (err) {\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.detail.attachAssetModal.error', 'Could not attach the asset.')\n );\n }\n };\n\n return (\n <Modal\n title={tr('relationships.detail.attachAssetModal.title', 'Attach asset')}\n onClose={onClose}\n >\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n <div>\n <label htmlFor=\"asset-file\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.fileLabel', 'File')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"asset-file\"\n type=\"file\"\n onChange={(e) => {\n const f = e.target.files?.[0] ?? null;\n setFile(f);\n if (f && !name.trim()) setName(f.name);\n }}\n className=\"w-full text-sm text-text-secondary file:mr-3 file:rounded-lg file:border file:border-border-subtle file:bg-bg-surface file:px-3 file:py-1.5 file:text-sm file:font-medium file:text-text-primary hover:file:bg-bg-sunken\"\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n {tr(\n 'relationships.detail.attachAssetModal.fileHint',\n 'Stored securely in files — only a reference is kept here.'\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"asset-name\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.nameLabel', 'Name')}\n </label>\n <input\n id=\"asset-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n 'relationships.detail.attachAssetModal.namePlaceholder',\n 'Defaults to the file name'\n )}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"asset-type\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.typeLabel', 'Type')}\n </label>\n <select\n id=\"asset-type\"\n value={type}\n onChange={(e) => setType(e.target.value as SubAssetType)}\n className={inputCls}\n >\n {ASSET_TYPES.map((t) => (\n <option key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div>\n <label htmlFor=\"asset-expires\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.expiresOnLabel', 'Expires on')}\n </label>\n <input\n id=\"asset-expires\"\n type=\"date\"\n value={expiresAt}\n onChange={(e) => setExpiresAt(e.target.value)}\n className={inputCls}\n />\n </div>\n {isUploading && (\n <p className=\"text-xs text-text-secondary\">\n {tr('relationships.detail.attachAssetModal.uploading', 'Uploading… {{progress}}%', {\n progress,\n })}\n </p>\n )}\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.detail.attachAssetModal.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={busy}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {busy\n ? tr('relationships.detail.attachAssetModal.attaching', 'Attaching…')\n : tr('relationships.detail.attachAssetModal.submit', 'Attach asset')}\n </button>\n </div>\n </form>\n </Modal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Asset row — resolves a presigned download URL on demand\n// ---------------------------------------------------------------------------\n\nfunction AssetRow({ asset }: { asset: NonNullable<SubRelationship['assets']>[number] }) {\n const tr = useTr();\n const getDownloadUrl = useFileDownloadUrl();\n const [downloading, setDownloading] = useState(false);\n\n const handleDownload = async () => {\n if (!asset.file?.id) return;\n setDownloading(true);\n try {\n const url = await getDownloadUrl(asset.file.id);\n window.open(url, '_blank', 'noopener,noreferrer');\n } catch {\n // Non-fatal: a broken/expired file reference just can't be downloaded.\n } finally {\n setDownloading(false);\n }\n };\n\n return (\n <div className=\"flex items-center justify-between gap-3 p-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Paperclip className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{formatEnumLabel(asset.type)}</p>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-3\">\n {asset.expiresAt && (\n <span className=\"text-xs text-text-secondary\">\n {tr('relationships.detail.assetRow.expires', 'Expires {{date}}', {\n date: formatDate(asset.expiresAt),\n })}\n </span>\n )}\n {asset.file?.id && (\n <button\n type=\"button\"\n onClick={handleDownload}\n disabled={downloading}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-subtle px-2.5 py-1 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Download className=\"h-3.5 w-3.5\" />{' '}\n {downloading\n ? tr('relationships.detail.assetRow.opening', 'Opening…')\n : tr('relationships.detail.assetRow.download', 'Download')}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport function RelationshipDetailPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useSubscriberBot();\n const { data: relationship, isLoading, isError, refetch } = useRelationship(id);\n const transition = useTransitionRelationship();\n const cancel = useCancelRelationship();\n const [actionError, setActionError] = useState<string | null>(null);\n const [showEdit, setShowEdit] = useState(false);\n const [showAddEntitlement, setShowAddEntitlement] = useState(false);\n const [showAttachAsset, setShowAttachAsset] = useState(false);\n\n if (isLoading) {\n return (\n <PageLayout title={tr('relationships.title', 'Relationship')}>\n <LoadingView label={tr('relationships.detail.loading', 'Loading relationship…')} />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title={tr('relationships.title', 'Relationship')}>\n <ErrorView\n message={tr('relationships.detail.error', 'Could not load this relationship.')}\n onRetry={() => void refetch()}\n />\n </PageLayout>\n );\n }\n\n if (!relationship) {\n return (\n <PageLayout title={tr('relationships.title', 'Relationship')}>\n <EmptyState\n illustration=\"empty-data\"\n title={tr('relationships.detail.notFoundTitle', 'Relationship not found')}\n description={tr(\n 'relationships.detail.notFoundDescription',\n 'It may have been removed, or you may not have access to it.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n {tr('relationships.detail.backToRelationships', 'Back to relationships')}\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n const r = relationship;\n const isBusy = transition.isPending || cancel.isPending;\n\n const runTransition = (status: SubRelationshipStatus) => {\n setActionError(null);\n transition.mutate(\n { id: r.id, status },\n {\n onError: (e) =>\n setActionError(\n e instanceof Error\n ? e.message\n : tr('relationships.detail.transitionError', 'Transition failed')\n ),\n }\n );\n };\n\n const runCancel = () => {\n setActionError(null);\n cancel.mutate(r.id, {\n onError: (e) =>\n setActionError(\n e instanceof Error ? e.message : tr('relationships.detail.cancelError', 'Cancel failed')\n ),\n });\n };\n\n // Renewal timeline — built entirely from the real renewalEvents, oldest → newest.\n const renewalTimeline: TimelineItem[] = [...(r.renewalEvents ?? [])]\n .sort((a, b) => new Date(a.occursAt).getTime() - new Date(b.occursAt).getTime())\n .map((event) => {\n const ts = new Date(event.occursAt).getTime();\n const isFuture = !Number.isNaN(ts) && ts > Date.now();\n return {\n title: formatEnumLabel(event.eventType),\n sub: `${formatDate(event.occursAt)}${event.detail ? ` · ${event.detail}` : ''}`,\n meta:\n event.amount != null\n ? formatCurrency(event.amount, event.currency ?? r.currency)\n : undefined,\n tone: isFuture ? 'warning' : 'muted',\n };\n });\n\n const autoRenewPill = r.autoRenew ? (\n <span className=\"inline-flex items-center rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-xs font-medium text-status-success-text\">\n {tr('relationships.detail.autoRenewOn', 'On')}\n </span>\n ) : (\n <span className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {tr('relationships.detail.autoRenewOff', 'Off')}\n </span>\n );\n\n const availableTransitions = TRANSITIONS.filter((t) => t.status !== r.status);\n const planFeatures = r.plan?.features ?? [];\n\n return (\n <PageLayout\n title={r.label}\n description={r.provider?.name ?? tr(KIND_KEY[r.kind], formatEnumLabel(r.kind))}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setShowEdit(true)}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <Pencil className=\"h-4 w-4\" /> {tr('relationships.detail.edit', 'Edit')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> {tr('relationships.detail.back', 'Back')}\n </button>\n </div>\n }\n >\n {/* Hero summary + lifecycle actions */}\n <GlassCard treatment=\"glass\" glow className=\"p-5 sm:p-6\">\n <div className=\"flex flex-col gap-5 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr(KIND_KEY[r.kind], formatEnumLabel(r.kind))}\n </p>\n <div className=\"mt-2 flex flex-wrap items-center gap-3\">\n <span className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {formatCurrency(r.amount, r.currency)}\n <span className=\"text-base font-normal text-text-secondary\">\n {formatIntervalSuffix(r.interval)}\n </span>\n </span>\n <StatusBadge status={r.status} />\n </div>\n <div className=\"mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-text-secondary\">\n <span className=\"inline-flex items-center gap-1.5\">\n <CalendarClock className=\"h-3.5 w-3.5\" />\n {r.renewsAt\n ? tr('relationships.detail.renews', 'Renews {{date}}', {\n date: formatDate(r.renewsAt),\n })\n : tr('relationships.detail.noRenewalScheduled', 'No renewal scheduled')}\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n <ShieldCheck className=\"h-3.5 w-3.5\" />\n {formatEnumLabel(r.discoverySource)}\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n {tr('relationships.detail.autoRenew', 'Auto-renew')} {autoRenewPill}\n </span>\n </div>\n {r.tags.length > 0 && (\n <div className=\"mt-3 flex flex-wrap items-center gap-2\">\n <Tag className=\"h-3.5 w-3.5 text-text-secondary\" />\n {r.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n </div>\n\n {/* Lifecycle actions */}\n <div className=\"flex shrink-0 flex-wrap gap-2 lg:flex-col lg:items-stretch\">\n {availableTransitions.map((t) => {\n const Icon = t.icon;\n return (\n <button\n key={t.status}\n type=\"button\"\n disabled={isBusy}\n onClick={() => runTransition(t.status)}\n className=\"inline-flex items-center justify-center gap-1.5 rounded-lg border border-border-subtle bg-bg-surface px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Icon className=\"h-3.5 w-3.5\" /> {tr(t.labelKey, t.defaultLabel)}\n </button>\n );\n })}\n {r.status !== 'CANCELLED' && (\n <button\n type=\"button\"\n disabled={isBusy}\n onClick={runCancel}\n className=\"inline-flex items-center justify-center gap-1.5 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-3 py-1.5 text-xs font-medium text-status-error-text hover:opacity-90 disabled:opacity-50\"\n >\n <Ban className=\"h-3.5 w-3.5\" />{' '}\n {tr('relationships.detail.actions.cancel', 'Cancel')}\n </button>\n )}\n </div>\n </div>\n </GlassCard>\n\n {actionError && (\n <div className=\"mt-4 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {actionError}\n </div>\n )}\n\n {/* Main layout: details (left) + health & timeline rail (right) */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <div className=\"space-y-4 lg:col-span-2\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n {/* Plan & pricing */}\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <CreditCard className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.planPricing', 'Plan & pricing')}\n </div>\n <div className=\"mt-3\">\n <InfoRow\n label={tr('relationships.detail.info.plan', 'Plan')}\n value={r.plan?.name ?? '—'}\n />\n <InfoRow\n label={tr('relationships.detail.info.price', 'Price')}\n value={\n <>\n {formatCurrency(r.amount, r.currency)}\n <span className=\"font-normal text-text-secondary\">\n {formatIntervalSuffix(r.interval)}\n </span>\n </>\n }\n />\n <InfoRow\n label={tr('relationships.detail.info.billingInterval', 'Billing interval')}\n value={formatEnumLabel(r.interval)}\n />\n <InfoRow\n label={tr('relationships.detail.info.provider', 'Provider')}\n value={r.provider?.name ?? '—'}\n />\n </div>\n {planFeatures.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {planFeatures.map((f) => (\n <span\n key={f}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary\"\n >\n {f}\n </span>\n ))}\n </div>\n )}\n </GlassCard>\n\n {/* Payment & billing */}\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Wallet className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.paymentBilling', 'Payment & billing')}\n </div>\n <div className=\"mt-3\">\n <InfoRow\n label={tr('relationships.detail.info.currency', 'Currency')}\n value={r.currency}\n />\n <InfoRow\n label={tr('relationships.detail.info.autoRenew', 'Auto-renew')}\n value={autoRenewPill}\n />\n <InfoRow\n label={tr('relationships.detail.info.nextRenewal', 'Next renewal')}\n value={r.renewsAt ? formatDate(r.renewsAt) : '—'}\n />\n <InfoRow\n label={tr('relationships.detail.info.started', 'Started')}\n value={r.startedAt ? formatDate(r.startedAt) : '—'}\n />\n {r.trialEndsAt && (\n <InfoRow\n label={tr('relationships.detail.info.trialEnds', 'Trial ends')}\n value={formatDate(r.trialEndsAt)}\n />\n )}\n </div>\n </GlassCard>\n </div>\n\n {/* Entitlements */}\n <Section\n className=\"mt-0\"\n title={tr('relationships.detail.sections.entitlements', 'Entitlements')}\n description={tr(\n 'relationships.detail.sections.entitlementsDescription',\n 'What this relationship grants you'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setShowAddEntitlement(true)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <Plus className=\"h-3.5 w-3.5\" />{' '}\n {tr('relationships.detail.sections.addEntitlement', 'Add entitlement')}\n </button>\n }\n >\n {!r.entitlements || r.entitlements.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title={tr('relationships.detail.empty.noEntitlementsTitle', 'No entitlements')}\n description={tr(\n 'relationships.detail.empty.noEntitlementsDescription',\n 'Entitlements (seats, quotas, feature access) will appear here.'\n )}\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {r.entitlements.map((e) => {\n const hasQuota = e.quota != null && e.quota > 0;\n return (\n <GlassCard key={e.id} treatment=\"plain\" className=\"p-4\">\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"min-w-0 truncate text-sm font-medium text-text-primary\">\n {e.name}\n </p>\n <StatusBadge status={e.isActive ? 'ACTIVE' : 'DISABLED'} />\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">{formatEnumLabel(e.type)}</p>\n {hasQuota && (\n <div className=\"mt-3\">\n <div className=\"flex items-center justify-between text-xs text-text-secondary\">\n <span>\n {e.used} / {e.quota}\n {e.unit ? ` ${e.unit}` : ''}\n </span>\n <span className=\"tabular-nums\">\n {Math.round((e.used / (e.quota as number)) * 100)}%\n </span>\n </div>\n <MiniProgress\n value={e.used}\n max={e.quota as number}\n tone={\n e.used / (e.quota as number) >= 0.9\n ? 'negative'\n : e.used / (e.quota as number) >= 0.7\n ? 'warning'\n : 'accent'\n }\n className=\"mt-1.5\"\n />\n </div>\n )}\n </GlassCard>\n );\n })}\n </div>\n )}\n </Section>\n\n {/* Assets */}\n <Section\n className=\"mt-0\"\n title={tr('relationships.detail.sections.assets', 'Assets')}\n description={tr(\n 'relationships.detail.sections.assetsDescription',\n 'Invoices, contracts, licenses and credentials'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setShowAttachAsset(true)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <Plus className=\"h-3.5 w-3.5\" />{' '}\n {tr('relationships.detail.sections.attachAsset', 'Attach asset')}\n </button>\n }\n >\n {!r.assets || r.assets.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title={tr('relationships.detail.empty.noAssetsTitle', 'No assets attached')}\n description={tr(\n 'relationships.detail.empty.noAssetsDescription',\n 'Attach invoices, contracts, licenses or receipts to this relationship.'\n )}\n />\n ) : (\n <GlassCard treatment=\"plain\" className=\"divide-y divide-border-subtle p-0\">\n {r.assets.map((a) => (\n <AssetRow key={a.id} asset={a} />\n ))}\n </GlassCard>\n )}\n </Section>\n\n {r.notes && (\n <GlassCard treatment=\"plain\" className=\"p-4\">\n <p className=\"text-xs font-medium text-text-secondary\">\n {tr('relationships.detail.sections.notes', 'Notes')}\n </p>\n <p className=\"mt-1 whitespace-pre-wrap text-sm text-text-primary\">{r.notes}</p>\n </GlassCard>\n )}\n </div>\n\n {/* Right rail: health gauge + renewal timeline */}\n <div className=\"space-y-4\">\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Activity className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.healthScore', 'Health score')}\n </div>\n {r.healthScore != null ? (\n <div className=\"mt-4 flex flex-col items-center\">\n <Gauge\n value={r.healthScore}\n max={100}\n size={160}\n label={tr('relationships.detail.outOf100', 'of 100')}\n />\n <div className=\"mt-2 w-full\">\n <MiniProgress value={r.healthScore} max={100} tone={healthTone(r.healthScore)} />\n </div>\n </div>\n ) : (\n <p className=\"mt-4 text-sm text-text-secondary\">\n {tr(\n 'relationships.detail.empty.noHealthScore',\n 'Not scored yet. A health score appears once Subscriber Bot has enough signal.'\n )}\n </p>\n )}\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <CalendarClock className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.renewalTimeline', 'Renewal timeline')}\n </div>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {tr(\n 'relationships.detail.sections.renewalTimelineDescription',\n 'Detected renewals and price changes'\n )}\n </p>\n {renewalTimeline.length === 0 ? (\n <div className=\"mt-4\">\n <EmptyState\n illustration=\"empty-calendar\"\n title={tr('relationships.detail.empty.noRenewalEventsTitle', 'No renewal events')}\n description={tr(\n 'relationships.detail.empty.noRenewalEventsDescription',\n \"Renewals and price changes will appear here as they're detected.\"\n )}\n />\n </div>\n ) : (\n <Timeline items={renewalTimeline} className=\"mt-4\" />\n )}\n </GlassCard>\n </div>\n </div>\n\n {showEdit && <RelationshipEditModal relationship={r} onClose={() => setShowEdit(false)} />}\n {showAddEntitlement && (\n <AddEntitlementModal relationshipId={r.id} onClose={() => setShowAddEntitlement(false)} />\n )}\n {showAttachAsset && (\n <AttachAssetModal relationshipId={r.id} onClose={() => setShowAttachAsset(false)} />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"RelationshipDetailPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/relationships/RelationshipDetailPage.tsx"],"sourcesContent":["/**\n * Relationship detail\n * @module subscriberbot/pages/relationships\n *\n * Full per-relationship view: plan, price, billing period, next renewal,\n * health score, entitlements, attached assets and renewal events — plus\n * lifecycle transitions (validated server-side), edit, and cancel.\n * Reads `subRelationship(id)`; writes `subTransitionRelationship`,\n * `subCancelRelationship`, `subUpdateRelationship`, `subCreateEntitlement`,\n * `subCreateAsset`.\n */\n\nimport { useState, type ReactNode } from 'react';\nimport { useParams } from 'react-router';\nimport {\n ArrowLeft,\n CreditCard,\n Wallet,\n ShieldCheck,\n CalendarClock,\n Paperclip,\n Activity,\n Tag,\n Pencil,\n Plus,\n Pause,\n Play,\n Ban,\n Download,\n} from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { Modal } from '../../components/Modal';\nimport { LoadingView, ErrorView, Section } from '../../components/StateViews';\nimport { Gauge, Timeline, MiniProgress } from '../../components';\nimport type { TimelineItem } from '../../components';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport {\n useRelationship,\n useTransitionRelationship,\n useCancelRelationship,\n useUpdateRelationship,\n useCreateEntitlement,\n useCreateAsset,\n useUploadFile,\n useFileDownloadUrl,\n useProviders,\n usePlans,\n} from '../../hooks/useSubscriberBotApi';\nimport {\n formatCurrency,\n formatDate,\n formatEnumLabel,\n formatIntervalSuffix,\n} from '../../utils/formatters';\nimport { useTr } from '../../hooks/useTr';\nimport type {\n SubAssetType,\n SubBillingInterval,\n SubEntitlementType,\n SubRelationship,\n SubRelationshipKind,\n SubRelationshipStatus,\n SubUpdateRelationshipInput,\n} from '../../types';\n\nconst inputCls =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelCls = 'mb-1 block text-xs font-medium text-text-secondary';\n\nconst INTERVALS: SubBillingInterval[] = [\n 'MONTHLY',\n 'YEARLY',\n 'QUARTERLY',\n 'WEEKLY',\n 'DAILY',\n 'USAGE_BASED',\n 'LIFETIME',\n 'FREE',\n];\n\nconst ENTITLEMENT_TYPES: SubEntitlementType[] = [\n 'FEATURE_ACCESS',\n 'SEAT',\n 'USAGE_QUOTA',\n 'CONTENT',\n 'DISCOUNT',\n 'SUPPORT_TIER',\n];\n\nconst ASSET_TYPES: SubAssetType[] = [\n 'RECEIPT',\n 'INVOICE',\n 'CONTRACT',\n 'LICENSE_KEY',\n 'CREDENTIAL',\n 'CERTIFICATE',\n 'WARRANTY',\n 'DOMAIN',\n];\n\nconst KIND_KEY: Record<SubRelationshipKind, string> = {\n SUBSCRIPTION: 'relationships.kinds.subscription',\n MEMBERSHIP: 'relationships.kinds.membership',\n LICENSE: 'relationships.kinds.license',\n CONTRACT: 'relationships.kinds.contract',\n NEWSLETTER: 'relationships.kinds.newsletter',\n RECURRING_PAYMENT: 'relationships.kinds.recurringPayment',\n ENROLLMENT: 'relationships.kinds.enrollment',\n TRIAL: 'relationships.kinds.trial',\n};\n\n// Lifecycle actions surfaced as buttons; the server validates the transition.\nconst TRANSITIONS: Array<{\n status: SubRelationshipStatus;\n labelKey: string;\n defaultLabel: string;\n icon: typeof Play;\n}> = [\n {\n status: 'ACTIVE',\n labelKey: 'relationships.detail.actions.activate',\n defaultLabel: 'Activate',\n icon: Play,\n },\n {\n status: 'PAUSED',\n labelKey: 'relationships.detail.actions.pause',\n defaultLabel: 'Pause',\n icon: Pause,\n },\n {\n status: 'EXPIRED',\n labelKey: 'relationships.detail.actions.markExpired',\n defaultLabel: 'Mark expired',\n icon: Ban,\n },\n];\n\n/** Compact label/value row for the detail info cards. */\nfunction InfoRow({ label, value }: { label: string; value: ReactNode }) {\n return (\n <div className=\"flex items-center justify-between gap-3 border-b border-border-subtle/60 py-2.5 last:border-0 last:pb-0\">\n <span className=\"shrink-0 text-sm text-text-secondary\">{label}</span>\n <span className=\"min-w-0 truncate text-right text-sm font-medium text-text-primary\">\n {value}\n </span>\n </div>\n );\n}\n\n/** Map a 0–100 health score onto a MiniProgress tone. */\nfunction healthTone(\n score: number | null | undefined\n): 'positive' | 'accent' | 'warning' | 'negative' {\n if (score == null) return 'accent';\n if (score >= 66) return 'positive';\n if (score >= 33) return 'warning';\n return 'negative';\n}\n\n/** ISO string → yyyy-mm-dd for a native <input type=\"date\">. */\nfunction toDateInputValue(iso: string | null | undefined): string {\n if (!iso) return '';\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toISOString().slice(0, 10);\n}\n\n// ---------------------------------------------------------------------------\n// Edit relationship modal → subUpdateRelationship\n// ---------------------------------------------------------------------------\n\nfunction RelationshipEditModal({\n relationship,\n onClose,\n}: {\n relationship: SubRelationship;\n onClose: () => void;\n}) {\n const tr = useTr();\n const update = useUpdateRelationship();\n const providersQ = useProviders({ pagination: { limit: 100, offset: 0 } });\n\n const [label, setLabel] = useState(relationship.label);\n const [providerId, setProviderId] = useState(relationship.providerId ?? '');\n const [planId, setPlanId] = useState(relationship.planId ?? '');\n const [amount, setAmount] = useState(String(relationship.amount ?? ''));\n const [currency, setCurrency] = useState(relationship.currency);\n const [interval, setInterval] = useState<SubBillingInterval>(relationship.interval);\n const [renewsAt, setRenewsAt] = useState(toDateInputValue(relationship.renewsAt));\n const [autoRenew, setAutoRenew] = useState(relationship.autoRenew);\n const [healthScore, setHealthScore] = useState(\n relationship.healthScore != null ? String(relationship.healthScore) : ''\n );\n const [notes, setNotes] = useState(relationship.notes ?? '');\n const [formError, setFormError] = useState<string | null>(null);\n\n const plansQ = usePlans(providerId || undefined);\n\n // Ensure the currently-linked provider is always selectable even if it isn't\n // in the first page of the registry.\n const providerOptions = (() => {\n const list = providersQ.data?.items ?? [];\n if (relationship.provider && !list.some((p) => p.id === relationship.provider?.id)) {\n return [relationship.provider, ...list];\n }\n return list;\n })();\n const plans = plansQ.data ?? [];\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!label.trim()) {\n setFormError(tr('relationships.detail.editModal.labelRequired', 'A label is required.'));\n return;\n }\n const input: SubUpdateRelationshipInput = {\n label: label.trim(),\n interval,\n autoRenew,\n currency: currency.trim() || 'USD',\n notes: notes.trim(),\n ...(providerId ? { providerId } : {}),\n ...(planId ? { planId } : {}),\n ...(amount.trim() ? { amount: Number(amount) } : {}),\n ...(healthScore.trim() ? { healthScore: Number(healthScore) } : {}),\n ...(renewsAt ? { renewsAt: new Date(renewsAt).toISOString() } : {}),\n };\n update.mutate(\n { id: relationship.id, input },\n {\n onSuccess: () => onClose(),\n onError: (err) =>\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.detail.editModal.error', 'Could not update relationship.')\n ),\n }\n );\n };\n\n return (\n <Modal\n title={tr('relationships.detail.editModal.title', 'Edit relationship')}\n onClose={onClose}\n maxWidthClassName=\"max-w-2xl\"\n >\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n\n <div>\n <label htmlFor=\"edit-label\" className={labelCls}>\n {tr('relationships.detail.editModal.labelLabel', 'Label')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"edit-label\"\n type=\"text\"\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n className={inputCls}\n required\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"edit-provider\" className={labelCls}>\n {tr('relationships.detail.editModal.providerLabel', 'Provider')}\n </label>\n <select\n id=\"edit-provider\"\n value={providerId}\n onChange={(e) => {\n setProviderId(e.target.value);\n setPlanId('');\n }}\n className={inputCls}\n >\n <option value=\"\">\n {tr('relationships.detail.editModal.providerNone', '— None —')}\n </option>\n {providerOptions.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"edit-plan\" className={labelCls}>\n {tr('relationships.detail.editModal.planLabel', 'Plan')}\n </label>\n <select\n id=\"edit-plan\"\n value={planId}\n onChange={(e) => setPlanId(e.target.value)}\n className={inputCls}\n disabled={!providerId || plans.length === 0}\n >\n <option value=\"\">{tr('relationships.detail.editModal.planNone', '— None —')}</option>\n {plans.map((pl) => (\n <option key={pl.id} value={pl.id}>\n {pl.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"edit-amount\" className={labelCls}>\n {tr('relationships.detail.editModal.amountLabel', 'Amount')}\n </label>\n <input\n id=\"edit-amount\"\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n value={amount}\n onChange={(e) => setAmount(e.target.value)}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"edit-currency\" className={labelCls}>\n {tr('relationships.detail.editModal.currencyLabel', 'Currency')}\n </label>\n <input\n id=\"edit-currency\"\n type=\"text\"\n value={currency}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n maxLength={3}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"edit-interval\" className={labelCls}>\n {tr('relationships.detail.editModal.intervalLabel', 'Billing interval')}\n </label>\n <select\n id=\"edit-interval\"\n value={interval}\n onChange={(e) => setInterval(e.target.value as SubBillingInterval)}\n className={inputCls}\n >\n {INTERVALS.map((i) => (\n <option key={i} value={i}>\n {i.replace(/_/g, ' ')}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"edit-renews\" className={labelCls}>\n {tr('relationships.detail.editModal.renewsOnLabel', 'Renews on')}\n </label>\n <input\n id=\"edit-renews\"\n type=\"date\"\n value={renewsAt}\n onChange={(e) => setRenewsAt(e.target.value)}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"edit-health\" className={labelCls}>\n {tr('relationships.detail.editModal.healthScoreLabel', 'Health score (0–100)')}\n </label>\n <input\n id=\"edit-health\"\n type=\"number\"\n min=\"0\"\n max=\"100\"\n value={healthScore}\n onChange={(e) => setHealthScore(e.target.value)}\n className={inputCls}\n />\n </div>\n <div className=\"flex items-end\">\n <label className=\"flex items-center gap-2 text-sm text-text-primary\">\n <input\n type=\"checkbox\"\n checked={autoRenew}\n onChange={(e) => setAutoRenew(e.target.checked)}\n className=\"size-4 rounded border-border-subtle\"\n />\n {tr('relationships.detail.editModal.autoRenews', 'Auto-renews')}\n </label>\n </div>\n </div>\n\n <div>\n <label htmlFor=\"edit-notes\" className={labelCls}>\n {tr('relationships.detail.editModal.notesLabel', 'Notes')}\n </label>\n <textarea\n id=\"edit-notes\"\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n rows={3}\n className={inputCls}\n />\n </div>\n\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.detail.editModal.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={update.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {update.isPending\n ? tr('relationships.detail.editModal.saving', 'Saving…')\n : tr('relationships.detail.editModal.submit', 'Save changes')}\n </button>\n </div>\n </form>\n </Modal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Add entitlement modal → subCreateEntitlement\n// ---------------------------------------------------------------------------\n\nfunction AddEntitlementModal({\n relationshipId,\n onClose,\n}: {\n relationshipId: string;\n onClose: () => void;\n}) {\n const tr = useTr();\n const create = useCreateEntitlement();\n const [name, setName] = useState('');\n const [type, setType] = useState<SubEntitlementType>('FEATURE_ACCESS');\n const [quota, setQuota] = useState('');\n const [unit, setUnit] = useState('');\n const [description, setDescription] = useState('');\n const [formError, setFormError] = useState<string | null>(null);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!name.trim()) {\n setFormError(\n tr(\n 'relationships.detail.addEntitlementModal.nameRequired',\n 'An entitlement name is required.'\n )\n );\n return;\n }\n create.mutate(\n {\n relationshipId,\n name: name.trim(),\n type,\n ...(quota.trim() ? { quota: Number(quota) } : {}),\n ...(unit.trim() ? { unit: unit.trim() } : {}),\n ...(description.trim() ? { description: description.trim() } : {}),\n },\n {\n onSuccess: () => onClose(),\n onError: (err) =>\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.detail.addEntitlementModal.error', 'Could not add entitlement.')\n ),\n }\n );\n };\n\n return (\n <Modal\n title={tr('relationships.detail.addEntitlementModal.title', 'Add entitlement')}\n onClose={onClose}\n >\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n <div>\n <label htmlFor=\"ent-name\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.nameLabel', 'Name')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"ent-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n 'relationships.detail.addEntitlementModal.namePlaceholder',\n 'e.g. Seats, API calls, Priority support'\n )}\n className={inputCls}\n required\n />\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <div>\n <label htmlFor=\"ent-type\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.typeLabel', 'Type')}\n </label>\n <select\n id=\"ent-type\"\n value={type}\n onChange={(e) => setType(e.target.value as SubEntitlementType)}\n className={inputCls}\n >\n {ENTITLEMENT_TYPES.map((t) => (\n <option key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor=\"ent-quota\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.quotaLabel', 'Quota')}\n </label>\n <input\n id=\"ent-quota\"\n type=\"number\"\n min=\"0\"\n value={quota}\n onChange={(e) => setQuota(e.target.value)}\n placeholder={tr(\n 'relationships.detail.addEntitlementModal.quotaPlaceholder',\n 'e.g. 5'\n )}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"ent-unit\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.unitLabel', 'Unit')}\n </label>\n <input\n id=\"ent-unit\"\n type=\"text\"\n value={unit}\n onChange={(e) => setUnit(e.target.value)}\n placeholder={tr(\n 'relationships.detail.addEntitlementModal.unitPlaceholder',\n 'e.g. seats, GB'\n )}\n className={inputCls}\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"ent-desc\" className={labelCls}>\n {tr('relationships.detail.addEntitlementModal.descriptionLabel', 'Description')}\n </label>\n <textarea\n id=\"ent-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n className={inputCls}\n />\n </div>\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.detail.addEntitlementModal.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={create.isPending}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {create.isPending\n ? tr('relationships.detail.addEntitlementModal.adding', 'Adding…')\n : tr('relationships.detail.addEntitlementModal.submit', 'Add entitlement')}\n </button>\n </div>\n </form>\n </Modal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Attach asset modal → upload to files-svc, then subCreateAsset\n// ---------------------------------------------------------------------------\n\nfunction AttachAssetModal({\n relationshipId,\n onClose,\n}: {\n relationshipId: string;\n onClose: () => void;\n}) {\n const tr = useTr();\n const create = useCreateAsset();\n const { uploadFile, progress, isUploading } = useUploadFile();\n const [name, setName] = useState('');\n const [type, setType] = useState<SubAssetType>('RECEIPT');\n const [file, setFile] = useState<File | null>(null);\n const [expiresAt, setExpiresAt] = useState('');\n const [formError, setFormError] = useState<string | null>(null);\n\n const busy = isUploading || create.isPending;\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setFormError(null);\n if (!file) {\n setFormError(\n tr('relationships.detail.attachAssetModal.chooseFile', 'Choose a file to attach.')\n );\n return;\n }\n try {\n const { fileId, fileName } = await uploadFile(file);\n await create.mutateAsync({\n relationshipId,\n name: name.trim() || fileName,\n type,\n fileId,\n ...(expiresAt ? { expiresAt: new Date(expiresAt).toISOString() } : {}),\n });\n onClose();\n } catch (err) {\n setFormError(\n err instanceof Error\n ? err.message\n : tr('relationships.detail.attachAssetModal.error', 'Could not attach the asset.')\n );\n }\n };\n\n return (\n <Modal\n title={tr('relationships.detail.attachAssetModal.title', 'Attach asset')}\n onClose={onClose}\n >\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {formError && (\n <div className=\"rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {formError}\n </div>\n )}\n <div>\n <label htmlFor=\"asset-file\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.fileLabel', 'File')}{' '}\n <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n id=\"asset-file\"\n type=\"file\"\n onChange={(e) => {\n const f = e.target.files?.[0] ?? null;\n setFile(f);\n if (f && !name.trim()) setName(f.name);\n }}\n className=\"w-full text-sm text-text-secondary file:mr-3 file:rounded-lg file:border file:border-border-subtle file:bg-bg-surface file:px-3 file:py-1.5 file:text-sm file:font-medium file:text-text-primary hover:file:bg-bg-sunken\"\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n {tr(\n 'relationships.detail.attachAssetModal.fileHint',\n 'Stored securely in files — only a reference is kept here.'\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div>\n <label htmlFor=\"asset-name\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.nameLabel', 'Name')}\n </label>\n <input\n id=\"asset-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={tr(\n 'relationships.detail.attachAssetModal.namePlaceholder',\n 'Defaults to the file name'\n )}\n className={inputCls}\n />\n </div>\n <div>\n <label htmlFor=\"asset-type\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.typeLabel', 'Type')}\n </label>\n <select\n id=\"asset-type\"\n value={type}\n onChange={(e) => setType(e.target.value as SubAssetType)}\n className={inputCls}\n >\n {ASSET_TYPES.map((t) => (\n <option key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div>\n <label htmlFor=\"asset-expires\" className={labelCls}>\n {tr('relationships.detail.attachAssetModal.expiresOnLabel', 'Expires on')}\n </label>\n <input\n id=\"asset-expires\"\n type=\"date\"\n value={expiresAt}\n onChange={(e) => setExpiresAt(e.target.value)}\n className={inputCls}\n />\n </div>\n {isUploading && (\n <p className=\"text-xs text-text-secondary\">\n {tr('relationships.detail.attachAssetModal.uploading', 'Uploading… {{progress}}%', {\n progress,\n })}\n </p>\n )}\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n {tr('relationships.detail.attachAssetModal.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={busy}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {busy\n ? tr('relationships.detail.attachAssetModal.attaching', 'Attaching…')\n : tr('relationships.detail.attachAssetModal.submit', 'Attach asset')}\n </button>\n </div>\n </form>\n </Modal>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Asset row — resolves a presigned download URL on demand\n// ---------------------------------------------------------------------------\n\nfunction AssetRow({ asset }: { asset: NonNullable<SubRelationship['assets']>[number] }) {\n const tr = useTr();\n const getDownloadUrl = useFileDownloadUrl();\n const [downloading, setDownloading] = useState(false);\n\n const handleDownload = async () => {\n if (!asset.file?.id) return;\n setDownloading(true);\n try {\n const url = await getDownloadUrl(asset.file.id);\n window.open(url, '_blank', 'noopener,noreferrer');\n } catch {\n // Non-fatal: a broken/expired file reference just can't be downloaded.\n } finally {\n setDownloading(false);\n }\n };\n\n return (\n <div className=\"flex items-center justify-between gap-3 p-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Paperclip className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{asset.name}</p>\n <p className=\"text-xs text-text-secondary\">{formatEnumLabel(asset.type)}</p>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-3\">\n {asset.expiresAt && (\n <span className=\"text-xs text-text-secondary\">\n {tr('relationships.detail.assetRow.expires', 'Expires {{date}}', {\n date: formatDate(asset.expiresAt),\n })}\n </span>\n )}\n {asset.file?.id && (\n <button\n type=\"button\"\n onClick={handleDownload}\n disabled={downloading}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-subtle px-2.5 py-1 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Download className=\"h-3.5 w-3.5\" />{' '}\n {downloading\n ? tr('relationships.detail.assetRow.opening', 'Opening…')\n : tr('relationships.detail.assetRow.download', 'Download')}\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Invoice row (BOFF-8659) — every invoice linked to this relationship via\n// `SubInvoice.relationshipId` is shown in the Assets section alongside any\n// file-based assets, so users don't have to leave the relationship page to\n// discover that they have an outstanding invoice tied to it.\n// ---------------------------------------------------------------------------\n\nfunction InvoiceRow({ invoice }: { invoice: NonNullable<SubRelationship['invoices']>[number] }) {\n const tr = useTr();\n // Each invoice appears once, grouped by the (most-recent) due or issue\n // date and labelled with number · status, then a right-aligned total that\n // matches the Invoices list currency formatting.\n const label =\n invoice.number ?? tr('relationships.detail.invoiceRow.unnumbered', 'Unnumbered invoice');\n return (\n <div className=\"flex items-center justify-between gap-3 p-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <CreditCard className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{label}</p>\n <p className=\"text-xs text-text-secondary\">\n {formatEnumLabel(invoice.status)}\n {invoice.dueDate\n ? ` · ${tr('relationships.detail.invoiceRow.due', 'due {{date}}', {\n date: formatDate(invoice.dueDate),\n })}`\n : invoice.issueDate\n ? ` · ${formatDate(invoice.issueDate)}`\n : ''}\n </p>\n </div>\n </div>\n <span className=\"shrink-0 text-sm font-medium tabular-nums text-text-primary\">\n {formatCurrency(invoice.total, invoice.currency)}\n </span>\n </div>\n );\n}\n\nexport function RelationshipDetailPage() {\n const tr = useTr();\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useSubscriberBot();\n const { data: relationship, isLoading, isError, refetch } = useRelationship(id);\n const transition = useTransitionRelationship();\n const cancel = useCancelRelationship();\n const [actionError, setActionError] = useState<string | null>(null);\n const [showEdit, setShowEdit] = useState(false);\n const [showAddEntitlement, setShowAddEntitlement] = useState(false);\n const [showAttachAsset, setShowAttachAsset] = useState(false);\n\n if (isLoading) {\n return (\n <PageLayout title={tr('relationships.title', 'Relationship')}>\n <LoadingView label={tr('relationships.detail.loading', 'Loading relationship…')} />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title={tr('relationships.title', 'Relationship')}>\n <ErrorView\n message={tr('relationships.detail.error', 'Could not load this relationship.')}\n onRetry={() => void refetch()}\n />\n </PageLayout>\n );\n }\n\n if (!relationship) {\n return (\n <PageLayout title={tr('relationships.title', 'Relationship')}>\n <EmptyState\n illustration=\"empty-data\"\n title={tr('relationships.detail.notFoundTitle', 'Relationship not found')}\n description={tr(\n 'relationships.detail.notFoundDescription',\n 'It may have been removed, or you may not have access to it.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n {tr('relationships.detail.backToRelationships', 'Back to relationships')}\n </button>\n }\n />\n </PageLayout>\n );\n }\n\n const r = relationship;\n const isBusy = transition.isPending || cancel.isPending;\n\n const runTransition = (status: SubRelationshipStatus) => {\n setActionError(null);\n transition.mutate(\n { id: r.id, status },\n {\n onError: (e) =>\n setActionError(\n e instanceof Error\n ? e.message\n : tr('relationships.detail.transitionError', 'Transition failed')\n ),\n }\n );\n };\n\n const runCancel = () => {\n setActionError(null);\n cancel.mutate(r.id, {\n onError: (e) =>\n setActionError(\n e instanceof Error ? e.message : tr('relationships.detail.cancelError', 'Cancel failed')\n ),\n });\n };\n\n // Renewal timeline — built entirely from the real renewalEvents, oldest → newest.\n const renewalTimeline: TimelineItem[] = [...(r.renewalEvents ?? [])]\n .sort((a, b) => new Date(a.occursAt).getTime() - new Date(b.occursAt).getTime())\n .map((event) => {\n const ts = new Date(event.occursAt).getTime();\n const isFuture = !Number.isNaN(ts) && ts > Date.now();\n return {\n title: formatEnumLabel(event.eventType),\n sub: `${formatDate(event.occursAt)}${event.detail ? ` · ${event.detail}` : ''}`,\n meta:\n event.amount != null\n ? formatCurrency(event.amount, event.currency ?? r.currency)\n : undefined,\n tone: isFuture ? 'warning' : 'muted',\n };\n });\n\n const autoRenewPill = r.autoRenew ? (\n <span className=\"inline-flex items-center rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-xs font-medium text-status-success-text\">\n {tr('relationships.detail.autoRenewOn', 'On')}\n </span>\n ) : (\n <span className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\">\n {tr('relationships.detail.autoRenewOff', 'Off')}\n </span>\n );\n\n const availableTransitions = TRANSITIONS.filter((t) => t.status !== r.status);\n const planFeatures = r.plan?.features ?? [];\n\n return (\n <PageLayout\n title={r.label}\n description={r.provider?.name ?? tr(KIND_KEY[r.kind], formatEnumLabel(r.kind))}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setShowEdit(true)}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <Pencil className=\"h-4 w-4\" /> {tr('relationships.detail.edit', 'Edit')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/relationships')}\n className=\"inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> {tr('relationships.detail.back', 'Back')}\n </button>\n </div>\n }\n >\n {/* Hero summary + lifecycle actions */}\n <GlassCard treatment=\"glass\" glow className=\"p-5 sm:p-6\">\n <div className=\"flex flex-col gap-5 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"min-w-0\">\n <p className=\"text-xs font-medium uppercase tracking-wide text-text-secondary\">\n {tr(KIND_KEY[r.kind], formatEnumLabel(r.kind))}\n </p>\n <div className=\"mt-2 flex flex-wrap items-center gap-3\">\n <span className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {formatCurrency(r.amount, r.currency)}\n <span className=\"text-base font-normal text-text-secondary\">\n {formatIntervalSuffix(r.interval)}\n </span>\n </span>\n <StatusBadge status={r.status} />\n </div>\n <div className=\"mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-text-secondary\">\n <span className=\"inline-flex items-center gap-1.5\">\n <CalendarClock className=\"h-3.5 w-3.5\" />\n {r.renewsAt\n ? tr('relationships.detail.renews', 'Renews {{date}}', {\n date: formatDate(r.renewsAt),\n })\n : tr('relationships.detail.noRenewalScheduled', 'No renewal scheduled')}\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n <ShieldCheck className=\"h-3.5 w-3.5\" />\n {formatEnumLabel(r.discoverySource)}\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n {tr('relationships.detail.autoRenew', 'Auto-renew')} {autoRenewPill}\n </span>\n </div>\n {r.tags.length > 0 && (\n <div className=\"mt-3 flex flex-wrap items-center gap-2\">\n <Tag className=\"h-3.5 w-3.5 text-text-secondary\" />\n {r.tags.map((tag) => (\n <span\n key={tag}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n </div>\n\n {/* Lifecycle actions */}\n <div className=\"flex shrink-0 flex-wrap gap-2 lg:flex-col lg:items-stretch\">\n {availableTransitions.map((t) => {\n const Icon = t.icon;\n return (\n <button\n key={t.status}\n type=\"button\"\n disabled={isBusy}\n onClick={() => runTransition(t.status)}\n className=\"inline-flex items-center justify-center gap-1.5 rounded-lg border border-border-subtle bg-bg-surface px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Icon className=\"h-3.5 w-3.5\" /> {tr(t.labelKey, t.defaultLabel)}\n </button>\n );\n })}\n {r.status !== 'CANCELLED' && (\n <button\n type=\"button\"\n disabled={isBusy}\n onClick={runCancel}\n className=\"inline-flex items-center justify-center gap-1.5 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-3 py-1.5 text-xs font-medium text-status-error-text hover:opacity-90 disabled:opacity-50\"\n >\n <Ban className=\"h-3.5 w-3.5\" />{' '}\n {tr('relationships.detail.actions.cancel', 'Cancel')}\n </button>\n )}\n </div>\n </div>\n </GlassCard>\n\n {actionError && (\n <div className=\"mt-4 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text\">\n {actionError}\n </div>\n )}\n\n {/* Main layout: details (left) + health & timeline rail (right) */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <div className=\"space-y-4 lg:col-span-2\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n {/* Plan & pricing */}\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <CreditCard className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.planPricing', 'Plan & pricing')}\n </div>\n <div className=\"mt-3\">\n <InfoRow\n label={tr('relationships.detail.info.plan', 'Plan')}\n value={r.plan?.name ?? '—'}\n />\n <InfoRow\n label={tr('relationships.detail.info.price', 'Price')}\n value={\n <>\n {formatCurrency(r.amount, r.currency)}\n <span className=\"font-normal text-text-secondary\">\n {formatIntervalSuffix(r.interval)}\n </span>\n </>\n }\n />\n <InfoRow\n label={tr('relationships.detail.info.billingInterval', 'Billing interval')}\n value={formatEnumLabel(r.interval)}\n />\n <InfoRow\n label={tr('relationships.detail.info.provider', 'Provider')}\n value={r.provider?.name ?? '—'}\n />\n </div>\n {planFeatures.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {planFeatures.map((f) => (\n <span\n key={f}\n className=\"rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary\"\n >\n {f}\n </span>\n ))}\n </div>\n )}\n </GlassCard>\n\n {/* Payment & billing */}\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Wallet className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.paymentBilling', 'Payment & billing')}\n </div>\n <div className=\"mt-3\">\n <InfoRow\n label={tr('relationships.detail.info.currency', 'Currency')}\n value={r.currency}\n />\n <InfoRow\n label={tr('relationships.detail.info.autoRenew', 'Auto-renew')}\n value={autoRenewPill}\n />\n <InfoRow\n label={tr('relationships.detail.info.nextRenewal', 'Next renewal')}\n value={r.renewsAt ? formatDate(r.renewsAt) : '—'}\n />\n <InfoRow\n label={tr('relationships.detail.info.started', 'Started')}\n value={r.startedAt ? formatDate(r.startedAt) : '—'}\n />\n {r.trialEndsAt && (\n <InfoRow\n label={tr('relationships.detail.info.trialEnds', 'Trial ends')}\n value={formatDate(r.trialEndsAt)}\n />\n )}\n </div>\n </GlassCard>\n </div>\n\n {/* Entitlements */}\n <Section\n className=\"mt-0\"\n title={tr('relationships.detail.sections.entitlements', 'Entitlements')}\n description={tr(\n 'relationships.detail.sections.entitlementsDescription',\n 'What this relationship grants you'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setShowAddEntitlement(true)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <Plus className=\"h-3.5 w-3.5\" />{' '}\n {tr('relationships.detail.sections.addEntitlement', 'Add entitlement')}\n </button>\n }\n >\n {!r.entitlements || r.entitlements.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title={tr('relationships.detail.empty.noEntitlementsTitle', 'No entitlements')}\n description={tr(\n 'relationships.detail.empty.noEntitlementsDescription',\n 'Entitlements (seats, quotas, feature access) will appear here.'\n )}\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {r.entitlements.map((e) => {\n const hasQuota = e.quota != null && e.quota > 0;\n return (\n <GlassCard key={e.id} treatment=\"plain\" className=\"p-4\">\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"min-w-0 truncate text-sm font-medium text-text-primary\">\n {e.name}\n </p>\n <StatusBadge status={e.isActive ? 'ACTIVE' : 'DISABLED'} />\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">{formatEnumLabel(e.type)}</p>\n {hasQuota && (\n <div className=\"mt-3\">\n <div className=\"flex items-center justify-between text-xs text-text-secondary\">\n <span>\n {e.used} / {e.quota}\n {e.unit ? ` ${e.unit}` : ''}\n </span>\n <span className=\"tabular-nums\">\n {Math.round((e.used / (e.quota as number)) * 100)}%\n </span>\n </div>\n <MiniProgress\n value={e.used}\n max={e.quota as number}\n tone={\n e.used / (e.quota as number) >= 0.9\n ? 'negative'\n : e.used / (e.quota as number) >= 0.7\n ? 'warning'\n : 'accent'\n }\n className=\"mt-1.5\"\n />\n </div>\n )}\n </GlassCard>\n );\n })}\n </div>\n )}\n </Section>\n\n {/* Assets — file-based assets + relationship-owned invoices.\n BOFF-8659: invoices linked via `SubInvoice.relationshipId` are now\n shown here too, so the panel copy \"Invoices, contracts, licenses\n and credentials\" is honored for the cross-module Relationships ↔\n Invoices flow. */}\n <Section\n className=\"mt-0\"\n title={tr('relationships.detail.sections.assets', 'Assets')}\n description={tr(\n 'relationships.detail.sections.assetsDescription',\n 'Invoices, contracts, licenses and credentials'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setShowAttachAsset(true)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken\"\n >\n <Plus className=\"h-3.5 w-3.5\" />{' '}\n {tr('relationships.detail.sections.attachAsset', 'Attach asset')}\n </button>\n }\n >\n {(() => {\n const assets = r.assets ?? [];\n // BOFF-8659 — pull relationship-owned invoices into the same\n // Assets list, sorted next to file-based assets by their sort\n // time so invoices appear in the same order as the Invoices\n // list (newest first).\n const invoices: NonNullable<SubRelationship['invoices']> = r.invoices ?? [];\n const hasAny = assets.length > 0 || invoices.length > 0;\n if (!hasAny) {\n return (\n <EmptyState\n illustration=\"empty-data\"\n title={tr('relationships.detail.empty.noAssetsTitle', 'No assets attached')}\n description={tr(\n 'relationships.detail.empty.noAssetsDescription',\n 'Attach invoices, contracts, licenses or receipts to this relationship.'\n )}\n />\n );\n }\n type AssetLike =\n | {\n kind: 'asset';\n sort: number;\n asset: NonNullable<SubRelationship['assets']>[number];\n }\n | {\n kind: 'invoice';\n sort: number;\n invoice: NonNullable<SubRelationship['invoices']>[number];\n };\n const combined: AssetLike[] = [\n ...assets.map((a) => ({\n kind: 'asset' as const,\n sort: new Date(a.createdAt).getTime() || 0,\n asset: a,\n })),\n ...invoices.map((i) => ({\n kind: 'invoice' as const,\n sort: new Date(i.createdAt).getTime() || 0,\n invoice: i,\n })),\n ].sort((x, y) => y.sort - x.sort);\n return (\n <GlassCard treatment=\"plain\" className=\"divide-y divide-border-subtle p-0\">\n {combined.map((row) =>\n row.kind === 'asset' ? (\n <AssetRow key={`a-${row.asset.id}`} asset={row.asset} />\n ) : (\n <InvoiceRow key={`i-${row.invoice.id}`} invoice={row.invoice} />\n )\n )}\n </GlassCard>\n );\n })()}\n </Section>\n\n {r.notes && (\n <GlassCard treatment=\"plain\" className=\"p-4\">\n <p className=\"text-xs font-medium text-text-secondary\">\n {tr('relationships.detail.sections.notes', 'Notes')}\n </p>\n <p className=\"mt-1 whitespace-pre-wrap text-sm text-text-primary\">{r.notes}</p>\n </GlassCard>\n )}\n </div>\n\n {/* Right rail: health gauge + renewal timeline */}\n <div className=\"space-y-4\">\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Activity className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.healthScore', 'Health score')}\n </div>\n {r.healthScore != null ? (\n <div className=\"mt-4 flex flex-col items-center\">\n <Gauge\n value={r.healthScore}\n max={100}\n size={160}\n label={tr('relationships.detail.outOf100', 'of 100')}\n />\n <div className=\"mt-2 w-full\">\n <MiniProgress value={r.healthScore} max={100} tone={healthTone(r.healthScore)} />\n </div>\n </div>\n ) : (\n <p className=\"mt-4 text-sm text-text-secondary\">\n {tr(\n 'relationships.detail.empty.noHealthScore',\n 'Not scored yet. A health score appears once Subscriber Bot has enough signal.'\n )}\n </p>\n )}\n </GlassCard>\n\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <div className=\"flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <CalendarClock className=\"h-4 w-4 text-text-secondary\" />{' '}\n {tr('relationships.detail.sections.renewalTimeline', 'Renewal timeline')}\n </div>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {tr(\n 'relationships.detail.sections.renewalTimelineDescription',\n 'Detected renewals and price changes'\n )}\n </p>\n {renewalTimeline.length === 0 ? (\n <div className=\"mt-4\">\n <EmptyState\n illustration=\"empty-calendar\"\n title={tr('relationships.detail.empty.noRenewalEventsTitle', 'No renewal events')}\n description={tr(\n 'relationships.detail.empty.noRenewalEventsDescription',\n \"Renewals and price changes will appear here as they're detected.\"\n )}\n />\n </div>\n ) : (\n <Timeline items={renewalTimeline} className=\"mt-4\" />\n )}\n </GlassCard>\n </div>\n </div>\n\n {showEdit && <RelationshipEditModal relationship={r} onClose={() => setShowEdit(false)} />}\n {showAddEntitlement && (\n <AddEntitlementModal relationshipId={r.id} onClose={() => setShowAddEntitlement(false)} />\n )}\n {showAttachAsset && (\n <AttachAssetModal relationshipId={r.id} onClose={() => setShowAttachAsset(false)} />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -212,6 +212,7 @@ export interface SubRelationship {
212
212
  plan?: SubPlan | null;
213
213
  entitlements?: SubEntitlement[];
214
214
  assets?: SubAsset[];
215
+ invoices?: SubInvoice[];
215
216
  renewalEvents?: SubRenewalEvent[];
216
217
  }
217
218
  export interface SubInboxMessage {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/subscriberbot/types/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-subscriberbot",
3
- "version": "2026.1023.1",
3
+ "version": "2026.1023.2",
4
4
  "description": "Burdenoff SubscriberBot Microfrontend",
5
5
  "type": "module",
6
6
  "files": [