feat: platform-aware storefront routing and billing improvements
Overhaul storefront URL routing to be platform-aware:
- Dev: /platforms/{code}/storefront/{store_code}/
- Prod: subdomain.platform.lu/ (internally rewritten to /storefront/)
- Add subdomain detection in PlatformContextMiddleware
- Add /storefront/ path rewrite for prod mode (subdomain/custom domain)
- Remove all silent platform fallbacks (platform_id=1)
- Add require_platform dependency for clean endpoint validation
- Update route registration, templates, module definitions, base_url calc
- Update StoreContextMiddleware for /storefront/ path detection
- Remove /stores/ from FrontendDetector STOREFRONT_PATH_PREFIXES
Billing service improvements:
- Add store_platform_sync_service to keep store_platforms in sync
- Make tier lookups platform-aware across billing services
- Add tiers for all platforms in seed data
- Add demo subscriptions to seed
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -507,3 +507,56 @@ class TestAdminBillingHistory:
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["total"] == 0
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Store Subscription Convenience Endpoint
|
||||
# ============================================================================
|
||||
|
||||
|
||||
class TestAdminStoreSubscription:
|
||||
"""Tests for GET /api/v1/admin/subscriptions/store/{store_id}."""
|
||||
|
||||
def test_get_subscriptions_for_store(
|
||||
self, client, super_admin_headers, rt_subscription, rt_store
|
||||
):
|
||||
"""Returns subscriptions when store has a merchant with subscriptions."""
|
||||
response = client.get(
|
||||
f"{BASE}/store/{rt_store.id}",
|
||||
headers=super_admin_headers,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "subscriptions" in data
|
||||
assert len(data["subscriptions"]) >= 1
|
||||
|
||||
def test_get_subscriptions_for_nonexistent_store(
|
||||
self, client, super_admin_headers
|
||||
):
|
||||
"""Returns 404 for non-existent store ID."""
|
||||
response = client.get(
|
||||
f"{BASE}/store/999999",
|
||||
headers=super_admin_headers,
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rt_store(db, rt_merchant):
|
||||
"""Create a store for route tests."""
|
||||
from app.modules.tenancy.models import Store
|
||||
|
||||
store = Store(
|
||||
merchant_id=rt_merchant.id,
|
||||
store_code=f"RT_{uuid.uuid4().hex[:6].upper()}",
|
||||
name="Route Test Store",
|
||||
subdomain=f"rt-{uuid.uuid4().hex[:8]}",
|
||||
is_active=True,
|
||||
is_verified=True,
|
||||
created_at=datetime.now(UTC),
|
||||
updated_at=datetime.now(UTC),
|
||||
)
|
||||
db.add(store)
|
||||
db.commit()
|
||||
db.refresh(store)
|
||||
return store
|
||||
|
||||
Reference in New Issue
Block a user