chore(api): promote test → main (GET /api/admins/artists/pro migration)#482
Conversation
* feat(api): migrate GET /api/artists/pro
Admin-scoped flat route returning the deduped list of artist IDs owned by
"pro" accounts (enterprise email domain or active Stripe subscription).
Ports Stripe client + getActiveSubscriptions inline until the subscription
PR lands; reuses validateAdminAuth for scope.
* fix(stripe): defer client init to first call
Next build on Vercel evaluates lib/stripe/client.ts while collecting
page data; throwing at module-load when STRIPE_SECRET_KEY is absent
from the preview env killed the build. Move the guard into a lazy
factory so build-time import is always safe — the first request
still surfaces a 500 via the handler's catch when the secret is
genuinely missing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* refactor: fold account_emails helpers into generic selectAccountEmails
Add optional domain filter (ilike %@<domain>%) to the existing
selectAccountEmails helper and drop the per-filter wrappers. One
helper, three optional filters (emails, accountIds, domain).
* refactor(stripe): paginate getActiveSubscriptions, drop unused accountId
Use Stripe SDK's async iterator so we're not capped at 100 rows — the
cursor paginates the full active set. The accountId filter param was
dead (no caller passed it); drop rather than carry; reintroduce via
Stripe Search API if a single-account lookup is ever needed.
* refactor(stripe): use autoPagingToArray in getActiveSubscriptions
* refactor(stripe): stream active subscriptions, use native status filter
Swap getActiveSubscriptions for an iterateActiveSubscriptions async
generator. Two wins:
1. status: 'active' is Stripe's native filter — no current_period_end
vs server-clock comparison (timezone / skew hazards).
2. Yielded incrementally so callers fold results into a Set as they
arrive; no hard in-memory cap on the active subscription count.
Caller now holds only the deduped accountId strings, not full
Subscription objects.
* refactor: separate stripe from enterprise; rename merge to getProArtists
- lib/stripe/ now owns getActiveSubscriptions + getSubscriberAccountEmails
(they query Stripe, not enterprise domains).
- lib/enterprise/ keeps only ENTERPRISE_DOMAINS and the domain email fan-out.
- The merge orchestrator moves to lib/artists/getProArtists.ts (enterprise ∪
subscribers); renamed from getEnterpriseArtists since 'enterprise artists'
understates what it returns.
- getActiveSubscriptions uses a manual starting_after cursor loop so there is
no iterator and no hard row cap.
* refactor: project pro sources to account_ids, skip subscriber email round-trip
The subscriber path fetched Stripe subs, extracted metadata.accountId,
round-tripped Supabase to get account_emails rows, then unpacked
account_id again — the email lookup was inert.
- lib/stripe/getSubscriberAccountIds reads metadata.accountId from
Stripe directly; no Supabase call.
- lib/enterprise/getEnterpriseAccountIds projects the ilike result to
account_ids at the source.
- getProArtists now merges two string arrays, dedupes once, then hits
account_artist_ids.
* refactor: inline subscriber accountId extraction into getProArtists
getSubscriberAccountIds was a two-line .map/.filter wrapper. Drop it
and inline against the Stripe result — no useful indirection.
* refactor(stripe): return account_ids directly, skip Subscription hop
getActiveSubscriptions returned full Subscription objects only to have
every caller project down to metadata.accountId. Collapse that into
getActiveSubscriptionAccountIds — strings in, strings out.
* refactor: query local subscriptions mirror instead of Stripe
Supabase has a subscriptions table mirroring billing-provider state
(stripe/lemon-squeezy/paddle) with account_id + active flag. Read from
that and skip Stripe entirely — no pagination, no secret-key env var,
no provider round-trip, and cross-provider correct.
- lib/supabase/subscriptions/selectActiveSubscriptionAccountIds.ts
- lib/stripe/ removed
- stripe package uninstalled
getProArtists now merges two Supabase queries.
* refactor: move route to /api/admins/artists/pro
* refactor: generalize to selectSubscriptions helper
Per review — replace selectActiveSubscriptionAccountIds with a generic
selectSubscriptions({ accountIds?, active? }) helper. Caller projects to
account_ids.
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughIntroduces a new admin API endpoint for retrieving pro artists, combining enterprise domain-based accounts with active Stripe subscription holders. The implementation includes request validation, business logic to fetch and deduplicate artist records, and supporting database query helpers. Changes
Sequence DiagramsequenceDiagram
participant Client as Admin Client
participant Route as GET /api/admins/artists/pro
participant Validator as validateGetArtistsProRequest
participant Handler as getArtistsProHandler
participant ProLogic as getProArtists
participant Enterprise as getEnterpriseAccountIds
participant Subscriptions as selectSubscriptions
participant ArtistSelect as selectAccountArtistIds
participant DB as Supabase DB
Client->>Route: GET /api/admins/artists/pro
Route->>Validator: validate request
Validator->>Validator: check admin auth
alt Auth fails
Validator-->>Route: NextResponse error
Route-->>Client: 401/403 response
else Auth succeeds
Validator-->>Route: {}
Route->>Handler: forward request
Handler->>ProLogic: getProArtists()
par Fetch Enterprise Accounts
ProLogic->>Enterprise: getEnterpriseAccountIds()
Enterprise->>DB: selectAccountEmails(domain filters)
DB-->>Enterprise: accounts by enterprise domain
Enterprise-->>ProLogic: enterprise account IDs
and Fetch Subscription Accounts
ProLogic->>Subscriptions: selectSubscriptions({active: true})
Subscriptions->>DB: query active subscriptions
DB-->>Subscriptions: subscription rows
Subscriptions-->>ProLogic: subscription account IDs
end
ProLogic->>ProLogic: merge & deduplicate IDs
alt No pro accounts found
ProLogic-->>Handler: []
else Pro accounts exist
ProLogic->>ArtistSelect: selectAccountArtistIds(merged IDs)
ArtistSelect->>DB: query account_artist_ids table
DB-->>ArtistSelect: artist rows
ArtistSelect-->>ProLogic: artist IDs
end
ProLogic-->>Handler: artist IDs array
Handler->>Handler: format response with CORS headers
Handler-->>Route: NextResponse.json(artists)
Route-->>Client: 200 with pro artists list
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Promotes the single change on `test` to `main`.
Includes
Test plan
🤖 Generated with Claude Code
Summary by cubic
Adds an admin-only endpoint at GET /api/admins/artists/pro that returns a deduped list of artist IDs for “pro” accounts, sourced from enterprise email domains and the local
subscriptionsmirror.New Features
Refactors
selectSubscriptions({ accountIds?, active? })to query the local billing mirror.selectAccountEmailswith adomainfilter; addedgetEnterpriseAccountIdsandselectAccountArtistIdshelpers.Written for commit 73fa2ad. Summary will update on new commits.
Summary by CodeRabbit