fix(subscriptions): fix subscription banner not showing on merchant detail page
Fix 3 bugs preventing the subscription banner from rendering on
/admin/merchants/{id}: correct API response parsing for platforms and
tiers endpoints (response.items → response.platforms/response.tiers),
and replace broken model_validator with field_validator for tier code
extraction in the billing schema.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ Used for admin subscription management and merchant-level billing.
|
|||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -117,7 +117,7 @@ class MerchantSubscriptionAdminResponse(BaseModel):
|
|||||||
id: int
|
id: int
|
||||||
merchant_id: int
|
merchant_id: int
|
||||||
platform_id: int
|
platform_id: int
|
||||||
tier_id: int | None = None
|
tier: str | None = None
|
||||||
|
|
||||||
status: str
|
status: str
|
||||||
is_annual: bool
|
is_annual: bool
|
||||||
@@ -137,6 +137,14 @@ class MerchantSubscriptionAdminResponse(BaseModel):
|
|||||||
created_at: datetime
|
created_at: datetime
|
||||||
updated_at: datetime
|
updated_at: datetime
|
||||||
|
|
||||||
|
@field_validator("tier", mode="before")
|
||||||
|
@classmethod
|
||||||
|
def extract_tier_code(cls, v):
|
||||||
|
"""Convert SubscriptionTier ORM object to its code string."""
|
||||||
|
if v is not None and hasattr(v, "code"):
|
||||||
|
return v.code
|
||||||
|
return v
|
||||||
|
|
||||||
|
|
||||||
class MerchantSubscriptionWithMerchant(MerchantSubscriptionAdminResponse):
|
class MerchantSubscriptionWithMerchant(MerchantSubscriptionAdminResponse):
|
||||||
"""Subscription response with merchant info."""
|
"""Subscription response with merchant info."""
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ function adminMerchantDetail() {
|
|||||||
async loadPlatforms() {
|
async loadPlatforms() {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.get('/admin/platforms');
|
const response = await apiClient.get('/admin/platforms');
|
||||||
const platforms = response.items || response;
|
const platforms = response.platforms || [];
|
||||||
const oms = platforms.find(p => p.code === 'oms');
|
const oms = platforms.find(p => p.code === 'oms');
|
||||||
if (oms) {
|
if (oms) {
|
||||||
this.platformId = oms.id;
|
this.platformId = oms.id;
|
||||||
@@ -155,7 +155,7 @@ function adminMerchantDetail() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.get('/admin/subscriptions/tiers');
|
const response = await apiClient.get('/admin/subscriptions/tiers');
|
||||||
this.tiers = response.items || response;
|
this.tiers = response.tiers || [];
|
||||||
merchantDetailLog.info('Loaded tiers:', this.tiers.length);
|
merchantDetailLog.info('Loaded tiers:', this.tiers.length);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
merchantDetailLog.warn('Failed to load tiers:', error.message);
|
merchantDetailLog.warn('Failed to load tiers:', error.message);
|
||||||
|
|||||||
Reference in New Issue
Block a user