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