Background
Listing/detail for individual subscriptions, plus a view over subscription payment history. The payments endpoint has a real dependency worth calling out explicitly rather than silently assuming it's satisfied: it reads Transaction rows where transactionType = SUBSCRIPTION_CHARGE, which only exist once a SubscriptionChargedEvent handler is writing them.
Proposed Steps
GET /admin/subscriptions — paginated, filterable by status, planId, merchantAddress (via Subscription.merchantId → Merchant.address, no join through the plan needed since merchantId is direct), customer (address, exact match), sortable by sortBy in [createdAt, lastCharged] / sortDir.
GET /admin/subscriptions/:id — subscription detail, including the related plan's description/amount/interval inlined (one query, include: { plan: true }) so the admin doesn't need a second request.
GET /admin/subscriptions/payments — lists Transaction rows where transactionType = 'SUBSCRIPTION_CHARGE', paginated, filterable by merchantAddress and date range, mirroring the filter shape already established for invoices.
Acceptance Criteria
Background
Listing/detail for individual subscriptions, plus a view over subscription payment history. The payments endpoint has a real dependency worth calling out explicitly rather than silently assuming it's satisfied: it reads
Transactionrows wheretransactionType = SUBSCRIPTION_CHARGE, which only exist once aSubscriptionChargedEventhandler is writing them.Proposed Steps
GET /admin/subscriptions— paginated, filterable bystatus,planId,merchantAddress(viaSubscription.merchantId→Merchant.address, no join through the plan needed sincemerchantIdis direct),customer(address, exact match), sortable bysortByin[createdAt, lastCharged]/sortDir.GET /admin/subscriptions/:id— subscription detail, including the related plan'sdescription/amount/intervalinlined (one query,include: { plan: true }) so the admin doesn't need a second request.GET /admin/subscriptions/payments— listsTransactionrows wheretransactionType = 'SUBSCRIPTION_CHARGE', paginated, filterable bymerchantAddressand date range, mirroring the filter shape already established for invoices.Acceptance Criteria
GET /admin/subscriptionssupports all listed filters, sort options, and paginationGET /admin/subscriptions/:idincludes plan details inline;404for unknown idGET /admin/subscriptions/paymentsreturns onlySUBSCRIPTION_CHARGEtransactions, correctly filtered and paginatedSubscriptionChargedEventhandler is documented in code (comment on the payments endpoint) so an empty result set is understood as "no charges indexed yet" rather than assumed broken