feat: add single endpoint for merchant subscriptions with usage data

Replace N+1 per-platform API calls on merchant detail page with a single
GET /admin/subscriptions/merchants/{id} endpoint. Extract shared
subscription+usage aggregation logic into a reusable service method and
refactor the store endpoint to use it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-22 20:58:02 +01:00
parent b9ac252a9f
commit 42b894094a
4 changed files with 92 additions and 66 deletions

View File

@@ -51,8 +51,7 @@ function adminMerchantDetail() {
this.merchantId = match[1];
merchantDetailLog.info('Viewing merchant:', this.merchantId);
await this.loadMerchant();
await this.loadPlatforms();
await this.loadSubscriptions();
await Promise.all([this.loadPlatforms(), this.loadSubscriptions()]);
} else {
merchantDetailLog.error('No merchant ID in URL');
this.error = 'Invalid merchant URL';
@@ -110,31 +109,19 @@ function adminMerchantDetail() {
}
},
// Load subscriptions for all platforms
// Load all subscriptions for this merchant in a single call
async loadSubscriptions() {
if (!this.merchantId || this.platforms.length === 0) return;
if (!this.merchantId) return;
merchantDetailLog.info('Loading subscriptions for merchant:', this.merchantId);
this.subscriptions = [];
for (const platform of this.platforms) {
try {
const url = `/admin/subscriptions/merchants/${this.merchantId}/platforms/${platform.id}`;
const response = await apiClient.get(url);
const sub = response.subscription || response;
this.subscriptions.push({
subscription: sub,
tier: response.tier || null,
features: response.features || [],
platform_id: platform.id,
platform_name: platform.name,
});
} catch (error) {
if (error.status !== 404) {
merchantDetailLog.warn(`Failed to load subscription for platform ${platform.name}:`, error.message);
}
}
try {
const url = `/admin/subscriptions/merchants/${this.merchantId}`;
const response = await apiClient.get(url);
this.subscriptions = response.subscriptions || [];
} catch (error) {
merchantDetailLog.warn('Failed to load subscriptions:', error.message);
}
merchantDetailLog.info('Subscriptions loaded:', {