fix: add ResolutionFlow service account to own default tree steps in library

Default/system trees had no author_id (NULL), causing a NOT NULL violation
when syncing steps to step_library.created_by on publish.

- Add is_service_account flag to users table (migration 4f4137ce)
- Add service_account.py: idempotent ensure_service_account() creates
  noreply@resolutionflow.com with unusable password on startup
- Cache service account ID on app.state at lifespan startup
- Add get_service_account_id() FastAPI dep (returns None in tests)
- sync_steps_from_tree: resolve author_id or service_account_id as created_by
- create_tree: set author_id=service_account_id for is_default trees
- Migration 1490781700bc: backfill author_id on 31 existing default trees

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-25 23:17:04 -05:00
parent 0002f75232
commit c2b3937e86
8 changed files with 221 additions and 6 deletions

View File

@@ -155,6 +155,14 @@ async def require_account_owner(
)
def get_service_account_id(request: Request) -> Optional[UUID]:
"""Return the cached ResolutionFlow service account UUID from app.state.
Returns None in test environments where lifespan startup did not run.
"""
return getattr(request.app.state, "service_account_id", None)
async def get_plan_limits_for_user(
current_user: Annotated[User, Depends(get_current_active_user)],
db: Annotated[AsyncSession, Depends(get_db)],