geo/backend/app/schemas/analytics.py

145 lines
3.8 KiB
Python

"""监测优化 Pydantic v2 Schemas"""
from __future__ import annotations
from datetime import datetime
from typing import Any
from pydantic import BaseModel, Field
# ------------------------------------------------------------------ #
# PublishRecord
# ------------------------------------------------------------------ #
class PublishRecordCreate(BaseModel):
content_title: str = Field(..., max_length=200)
content_id: str | None = None
platform: str = Field(..., max_length=50)
published_url: str | None = None
status: str = Field(default="published", max_length=20)
published_at: datetime | None = None
class PublishRecordResponse(BaseModel):
id: str
organization_id: str
content_title: str
content_id: str | None
platform: str
published_url: str | None
status: str
published_at: datetime | None
created_at: datetime
model_config = {"from_attributes": True}
# ------------------------------------------------------------------ #
# ContentMetrics
# ------------------------------------------------------------------ #
class MetricsUpdateRequest(BaseModel):
views: int = Field(default=0, ge=0)
likes: int = Field(default=0, ge=0)
comments: int = Field(default=0, ge=0)
shares: int = Field(default=0, ge=0)
bookmarks: int = Field(default=0, ge=0)
ai_citation_count: int = Field(default=0, ge=0)
search_impressions: int = Field(default=0, ge=0)
search_clicks: int = Field(default=0, ge=0)
avg_read_duration: float = Field(default=0.0, ge=0.0)
read_completion_rate: float = Field(default=0.0, ge=0.0, le=1.0)
class MetricsResponse(BaseModel):
id: str
publish_record_id: str
recorded_at: datetime
views: int
likes: int
comments: int
shares: int
bookmarks: int
ai_citation_count: int
search_impressions: int
search_clicks: int
avg_read_duration: float
read_completion_rate: float
model_config = {"from_attributes": True}
# ------------------------------------------------------------------ #
# Overview
# ------------------------------------------------------------------ #
class OverviewStatsResponse(BaseModel):
total_published: int
total_views: int
total_interactions: int
total_ai_citations: int
avg_engagement_rate: float
platform_distribution: dict[str, int]
# ------------------------------------------------------------------ #
# Content Performance
# ------------------------------------------------------------------ #
class ContentPerformanceResponse(BaseModel):
id: str
content_title: str
platform: str
published_url: str | None
status: str
published_at: str | None
latest_metrics: dict[str, Any] | None
metrics_history: list[dict[str, Any]]
# ------------------------------------------------------------------ #
# Insight
# ------------------------------------------------------------------ #
class InsightResponse(BaseModel):
id: str
organization_id: str
content_id: str | None
insight_type: str
title: str
description: str
recommendation: str
severity: str
applied: bool
created_at: datetime
model_config = {"from_attributes": True}
# ------------------------------------------------------------------ #
# Top Content
# ------------------------------------------------------------------ #
class TopContentItem(BaseModel):
publish_record_id: str
content_title: str
platform: str
published_url: str | None
views: int
likes: int
comments: int
shares: int
bookmarks: int
ai_citation_count: int
search_impressions: int
search_clicks: int
avg_read_duration: float
read_completion_rate: float
recorded_at: str | None
class TopContentResponse(BaseModel):
items: list[TopContentItem]
sort_by: str
total: int