feat(deps): add require_active_subscription guard with allowlist

Mounts on Pro routers (trees, sessions, scripts, FlowPilot, etc.) and
returns 402 with structured detail when an account's subscription is
missing or locked. Allowlist bypasses billing/account/auth flows so
users can recover from a lapsed subscription.

Conftest now seeds a default Pro/active Subscription on test_user and
test_admin (delete-then-insert because the register endpoint already
creates a free/active sub by default). Two existing tests adapted to
the new seeded plan; tenant-isolation tests seed Subscription rows for
the accounts they create directly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 14:35:59 -04:00
parent cfe0e6cae6
commit 9ec208f6e7
7 changed files with 245 additions and 29 deletions

View File

@@ -21,17 +21,21 @@ class TestAccountEndpoints:
@pytest.mark.asyncio
async def test_get_my_subscription(self, client: AsyncClient, auth_headers: dict):
"""Test getting current user's subscription details."""
"""Test getting current user's subscription details.
The test_user fixture seeds a Pro/active Subscription so
Pro-guarded routers work; reflect that in the expected plan.
"""
response = await client.get("/api/v1/accounts/me/subscription", headers=auth_headers)
assert response.status_code == 200
data = response.json()
assert "subscription" in data
assert "limits" in data
assert "usage" in data
assert data["subscription"]["plan"] == "free"
assert data["subscription"]["plan"] == "pro"
assert data["subscription"]["status"] == "active"
assert data["limits"]["max_trees"] == 3
assert data["limits"]["max_sessions_per_month"] == 20
assert data["limits"]["max_trees"] == 25
assert data["limits"]["max_sessions_per_month"] == 200
@pytest.mark.asyncio
async def test_get_my_members(self, client: AsyncClient, auth_headers: dict):