Background
SubscriptionPlan and Subscription already exist in the schema (fields match the contract's structs — id, planId, merchantId, description, token, amount, interval, active for plans) — no new schema is needed for this issue.
Proposed Steps
GET /admin/subscription-plans — paginated, filterable by merchantAddress (join), token, active (bool), sortable by sortBy in [createdAt, amount, interval] / sortDir.
GET /admin/subscription-plans/:id — plan detail, including a subscriberCount (via Prisma's _count on the subscriptions relation) since an admin looking at a plan will reasonably want to know how many active subscribers it has without a second request.
- Tests, as explicitly requested:
tests/unit/admin.subscription-plan.services.test.ts (filter/sort/pagination logic) and tests/integration/admin.subscription-plan.routes.test.ts (route-level, following the existing mocked-Prisma pattern used throughout tests/integration/).
Acceptance Criteria
Background
SubscriptionPlanandSubscriptionalready exist in the schema (fields match the contract's structs —id,planId,merchantId,description,token,amount,interval,activefor plans) — no new schema is needed for this issue.Proposed Steps
GET /admin/subscription-plans— paginated, filterable bymerchantAddress(join),token,active(bool), sortable bysortByin[createdAt, amount, interval]/sortDir.GET /admin/subscription-plans/:id— plan detail, including asubscriberCount(via Prisma's_counton thesubscriptionsrelation) since an admin looking at a plan will reasonably want to know how many active subscribers it has without a second request.tests/unit/admin.subscription-plan.services.test.ts(filter/sort/pagination logic) andtests/integration/admin.subscription-plan.routes.test.ts(route-level, following the existing mocked-Prisma pattern used throughouttests/integration/).Acceptance Criteria
GET /admin/subscription-planssupports all listed filters, sort options, and paginationGET /admin/subscription-plans/:idincludessubscriberCount;404for unknown id