from __future__ import annotations from dataclasses import asdict from datetime import datetime from typing import Any from app.domain.admin import Experiment, ExperimentRelease, Goal, SdkConfig, Site, Variant from app.schemas.common import ApiModel, ItemListResponse class SiteRead(ApiModel): id: str site_key: str name: str primary_domain: str status: str site_settings: dict[str, Any] | list[Any] | None = None class SiteListResponse(ItemListResponse): items: list[SiteRead] class ExperimentRead(ApiModel): id: str site_id: str experiment_key: str name: str module_type: str status: str start_at: datetime | None = None end_at: datetime | None = None targeting_config: dict[str, Any] | list[Any] | None = None class ExperimentListResponse(ItemListResponse): items: list[ExperimentRead] class ExperimentCreate(ApiModel): site_id: str name: str module_type: str = "visual" status: str = "draft" start_at: datetime | None = None end_at: datetime | None = None targeting_config: dict[str, Any] | None = None class ExperimentUpdate(ApiModel): name: str | None = None module_type: str | None = None status: str | None = None start_at: datetime | None = None end_at: datetime | None = None targeting_config: dict[str, Any] | None = None class VariantRead(ApiModel): id: str experiment_id: str variant_key: str name: str traffic_weight: int content_config: dict[str, Any] | list[Any] | None = None class VariantListResponse(ItemListResponse): items: list[VariantRead] class VariantCreate(ApiModel): experiment_id: str name: str traffic_weight: int = 0 content_config: dict[str, Any] | None = None class VariantUpdate(ApiModel): name: str | None = None traffic_weight: int | None = None content_config: dict[str, Any] | None = None class ReleaseRead(ApiModel): id: str experiment_id: str version_no: int status: str runtime_payload: dict[str, Any] | list[Any] | None = None class ReleaseListResponse(ItemListResponse): items: list[ReleaseRead] class BuildReleaseRequest(ApiModel): experiment_id: str class ReleaseLifecycleResponse(ApiModel): id: str status: str version_no: int class GoalRead(ApiModel): id: str site_id: str goal_key: str name: str goal_type: str match_rule: dict[str, Any] | list[Any] | None = None class GoalListResponse(ItemListResponse): items: list[GoalRead] class SdkConfigRead(ApiModel): id: str site_id: str sdk_key: str status: str origin_url: str | None = None cdn_url: str | None = None sdk_config: dict[str, Any] | list[Any] | None = None class SdkConfigListResponse(ItemListResponse): items: list[SdkConfigRead] def site_to_read_model(site: Site) -> SiteRead: return SiteRead( id=site.id, site_key=site.site_key, name=site.name, primary_domain=site.primary_domain, status=site.status, site_settings=site.settings, ) def experiment_to_read_model(experiment: Experiment) -> ExperimentRead: return ExperimentRead(**asdict(experiment)) def variant_to_read_model(variant: Variant) -> VariantRead: return VariantRead(**asdict(variant)) def release_to_read_model(release: ExperimentRelease) -> ReleaseRead: return ReleaseRead(**asdict(release)) def goal_to_read_model(goal: Goal) -> GoalRead: return GoalRead(**asdict(goal)) def sdk_config_to_read_model(sdk_config: SdkConfig) -> SdkConfigRead: return SdkConfigRead(**asdict(sdk_config)) class ActivityLogRead(ApiModel): id: int action: str action_label: str = "" collection: str collection_label: str = "" item: str timestamp: datetime | None = None actor_email: str | None = None actor_id: str | None = None class ActivityLogListResponse(ApiModel): items: list[ActivityLogRead]