# Требования к API для аналитики по проектам ## Endpoint ``` GET /api/v1/workspaces/{workspace_id}/analytics/projects ``` ## Параметры запроса (Query Parameters) | Параметр | Тип | Обязательный | Описание | |----------|-----|-------------|----------| | `project_ids` | `string[]` | Нет | Массив UUID проектов для фильтрации. Если не указан - все проекты workspace | | `date_from` | `string (ISO 8601)` | Нет | Начало периода (например: `2024-12-01T00:00:00Z`) | | `date_to` | `string (ISO 8601)` | Нет | Конец периода (например: `2024-12-31T23:59:59Z`) | | `grouping` | `enum: "day" \| "week" \| "month" \| "quarter"` | Да | Группировка данных по периодам | | `date_grouping` | `enum: "purchase_date" \| "link_date" \| "placement_date"` | Да | По какой дате группировать размещения | | `metrics` | `string[]` | Нет | Массив метрик для расчета. Если не указан - возвращаются все доступные метрики | ### Доступные метрики: - `total_cost` - Сумма расходов - `purchases_count` - Количество закупов (размещений) - `total_subscriptions` - Общее количество подписок - `total_views` - Общее количество просмотров - `avg_cpf` - Средний CPF (cost per follower) - `avg_cpm` - Средний CPM (cost per mille) - `avg_post_cost` - Средняя стоимость поста - `clicks_count` - Количество переходов (кликов) - `reach_volume` - Объем охвата - `total_discounts` - Сумма скидок - `avg_discount_percent` - Средний процент скидки - `avg_conversion` - Средняя конверсия закупов ## Формат ответа ```json { "periods": [ { "period": "2024-12-01", "period_label": "1 дек", "metrics": { "total_cost": 5500.0, "purchases_count": 3, "total_subscriptions": 156, "total_views": 8500, "avg_cpf": 35.26, "avg_cpm": 647.06, "avg_post_cost": 1833.33, "clicks_count": 156, "reach_volume": 8500, "total_discounts": 0.0, "avg_discount_percent": 0.0, "avg_conversion": 0.0 } }, { "period": "2024-12-02", "period_label": "2 дек", "metrics": { "total_cost": 3200.0, "purchases_count": 2, "total_subscriptions": 89, "total_views": 4200, "avg_cpf": 35.96, "avg_cpm": 761.9, "avg_post_cost": 1600.0, "clicks_count": 89, "reach_volume": 4200, "total_discounts": 0.0, "avg_discount_percent": 0.0, "avg_conversion": 0.0 } } ], "totals": { "total_cost": 8700.0, "purchases_count": 5, "total_subscriptions": 245, "total_views": 12700, "avg_cpf": 35.51, "avg_cpm": 685.04, "avg_post_cost": 1740.0, "clicks_count": 245, "reach_volume": 12700, "total_discounts": 0.0, "avg_discount_percent": 0.0, "avg_conversion": 0.0 } } ``` ## Примеры запросов ### Пример 1: График расходов по дням за декабрь ```http GET /api/v1/workspaces/123e4567-e89b-12d3-a456-426614174000/analytics/projects?grouping=day&date_grouping=placement_date&date_from=2024-12-01T00:00:00Z&date_to=2024-12-31T23:59:59Z&metrics[]=total_cost&project_ids[]=proj-001&project_ids[]=proj-002 ``` ### Пример 2: Средний CPF по неделям ```http GET /api/v1/workspaces/123e4567-e89b-12d3-a456-426614174000/analytics/projects?grouping=week&date_grouping=placement_date&metrics[]=avg_cpf&metrics[]=total_subscriptions ``` ### Пример 3: Все метрики по месяцам ```http GET /api/v1/workspaces/123e4567-e89b-12d3-a456-426614174000/analytics/projects?grouping=month&date_grouping=purchase_date&date_from=2024-01-01T00:00:00Z&date_to=2024-12-31T23:59:59Z ``` ## Формат периода (period) В зависимости от `grouping`: - `day`: `"YYYY-MM-DD"` (например: `"2024-12-01"`) - `week`: `"YYYY-Www"` (например: `"2024-W49"`) - ISO week format - `month`: `"YYYY-MM"` (например: `"2024-12"`) - `quarter`: `"YYYY-QN"` (например: `"2024-Q4"`) ## Формат period_label Человекочитаемая метка периода для отображения на графике: - `day`: `"1 дек"` или `"1 дек 2024"` - `week`: `"49 нед. 2024"` или `"1-7 дек"` - `month`: `"дек 2024"` - `quarter`: `"Q4 2024"` ## Логика расчета метрик ### Агрегации (SUM): - `total_cost` - сумма всех `cost` - `total_subscriptions` - сумма всех `subscriptions_count` - `total_views` - сумма всех `views_count` - `total_discounts` - сумма всех скидок - `clicks_count` - сумма всех кликов - `reach_volume` - сумма всех просмотров (аналогично `total_views`) ### Счетчики (COUNT): - `purchases_count` - количество размещений в периоде ### Средние значения (AVG): - `avg_cpf` = `total_cost / total_subscriptions` (если `total_subscriptions > 0`) - `avg_cpm` = `(total_cost / total_views) * 1000` (если `total_views > 0`) - `avg_post_cost` = `total_cost / purchases_count` (если `purchases_count > 0`) - `avg_discount_percent` = средний процент скидки по размещениям - `avg_conversion` = средняя конверсия закупов ### Totals (итоговые значения): Все метрики в `totals` рассчитываются как агрегация по всем периодам в ответе. ## Обработка ошибок ### 400 Bad Request ```json { "detail": [ { "loc": ["query", "grouping"], "msg": "Invalid grouping value. Must be one of: day, week, month, quarter", "type": "value_error" } ] } ``` ### 422 Unprocessable Entity ```json { "detail": [ { "loc": ["query", "date_from"], "msg": "date_from must be before date_to", "type": "value_error" } ] } ``` ## Примечания - Если для метрики нет данных (например, `total_discounts`), возвращается `0` или `null` - Если знаменатель равен 0 при расчете средних значений, возвращается `null` - Периоды сортируются по возрастанию (`period`) - Если данных нет для какого-то периода, он не включается в ответ (или включается с нулевыми значениями - на усмотрение бэкенда)