// ============================================================================ // API Types - Based on actual API responses // ============================================================================ // ---------------------------------------------------------------------------- // User & Auth // ---------------------------------------------------------------------------- export interface User { id: string; // UUID telegram_id: number; username: string | null; first_name: string | null; last_name: string | null; } export interface AuthCompleteResponse { access_token: string; } // ---------------------------------------------------------------------------- // Pagination // ---------------------------------------------------------------------------- export interface PaginatedResponse { items: T[]; total: number; page: number; size: number; pages: number; } export interface PaginationParams { page?: number; size?: number; } // ---------------------------------------------------------------------------- // Workspaces // ---------------------------------------------------------------------------- export interface Workspace { id: string; // UUID name: string; avatar_url?: string | null; } export interface WorkspaceCreateRequest { name: string; avatar_file?: File | null; } export interface WorkspaceUpdateRequest { name?: string; } // ---------------------------------------------------------------------------- // Workspace Members & Permissions // ---------------------------------------------------------------------------- export type WorkspaceUserStatus = "active" | "invited"; export type PermissionKey = | "admin_full" | "projects_read" | "projects_write" | "placements_read" | "placements_write" | "analytics_read"; export type PermissionScopeType = "project"; export interface PermissionScope { type: PermissionScopeType; id: string; // UUID } export interface Permission { key: PermissionKey; scopes?: PermissionScope[]; } export interface WorkspaceMemberUser { id: string; // user_id telegram_id: number; username: string | null; first_name: string | null; last_name: string | null; } export interface WorkspaceMember { id: string; // member record id status: WorkspaceUserStatus; user: WorkspaceMemberUser; permissions: Permission[]; } export interface UpdatePermissionsRequest { permissions: Permission[]; } // ---------------------------------------------------------------------------- // Workspace Invites // ---------------------------------------------------------------------------- export type WorkspaceInviteStatus = "pending" | "accepted" | "rejected"; export interface WorkspaceInvite { id: string; // UUID username: string; status: WorkspaceInviteStatus; created_at: string; } export interface WorkspaceInviteCreateRequest { username: string; // без @ } // ---------------------------------------------------------------------------- // Projects (Target Channels) // ---------------------------------------------------------------------------- export type ProjectStatus = "active" | "inactive" | "archived"; export interface Project { id: string; // UUID telegram_id: number; title: string; username: string | null; status: ProjectStatus; subscribers_count?: number; purchase_invite_type_default?: "public" | "approval"; } // ---------------------------------------------------------------------------- // Channels (Catalog for Placements) // ---------------------------------------------------------------------------- export type ChannelStatus = "active" | "inactive" | "archived"; export interface Channel { id: string; // UUID telegram_id: number; title: string; username: string | null; description?: string | null; subscribers_count?: number; } export interface ChannelsQueryParams extends PaginationParams { username?: string; } // ---------------------------------------------------------------------------- // Purchase Plan // ---------------------------------------------------------------------------- export type PurchasePlanStatus = "planned" | "completed" | "cancelled"; export interface PurchasePlanChannel { id: string; // UUID status: PurchasePlanStatus; planned_cost: number | null; comment: string | null; channel: { id: string; telegram_id: number; title: string; username: string | null; }; } export interface PurchasePlanChannelCreateRequest { channel_id: string; planned_cost?: number; comment?: string; } export interface PurchasePlanChannelUpdateRequest { planned_cost?: number; comment?: string; } // ---------------------------------------------------------------------------- // Creatives // ---------------------------------------------------------------------------- export type CreativeStatus = "active" | "archived"; export interface Creative { id: string; // UUID name: string; text: string; // Contains {invite_link} placeholder project_id: string; project_channel_title: string; created_at: string; status: CreativeStatus; placements_count: number; } export interface CreativeCreateRequest { name: string; text: string; } export interface CreativeUpdateRequest { name?: string; text?: string; } export interface CreativesQueryParams extends PaginationParams { project_id?: string; include_archived?: boolean; } // ---------------------------------------------------------------------------- // Placements // ---------------------------------------------------------------------------- export type PlacementStatus = | "Без статуса" | "Написать" | "Ждём ответа" | "Согласование условий" | "Оплатить" | "Оплачено" | "Отмена" | "Не подходит цена" | "Неактуально" | "Не отвечает"; export type InviteLinkType = "public" | "approval"; export type PostViewsAvailability = | "unknown" | "available" | "unavailable" | "manual"; export interface PlacementChannel { id: string; telegram_id: number; title: string; username: string | null; subscribers_count?: number; } export interface PlacementCostInfo { type: "fixed" | "cpm"; value: number; } export interface PlacementDetails { placement_at: string | null; // ISO 8601 payment_at: string | null; // ISO 8601 cost: PlacementCostInfo | null; cost_before_bargain: number | null; placement_type: string | null; format: string | null; comment: string | null; creative_id: string | null; } export interface PlacementPost { subscriptions_count: number; views_count: number | null; created_at: string; post: { id: string; message_id: number; text: string; url: string | null; deleted_from_channel_at: string | null; created_at: string; updated_at: string; } | null; } export interface Placement { id: string; status: PlacementStatus; creative_id: string | null; comment: string | null; invite_link: string | null; invite_link_type: InviteLinkType; channel: PlacementChannel; details: PlacementDetails | null; placement_post: PlacementPost | null; created_at: string; } export interface PlacementWithStats extends Placement { cpf: number | null; cpm: number | null; } export interface PlacementsGroupedByChannel { channel: PlacementChannel; placements: PlacementWithStats[]; total_cost: number; total_subscriptions: number; total_views: number; } export interface ProjectPlacementsSummary { total_placements: number; total_channels: number; total_cost: number; total_subscriptions: number; total_views: number; avg_cpf: number | null; avg_cpm: number | null; } export interface PlacementCreateRequest { project_id: string; placement_channel_id: string; creative_id: string; placement_date: string; // ISO 8601 cost?: number; comment?: string; ad_post_url?: string; invite_link_type: InviteLinkType; } export interface PlacementUpdateRequest { placement_date?: string; cost?: number; comment?: string; ad_post_url?: string; } export interface PlacementsQueryParams extends PaginationParams { project_id?: string; placement_channel_id?: string; creative_id?: string; include_archived?: boolean; } // ---------------------------------------------------------------------------- // Views History // ---------------------------------------------------------------------------- export interface ViewsHistoryItem { id: string; // UUID views_count: number; fetched_at: string; // ISO 8601 } export interface ViewsHistoryQueryParams extends PaginationParams { from_date?: string; to_date?: string; } // ---------------------------------------------------------------------------- // Analytics // ---------------------------------------------------------------------------- export type DateGrouping = "day" | "week" | "month" | "DAY" | "WEEK" | "MONTH"; // Placements Analytics (Projects Analytics) export interface PlacementAnalyticsItem { id: string; // UUID project_id: string; // UUID project_channel_title: string; placement_channel_id: string; // UUID placement_channel_title: string; creative_id: string; // UUID creative_name: string; placement_date: string; // ISO 8601 cost: number; subscriptions_count: number; views_count: number; cpf: number; cpm: number; post_url?: string | null; } export interface PlacementsAnalyticsQueryParams extends PaginationParams { project_id?: string; placement_channel_id?: string; creative_id?: string; date_from?: string; date_to?: string; } // Creatives Analytics (matches actual API response) export interface CreativeAnalyticsItem { id: string; name: string; placements_count: number; total_cost: number; total_subscriptions: number; total_views: number; avg_cpf: number | null; // cost per follower (same as CPS) avg_cpm: number | null; } // Channels Analytics export interface ChannelAnalyticsItem { channel_id: string; channel_title: string; channel_username: string | null; placements_count: number; total_cost: number; total_subscriptions: number; total_views: number; avg_cps: number | null; avg_cpm: number | null; } // Spending Analytics export interface SpendingDataPoint { period: string; cost: number; subscriptions: number; views: number; cpf: number | null; cpm: number | null; } export interface SpendingAnalytics { chart_data: SpendingDataPoint[]; total_cost: number; total_subscriptions: number; total_views: number; avg_cpf: number | null; avg_cpm: number | null; placements_count: number; } export interface AnalyticsQueryParams extends PaginationParams { project_id?: string; } // Projects Analytics Chart API export interface ProjectsAnalyticsMetrics { total_cost: number; purchases_count: number; total_subscriptions: number; total_views: number; avg_cpf: number | null; avg_cpm: number | null; avg_post_cost: number | null; clicks_count: number; reach_volume: number; total_discounts: number | null; avg_discount_percent: number | null; avg_conversion: number | null; } export interface ProjectsAnalyticsPeriod { period: string; period_label: string; metrics: ProjectsAnalyticsMetrics; } export interface ProjectsAnalyticsResponse { periods: ProjectsAnalyticsPeriod[]; totals: ProjectsAnalyticsMetrics; } export interface ProjectsAnalyticsQueryParams { project_ids?: string[]; date_from?: string; date_to?: string; grouping: "day" | "week" | "month" | "quarter"; date_grouping: "purchase_date" | "link_date" | "placement_date"; metrics?: string[]; } export interface SpendingAnalyticsQueryParams { project_id?: string; date_from?: string; date_to?: string; grouping?: DateGrouping; } // Overview Analytics export interface OverviewMetric { value: number; delta_percent: number; } export interface OverviewDailyStat { date: string; // YYYY-MM-DD cost: number; subscriptions: number; subscriptions_delta: number; cpf: number; } export interface OverviewChannelCpf { channel_id: string; title: string; username: string | null; cpf: number; total_cost: number; subscriptions: number; } export interface OverviewProjectSpending { project_id: string; project_title: string; project_username: string | null; total_cost: number; } export interface OverviewAnalytics { total_cost: OverviewMetric; total_reach: OverviewMetric; placements_count: OverviewMetric; subscriptions_count: OverviewMetric; avg_cpm: OverviewMetric; avg_cpf: OverviewMetric; daily_stats: OverviewDailyStat[]; top_channels_by_cpf: OverviewChannelCpf[]; worst_channels_by_cpf: OverviewChannelCpf[]; project_spending: OverviewProjectSpending[]; } export interface OverviewAnalyticsQueryParams { project_id?: string; date_from?: string; date_to?: string; } // ---------------------------------------------------------------------------- // Common Types // ---------------------------------------------------------------------------- export interface ApiError { detail: string; } // ---------------------------------------------------------------------------- // Legacy Aliases (for backwards compatibility during migration) // ---------------------------------------------------------------------------- /** @deprecated Use Project instead */ export type TargetChannel = Project; /** @deprecated Use Channel instead */ export type ExternalChannel = Channel; /** @deprecated Use PlacementCreateRequest with new fields */ export type PurchaseCreateRequest = PlacementCreateRequest;