fix: propagate account_id through all write paths missing NOT NULL coverage
Service layer (production code): - branch_manager: set account_id on SessionBranch (root + fork) and ForkPoint from session.account_id; load session in create_fork for this purpose - handoff_manager: set account_id on SessionHandoff from session.account_id - ai_suggestions endpoint: set account_id on AISuggestion from current_user - steps endpoint (/feedback): set account_id on StepRating from current_user - ratings endpoint: set account_id on StepRating from current_user Test infrastructure: - conftest.py: seed PLATFORM_ACCOUNT_ID (00000000-...-0001) account after Base.metadata.create_all so global categories and gallery items have a valid FK - test_rls_isolation: add _ensure_rls_schema fixture that runs 'alembic upgrade head' before module tests — previous function-scoped test_db fixtures drop the schema, leaving the RLS tests with no tables - test_branding: create Account before User in helper functions - test_admin_gallery: set account_id=PLATFORM_ACCOUNT_ID on Tree/ScriptTemplate - test_public_templates: set account_id=PLATFORM_ACCOUNT_ID on Tree, ScriptTemplate, TreeCategory - test_resolution_outputs: set account_id=session.account_id on SessionResolutionOutput - test_analytics_phase5: set account_id on PsaPostLog - test_draft_trees: replace account_id=None with PLATFORM_ACCOUNT_ID in migration default test (NOT NULL now enforced) - test_maintenance_schedules: set account_id on other_tree - test_save_session_as_tree: set account_id on all 5 Session() constructors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.core.security import get_password_hash
|
||||
from app.models.account import Account
|
||||
from app.models.team import Team
|
||||
from app.models.user import User
|
||||
|
||||
@@ -23,6 +24,8 @@ async def _create_team_with_admin(
|
||||
team_name: str = "Branding Test Team",
|
||||
) -> tuple[dict, str, Team]:
|
||||
"""Create a team + team admin user. Returns (auth_headers, team_id_str, team)."""
|
||||
account = Account(name=team_name, display_code=uuid.uuid4().hex[:8].upper())
|
||||
test_db.add(account)
|
||||
team = Team(name=team_name)
|
||||
test_db.add(team)
|
||||
await test_db.flush()
|
||||
@@ -36,6 +39,8 @@ async def _create_team_with_admin(
|
||||
team_id=team.id,
|
||||
is_team_admin=True,
|
||||
role="engineer",
|
||||
account_id=account.id,
|
||||
account_role="engineer",
|
||||
)
|
||||
test_db.add(user)
|
||||
await test_db.commit()
|
||||
@@ -58,6 +63,15 @@ async def _create_team_member(
|
||||
is_team_admin: bool = False,
|
||||
) -> dict:
|
||||
"""Create a regular team member. Returns auth_headers."""
|
||||
# Look up the account associated with this team via an existing member
|
||||
from sqlalchemy import select as _select
|
||||
from app.models.user import User as _User
|
||||
result = await test_db.execute(
|
||||
_select(_User).where(_User.team_id == team.id).limit(1)
|
||||
)
|
||||
team_member = result.scalar_one_or_none()
|
||||
member_account_id = team_member.account_id if team_member else None
|
||||
|
||||
email = f"member_{uuid.uuid4().hex[:8]}@test.com"
|
||||
user = User(
|
||||
email=email,
|
||||
@@ -67,6 +81,8 @@ async def _create_team_member(
|
||||
team_id=team.id,
|
||||
is_team_admin=is_team_admin,
|
||||
role="engineer",
|
||||
account_id=member_account_id,
|
||||
account_role="engineer",
|
||||
)
|
||||
test_db.add(user)
|
||||
await test_db.commit()
|
||||
|
||||
Reference in New Issue
Block a user