Add the experience service with sites through analytics/AI hooks, migrations through 0011, and phase docs/manifests marking the track complete. Co-authored-by: Cursor <cursoragent@cursor.com>
179 lines
4.7 KiB
Python
179 lines
4.7 KiB
Python
"""Bundle, licensing and feature-toggle DTOs — Phase 11.8."""
|
|
from datetime import datetime
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
from app.models.types import (
|
|
BundleDefinitionStatus,
|
|
BundleKey,
|
|
FeatureToggleStatus,
|
|
LicenseBindingStatus,
|
|
TenantBundleStatus,
|
|
)
|
|
from app.schemas.common import ORMBase
|
|
|
|
_FORBID = ConfigDict(extra="forbid")
|
|
|
|
|
|
class _Create(BaseModel):
|
|
model_config = _FORBID
|
|
metadata_json: dict | None = None
|
|
|
|
|
|
class _Update(BaseModel):
|
|
model_config = _FORBID
|
|
metadata_json: dict | None = None
|
|
version: int = Field(ge=1)
|
|
|
|
|
|
class _Read(ORMBase):
|
|
id: UUID
|
|
tenant_id: UUID
|
|
metadata_json: dict | None
|
|
version: int
|
|
is_deleted: bool
|
|
created_by: str | None
|
|
updated_by: str | None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class BundleDefinitionCreate(_Create):
|
|
workspace_id: UUID | None = None
|
|
code: str = Field(min_length=1, max_length=50)
|
|
bundle_key: BundleKey
|
|
name: str = Field(min_length=1, max_length=255)
|
|
description: str | None = None
|
|
status: BundleDefinitionStatus = BundleDefinitionStatus.DRAFT
|
|
feature_keys: list[str] | None = None
|
|
permission_prefixes: list[str] | None = None
|
|
api_prefixes: list[str] | None = None
|
|
|
|
|
|
class BundleDefinitionUpdate(_Update):
|
|
name: str | None = Field(default=None, min_length=1, max_length=255)
|
|
description: str | None = None
|
|
status: BundleDefinitionStatus | None = None
|
|
feature_keys: list[str] | None = None
|
|
permission_prefixes: list[str] | None = None
|
|
api_prefixes: list[str] | None = None
|
|
|
|
|
|
class BundleDefinitionRead(_Read):
|
|
workspace_id: UUID | None
|
|
code: str
|
|
bundle_key: BundleKey
|
|
name: str
|
|
description: str | None
|
|
status: BundleDefinitionStatus
|
|
feature_keys: list | None
|
|
permission_prefixes: list | None
|
|
api_prefixes: list | None
|
|
|
|
|
|
class BundleDefinitionListResponse(BaseModel):
|
|
items: list[BundleDefinitionRead]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
class TenantBundleCreate(_Create):
|
|
workspace_id: UUID
|
|
site_id: UUID | None = None
|
|
bundle_definition_id: UUID
|
|
status: TenantBundleStatus = TenantBundleStatus.PENDING
|
|
core_entitlement_ref: str | None = Field(default=None, max_length=255)
|
|
expires_at: datetime | None = None
|
|
|
|
|
|
class TenantBundleUpdate(_Update):
|
|
status: TenantBundleStatus | None = None
|
|
core_entitlement_ref: str | None = Field(default=None, max_length=255)
|
|
expires_at: datetime | None = None
|
|
|
|
|
|
class TenantBundleRead(_Read):
|
|
workspace_id: UUID
|
|
site_id: UUID | None
|
|
bundle_definition_id: UUID
|
|
bundle_key: BundleKey
|
|
status: TenantBundleStatus
|
|
core_entitlement_ref: str | None
|
|
activated_at: datetime | None
|
|
expires_at: datetime | None
|
|
activated_by: str | None
|
|
|
|
|
|
class TenantBundleListResponse(BaseModel):
|
|
items: list[TenantBundleRead]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
class LicenseBindingCreate(_Create):
|
|
workspace_id: UUID
|
|
tenant_bundle_id: UUID | None = None
|
|
bundle_key: BundleKey | None = None
|
|
core_entitlement_ref: str = Field(min_length=1, max_length=255)
|
|
status: LicenseBindingStatus = LicenseBindingStatus.PENDING
|
|
starts_at: datetime | None = None
|
|
ends_at: datetime | None = None
|
|
|
|
|
|
class LicenseBindingUpdate(_Update):
|
|
status: LicenseBindingStatus | None = None
|
|
core_entitlement_ref: str | None = Field(default=None, min_length=1, max_length=255)
|
|
starts_at: datetime | None = None
|
|
ends_at: datetime | None = None
|
|
|
|
|
|
class LicenseBindingRead(_Read):
|
|
workspace_id: UUID
|
|
tenant_bundle_id: UUID | None
|
|
bundle_key: BundleKey | None
|
|
core_entitlement_ref: str
|
|
status: LicenseBindingStatus
|
|
starts_at: datetime | None
|
|
ends_at: datetime | None
|
|
|
|
|
|
class LicenseBindingListResponse(BaseModel):
|
|
items: list[LicenseBindingRead]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
|
|
class FeatureToggleCreate(_Create):
|
|
workspace_id: UUID
|
|
site_id: UUID | None = None
|
|
feature_key: str = Field(min_length=1, max_length=100)
|
|
enabled: bool = False
|
|
status: FeatureToggleStatus = FeatureToggleStatus.ACTIVE
|
|
bundle_key: BundleKey | None = None
|
|
|
|
|
|
class FeatureToggleUpdate(_Update):
|
|
enabled: bool | None = None
|
|
status: FeatureToggleStatus | None = None
|
|
bundle_key: BundleKey | None = None
|
|
|
|
|
|
class FeatureToggleRead(_Read):
|
|
workspace_id: UUID
|
|
site_id: UUID | None
|
|
feature_key: str
|
|
enabled: bool
|
|
status: FeatureToggleStatus
|
|
bundle_key: BundleKey | None
|
|
|
|
|
|
class FeatureToggleListResponse(BaseModel):
|
|
items: list[FeatureToggleRead]
|
|
total: int
|
|
page: int
|
|
page_size: int
|