411 lines
9.9 KiB
TypeScript
411 lines
9.9 KiB
TypeScript
// ============================================================================
|
|
// API Types - Generated from API_DOCUMENTATION.md
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// User & Auth
|
|
// ----------------------------------------------------------------------------
|
|
|
|
export interface User {
|
|
id: string;
|
|
telegram_id: number;
|
|
username: string | null;
|
|
first_name: string;
|
|
last_name: string | null;
|
|
created_at: string; // ISO 8601
|
|
}
|
|
|
|
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
|
|
// ----------------------------------------------------------------------------
|
|
|
|
export interface TargetChannel {
|
|
id: string;
|
|
telegram_id: number;
|
|
title: string;
|
|
username: string | null; // @channel_name
|
|
description: string | null;
|
|
is_active: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
// Stats
|
|
total_purchases: number;
|
|
total_subscriptions: number;
|
|
avg_cpf: number | null; // Average Cost Per Follower
|
|
}
|
|
|
|
export interface TargetChannelDetail extends TargetChannel {
|
|
recent_purchases: Purchase[]; // last 5
|
|
stats_by_period: {
|
|
period: "day" | "week" | "month";
|
|
subscriptions: number;
|
|
cost: number;
|
|
cpf: number;
|
|
}[];
|
|
}
|
|
|
|
export interface TargetChannelUpdateRequest {
|
|
is_active: boolean;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// External Channel
|
|
// ----------------------------------------------------------------------------
|
|
|
|
export interface ExternalChannel {
|
|
id: string;
|
|
telegram_id: number | null;
|
|
title: string;
|
|
username: string | null;
|
|
link: string; // t.me link or custom
|
|
subscribers_count: number | null;
|
|
description: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
// Relations
|
|
target_channels: string[]; // IDs of target channels
|
|
// Stats
|
|
total_purchases: number;
|
|
avg_cpf: number | null;
|
|
avg_cpm: number | null;
|
|
}
|
|
|
|
export interface ExternalChannelDetail extends ExternalChannel {
|
|
purchases: Purchase[];
|
|
}
|
|
|
|
export interface ExternalChannelCreateRequest {
|
|
title: string;
|
|
username?: string;
|
|
link: string;
|
|
subscribers_count?: number;
|
|
description?: string;
|
|
target_channel_ids: string[]; // Привязка к целевым каналам
|
|
}
|
|
|
|
export interface ExternalChannelUpdateRequest {
|
|
title?: string;
|
|
username?: string;
|
|
link?: string;
|
|
subscribers_count?: number;
|
|
description?: string;
|
|
target_channel_ids?: string[];
|
|
}
|
|
|
|
export interface ExternalChannelImportResponse {
|
|
imported: number;
|
|
skipped: number;
|
|
errors: string[];
|
|
channels: ExternalChannel[];
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Creative
|
|
// ----------------------------------------------------------------------------
|
|
|
|
export interface Creative {
|
|
id: string;
|
|
name: string;
|
|
text: string; // Template with {link} placeholder
|
|
target_channel_id: string;
|
|
is_archived: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
// Relations
|
|
target_channel: TargetChannel;
|
|
// Stats
|
|
total_purchases: number;
|
|
total_subscriptions: number;
|
|
avg_cpf: number | null;
|
|
}
|
|
|
|
export interface CreativeDetail extends Creative {
|
|
purchases: Purchase[];
|
|
}
|
|
|
|
export interface CreativeCreateRequest {
|
|
name: string;
|
|
text: string; // Must contain {link} placeholder
|
|
target_channel_id: string;
|
|
}
|
|
|
|
export interface CreativeUpdateRequest {
|
|
name?: string;
|
|
text?: string;
|
|
is_archived?: boolean;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Purchase
|
|
// ----------------------------------------------------------------------------
|
|
|
|
export type InviteLinkType = "public" | "private";
|
|
|
|
export interface Purchase {
|
|
id: string;
|
|
target_channel_id: string;
|
|
external_channel_id: string;
|
|
creative_id: string;
|
|
// Purchase details
|
|
scheduled_date: string | null; // ISO 8601
|
|
actual_date: string | null;
|
|
cost: number | null; // in rubles
|
|
comment: string | null;
|
|
post_link: string | null; // Link to ad post in external channel
|
|
invite_link: string; // Generated invite link
|
|
invite_link_type: InviteLinkType; // with bot approval or not
|
|
is_archived: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
// Relations
|
|
target_channel: TargetChannel;
|
|
external_channel: ExternalChannel;
|
|
creative: Creative;
|
|
// Stats
|
|
subscriptions_count: number;
|
|
views_count: number | null;
|
|
cpf: number | null; // Cost Per Follower
|
|
cpm: number | null; // Cost Per Mile (1000 views)
|
|
conversion_rate: number | null; // subscriptions / views * 100
|
|
}
|
|
|
|
export interface PurchaseDetail extends Purchase {
|
|
subscriptions: Subscription[];
|
|
views_history: ViewsSnapshot[];
|
|
}
|
|
|
|
export interface PurchaseCreateRequest {
|
|
target_channel_id: string;
|
|
external_channel_id: string;
|
|
creative_id: string;
|
|
scheduled_date?: string;
|
|
actual_date?: string;
|
|
cost?: number;
|
|
comment?: string;
|
|
post_link?: string;
|
|
invite_link_type: InviteLinkType;
|
|
}
|
|
|
|
export interface PurchaseCreateResponse extends Purchase {
|
|
formatted_message: string; // Creative text with invite_link inserted
|
|
}
|
|
|
|
export interface PurchaseUpdateRequest {
|
|
scheduled_date?: string;
|
|
actual_date?: string;
|
|
cost?: number;
|
|
comment?: string;
|
|
post_link?: string;
|
|
is_archived?: boolean;
|
|
}
|
|
|
|
export interface PurchaseRefreshViewsResponse {
|
|
views: number;
|
|
fetched_at: string;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// 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 PurchaseQueryParams {
|
|
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;
|
|
}
|