systemprompt_cli/commands/analytics/content/
mod.rs1mod stats;
11mod top;
12mod trends;
13
14use anyhow::Result;
15use clap::Subcommand;
16use schemars::JsonSchema;
17use serde::{Deserialize, Serialize};
18
19use crate::context::CommandContext;
20use crate::shared::render_result;
21
22#[derive(Debug, Subcommand)]
23pub enum ContentCommands {
24 #[command(about = "Content engagement statistics", alias = "list")]
25 Stats(stats::StatsArgs),
26
27 #[command(about = "Top performing content")]
28 Top(top::TopArgs),
29
30 #[command(about = "Top performing content", hide = true)]
31 Popular(top::TopArgs),
32
33 #[command(about = "Content trends over time")]
34 Trends(trends::TrendsArgs),
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
38pub struct ContentStatsOutput {
39 pub period: String,
40 pub total_views: i64,
41 pub unique_visitors: i64,
42 pub avg_time_on_page_seconds: i64,
43 pub avg_scroll_depth: f64,
44 pub total_clicks: i64,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
48pub struct TopContentRow {
49 #[serde(rename = "content_id")]
50 pub content: String,
51 pub slug: String,
52 pub title: String,
53 pub source: String,
54 pub views: i64,
55 pub unique_visitors: i64,
56 pub avg_time_seconds: i64,
57 pub trend: String,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
61pub struct TopContentOutput {
62 pub period: String,
63 pub content: Vec<TopContentRow>,
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
67pub struct ContentTrendPoint {
68 pub timestamp: String,
69 pub views: i64,
70 pub unique_visitors: i64,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
74pub struct ContentTrendsOutput {
75 pub period: String,
76 pub group_by: String,
77 pub points: Vec<ContentTrendPoint>,
78}
79
80pub async fn execute(command: ContentCommands, ctx: &CommandContext) -> Result<()> {
81 let db_ctx = ctx.database().await?;
82 match command {
83 ContentCommands::Stats(args) => {
84 let result = stats::execute_with_pool(args, &db_ctx, &ctx.cli).await?;
85 render_result(&result, &ctx.cli);
86 Ok(())
87 },
88 ContentCommands::Top(args) | ContentCommands::Popular(args) => {
89 let result = top::execute_with_pool(args, &db_ctx, &ctx.cli).await?;
90 render_result(&result, &ctx.cli);
91 Ok(())
92 },
93 ContentCommands::Trends(args) => {
94 let result = trends::execute_with_pool(args, &db_ctx, &ctx.cli).await?;
95 render_result(&result, &ctx.cli);
96 Ok(())
97 },
98 }
99}