Files
tgex-frontend/lib/types/api.ts
2025-11-19 12:56:04 +03:00

391 lines
9.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================================
// API Types - Generated from API_DOCUMENTATION.md
// ============================================================================
// ----------------------------------------------------------------------------
// User & Auth
// ----------------------------------------------------------------------------
export interface User {
id: string; // UUID
telegram_id: number;
username: string | null;
}
export interface AuthInitResponse {
bot_username: string;
start_param: string; // "login"
}
export interface AuthCompleteRequest {
token: string; // one-time token from bot
}
export interface AuthCompleteResponse {
access_token: string;
refresh_token: string;
user: User;
}
export interface AuthRefreshRequest {
refresh_token: string;
}
export interface AuthRefreshResponse {
access_token: string;
}
// ----------------------------------------------------------------------------
// Target Channel
// ----------------------------------------------------------------------------
// Основная структура как возвращает API
export interface TargetChannel {
id: string; // UUID
telegram_id: number;
title: string;
username: string | null;
is_active: boolean;
}
// Расширенная версия с дополнительными полями (пока не реализовано на бекенде)
export interface TargetChannelDetail extends TargetChannel {
// В будущем можно добавить статистику
}
export interface TargetChannelUpdateRequest {
is_active?: boolean;
}
export interface TargetChannelsListResponse {
target_channels: TargetChannel[];
}
// ----------------------------------------------------------------------------
// External Channel
// ----------------------------------------------------------------------------
// Основная структура как возвращает API
export interface ExternalChannel {
id: string; // UUID
telegram_id: number;
title: string;
username: string | null;
description: string | null;
subscribers_count: number | null;
}
export interface ExternalChannelCreateRequest {
telegram_id: number;
title: string;
username?: string | null;
description?: string | null;
subscribers_count?: number | null;
target_channel_ids: string[]; // UUID[]
}
export interface ExternalChannelUpdateRequest {
title?: string;
username?: string | null;
description?: string | null;
subscribers_count?: number | null;
}
export interface ExternalChannelLinksUpdateRequest {
add_target_channel_ids?: string[];
remove_target_channel_ids?: string[];
}
export interface ExternalChannelsListResponse {
external_channels: ExternalChannel[];
}
// ----------------------------------------------------------------------------
// Creative
// ----------------------------------------------------------------------------
export type CreativeStatus = "active" | "archived";
export interface Creative {
id: string;
name: string;
text: string;
target_channel_id: string;
target_channel_title: string;
created_at: string;
status: CreativeStatus;
placements_count: number;
}
export interface CreativesListResponse {
creatives: Creative[];
}
export interface CreativeCreateRequest {
name: string;
text: string;
target_channel_id: string;
}
export interface CreativeUpdateRequest {
name?: string;
text?: string;
status?: CreativeStatus;
}
// ----------------------------------------------------------------------------
// Placement (Purchase)
// ----------------------------------------------------------------------------
export type InviteLinkType = "public" | "approval";
export type PlacementStatus = "active" | "archived";
export type ViewsAvailability =
| "unknown"
| "available"
| "unavailable"
| "manual";
export interface Placement {
id: string;
target_channel_id: string;
target_channel_title: string;
external_channel_id: string;
external_channel_title: string;
creative_id: string;
creative_name: string;
placement_date: string;
cost: number | null;
comment: string | null;
ad_post_url: string | null;
invite_link_type: InviteLinkType;
invite_link: string;
status: PlacementStatus;
subscriptions_count: number;
views_count: number | null;
views_availability: ViewsAvailability;
last_views_fetch_at: string | null;
created_at: string;
}
export interface PlacementsListResponse {
placements: Placement[];
}
export interface PlacementCreateRequest {
target_channel_id: string;
external_channel_id: string;
creative_id: string;
placement_date: string;
cost?: number | null;
comment?: string | null;
ad_post_url?: string | null;
invite_link_type?: InviteLinkType;
}
export interface PlacementUpdateRequest {
placement_date?: string;
cost?: number | null;
comment?: string | null;
ad_post_url?: string | null;
status?: PlacementStatus;
}
// Legacy aliases for backwards compatibility
export type Purchase = Placement;
export type PurchaseCreateRequest = PlacementCreateRequest;
export type PurchaseUpdateRequest = PlacementUpdateRequest;
export interface ViewsFetchResponse {
placement_id: string;
views_count: number | null;
views_availability: ViewsAvailability;
fetched_at: string;
error_message: string | null;
}
export interface ViewsHistoryResponse {
histories: ViewsSnapshot[];
}
// ----------------------------------------------------------------------------
// Subscription
// ----------------------------------------------------------------------------
export interface Subscription {
id: string;
purchase_id: string;
telegram_user_id: number;
user_first_name: string;
user_last_name: string | null;
user_username: string | null;
subscribed_at: string; // ISO 8601
is_active: boolean;
event_type: "chat_member" | "join_request";
}
// ----------------------------------------------------------------------------
// Views Snapshot
// ----------------------------------------------------------------------------
export interface ViewsSnapshot {
id: string;
purchase_id: string;
views: number;
fetched_at: string; // ISO 8601
}
// ----------------------------------------------------------------------------
// Analytics
// ----------------------------------------------------------------------------
export interface AnalyticsOverview {
totalPurchases: number;
purchasesChange: number;
totalFollowers: number;
followersChange: number;
averageCpf: number;
cpfChange: number;
averageCpm: number;
cpmChange: number;
topChannelsByCpf: {
channel_id: string;
channel_name: string;
total_purchases: number;
avg_cpf: number;
}[];
topCreativesByCpf: {
creative_id: string;
creative_name: string;
total_subscriptions: number;
avg_cpf: number;
}[];
}
export type GroupByPeriod = "day" | "week" | "month" | "quarter" | "year";
export interface AnalyticsCostsDataPoint {
period: string; // ISO 8601 date (start of period)
cost: number;
purchases_count: number;
subscriptions: number;
}
export interface AnalyticsCostsResponse {
data: AnalyticsCostsDataPoint[];
}
export interface CostsReport {
totalCost: number;
averageCost: number;
periods: {
date: string;
total_cost: number;
purchases_count: number;
avg_cost: number;
}[];
}
export interface AnalyticsChannelData {
channel_id: string;
channel_name: string;
purchases_count: number;
total_cost: number;
total_subscriptions: number;
avg_cpf: number;
avg_cpm: number;
}
export interface AnalyticsChannelsResponse {
data: AnalyticsChannelData[];
}
export interface AnalyticsCreativeData {
creative_id: string;
creative_name: string;
purchases_count: number;
total_cost: number;
total_subscriptions: number;
avg_cpf: number;
conversion_rate: number;
}
export interface AnalyticsCreativesResponse {
data: AnalyticsCreativeData[];
}
// ----------------------------------------------------------------------------
// Common API Responses
// ----------------------------------------------------------------------------
export interface ListResponse<T> {
data: T[];
total: number;
}
export interface SuccessResponse {
success: boolean;
}
export interface ApiError {
error: {
code: string;
message: string;
details?: any;
};
}
// ----------------------------------------------------------------------------
// Query Parameters
// ----------------------------------------------------------------------------
export interface TargetChannelQueryParams {
is_active?: boolean;
}
export interface ExternalChannelQueryParams {
target_channel_id?: string;
search?: string;
}
export interface CreativeQueryParams {
target_channel_id?: string;
is_archived?: boolean;
}
export interface PlacementQueryParams {
target_channel_id?: string;
external_channel_id?: string;
creative_id?: string;
is_archived?: boolean;
date_from?: string; // ISO 8601
date_to?: string; // ISO 8601
sort?: "date" | "cost" | "cpf" | "subscriptions";
order?: "asc" | "desc";
}
export interface AnalyticsOverviewQueryParams {
target_channel_id?: string;
date_from?: string;
date_to?: string;
}
export interface AnalyticsCostsQueryParams {
target_channel_id?: string;
date_from: string; // required
date_to: string; // required
group_by: GroupByPeriod;
}
export interface AnalyticsChannelsQueryParams {
target_channel_id?: string;
date_from?: string;
date_to?: string;
type: "external" | "target";
}
export interface AnalyticsCreativesQueryParams {
target_channel_id?: string;
date_from?: string;
date_to?: string;
}