6f806ff4a4
Adds deerflow/persistence/external_user/{__init__,model}.py with
ExternalUserRow:
- id: UUID36 PK
- workspace_id: FK workspaces ON DELETE CASCADE (redundant with SA's
workspace_id but stored directly to speed workspace-scoped queries
that span multiple SAs)
- service_account_id: FK service_accounts ON DELETE CASCADE
- external_id: String(128) — caller-supplied X-External-User-Id
- display_name: String(128) nullable (admin UI only, not auth-relevant)
- metadata_json: JSON nullable=False default {} — plan tier / region /
custom tags
- created_at / last_seen_at (UTC)
- UniqueConstraint (service_account_id, external_id)
name=uq_external_users_sa_external — the same external_id may be
reused under a different SA, but is upsert-unique under a single SA
T8.5 tests:
- test_unique_service_account_id_plus_external_id: second row with
same (SA, external_id) raises IntegrityError
- test_cascade_on_service_account_delete: deleting parent SA removes
all external_users rows under it
Registered in deerflow/persistence/models/__init__.py — all three PR8
tables (service_accounts / api_keys / external_users) are now wired
into Base.metadata.create_all().
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
45 lines
1.7 KiB
Python
45 lines
1.7 KiB
Python
"""ORM model registration entry point.
|
|
|
|
Importing this module ensures all ORM models are registered with
|
|
``Base.metadata`` so Alembic autogenerate detects every table.
|
|
|
|
The actual ORM classes have moved to entity-specific subpackages:
|
|
- ``deerflow.persistence.thread_meta``
|
|
- ``deerflow.persistence.run``
|
|
- ``deerflow.persistence.feedback``
|
|
- ``deerflow.persistence.user``
|
|
- ``deerflow.persistence.workspace`` (Stage 0 PR3)
|
|
- ``deerflow.persistence.workspace_membership`` (Stage 0 PR3)
|
|
- ``deerflow.persistence.service_account`` (Stage 0 PR8)
|
|
- ``deerflow.persistence.api_key`` (Stage 0 PR8)
|
|
- ``deerflow.persistence.external_user`` (Stage 0 PR8)
|
|
|
|
``RunEventRow`` remains in ``deerflow.persistence.models.run_event`` because
|
|
its storage implementation lives in ``deerflow.runtime.events.store.db`` and
|
|
there is no matching entity directory.
|
|
"""
|
|
|
|
from deerflow.persistence.api_key.model import ApiKeyRow
|
|
from deerflow.persistence.external_user.model import ExternalUserRow
|
|
from deerflow.persistence.feedback.model import FeedbackRow
|
|
from deerflow.persistence.models.run_event import RunEventRow
|
|
from deerflow.persistence.run.model import RunRow
|
|
from deerflow.persistence.service_account.model import ServiceAccountRow
|
|
from deerflow.persistence.thread_meta.model import ThreadMetaRow
|
|
from deerflow.persistence.user.model import UserRow
|
|
from deerflow.persistence.workspace.model import WorkspaceRow
|
|
from deerflow.persistence.workspace_membership.model import WorkspaceMembershipRow
|
|
|
|
__all__ = [
|
|
"ApiKeyRow",
|
|
"ExternalUserRow",
|
|
"FeedbackRow",
|
|
"RunEventRow",
|
|
"RunRow",
|
|
"ServiceAccountRow",
|
|
"ThreadMetaRow",
|
|
"UserRow",
|
|
"WorkspaceMembershipRow",
|
|
"WorkspaceRow",
|
|
]
|