// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.30.0 // source: analytics.sql package dbgen import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const AnalyticsCourseCounts = `-- name: AnalyticsCourseCounts :one SELECT 0::bigint AS total_categories, 0::bigint AS total_courses, 0::bigint AS total_sub_courses, 0::bigint AS total_videos ` type AnalyticsCourseCountsRow struct { TotalCategories int64 `json:"total_categories"` TotalCourses int64 `json:"total_courses"` TotalSubCourses int64 `json:"total_sub_courses"` TotalVideos int64 `json:"total_videos"` } // ===================== // Course Analytics // ===================== func (q *Queries) AnalyticsCourseCounts(ctx context.Context) (AnalyticsCourseCountsRow, error) { row := q.db.QueryRow(ctx, AnalyticsCourseCounts) var i AnalyticsCourseCountsRow err := row.Scan( &i.TotalCategories, &i.TotalCourses, &i.TotalSubCourses, &i.TotalVideos, ) return i, err } const AnalyticsIssuesByStatus = `-- name: AnalyticsIssuesByStatus :many SELECT COALESCE(ri.status, 'unknown') AS status, COUNT(*)::bigint AS count FROM reported_issues ri WHERE ($1::timestamptz IS NULL OR ri.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR ri.created_at < $2::timestamptz) GROUP BY ri.status ORDER BY count DESC ` type AnalyticsIssuesByStatusParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsIssuesByStatusRow struct { Status string `json:"status"` Count int64 `json:"count"` } func (q *Queries) AnalyticsIssuesByStatus(ctx context.Context, arg AnalyticsIssuesByStatusParams) ([]AnalyticsIssuesByStatusRow, error) { rows, err := q.db.Query(ctx, AnalyticsIssuesByStatus, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsIssuesByStatusRow for rows.Next() { var i AnalyticsIssuesByStatusRow if err := rows.Scan(&i.Status, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsIssuesByType = `-- name: AnalyticsIssuesByType :many SELECT COALESCE(ri.issue_type, 'unknown') AS issue_type, COUNT(*)::bigint AS count FROM reported_issues ri WHERE ($1::timestamptz IS NULL OR ri.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR ri.created_at < $2::timestamptz) GROUP BY ri.issue_type ORDER BY count DESC ` type AnalyticsIssuesByTypeParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsIssuesByTypeRow struct { IssueType string `json:"issue_type"` Count int64 `json:"count"` } func (q *Queries) AnalyticsIssuesByType(ctx context.Context, arg AnalyticsIssuesByTypeParams) ([]AnalyticsIssuesByTypeRow, error) { rows, err := q.db.Query(ctx, AnalyticsIssuesByType, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsIssuesByTypeRow for rows.Next() { var i AnalyticsIssuesByTypeRow if err := rows.Scan(&i.IssueType, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsIssuesSummary = `-- name: AnalyticsIssuesSummary :one SELECT COUNT(*)::bigint AS total, COUNT(*) FILTER (WHERE ri.status = 'resolved')::bigint AS resolved, CASE WHEN COUNT(*) > 0 THEN (COUNT(*) FILTER (WHERE ri.status = 'resolved')::float8 / COUNT(*)::float8) ELSE 0::float8 END AS resolution_rate FROM reported_issues ri WHERE ($1::timestamptz IS NULL OR ri.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR ri.created_at < $2::timestamptz) ` type AnalyticsIssuesSummaryParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsIssuesSummaryRow struct { Total int64 `json:"total"` Resolved int64 `json:"resolved"` ResolutionRate float64 `json:"resolution_rate"` } // ===================== // Issue Analytics // ===================== func (q *Queries) AnalyticsIssuesSummary(ctx context.Context, arg AnalyticsIssuesSummaryParams) (AnalyticsIssuesSummaryRow, error) { row := q.db.QueryRow(ctx, AnalyticsIssuesSummary, arg.RangeStart, arg.RangeEnd) var i AnalyticsIssuesSummaryRow err := row.Scan(&i.Total, &i.Resolved, &i.ResolutionRate) return i, err } const AnalyticsNewSubscriptionsLast30Days = `-- name: AnalyticsNewSubscriptionsLast30Days :many SELECT d.date, COUNT(us.id)::bigint AS count FROM generate_series( $1::date, $2::date, INTERVAL '1 day' ) AS d(date) LEFT JOIN user_subscriptions us ON us.created_at::date = d.date AND ($3::timestamptz IS NULL OR us.created_at >= $3::timestamptz) AND ($4::timestamptz IS NULL OR us.created_at < $4::timestamptz) GROUP BY d.date ORDER BY d.date ` type AnalyticsNewSubscriptionsLast30DaysParams struct { SeriesStart pgtype.Date `json:"series_start"` SeriesEnd pgtype.Date `json:"series_end"` RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsNewSubscriptionsLast30DaysRow struct { Date interface{} `json:"date"` Count int64 `json:"count"` } func (q *Queries) AnalyticsNewSubscriptionsLast30Days(ctx context.Context, arg AnalyticsNewSubscriptionsLast30DaysParams) ([]AnalyticsNewSubscriptionsLast30DaysRow, error) { rows, err := q.db.Query(ctx, AnalyticsNewSubscriptionsLast30Days, arg.SeriesStart, arg.SeriesEnd, arg.RangeStart, arg.RangeEnd, ) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsNewSubscriptionsLast30DaysRow for rows.Next() { var i AnalyticsNewSubscriptionsLast30DaysRow if err := rows.Scan(&i.Date, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsNotificationsByChannel = `-- name: AnalyticsNotificationsByChannel :many SELECT COALESCE(n.channel, 'unknown') AS channel, COUNT(*)::bigint AS count FROM notifications n WHERE ($1::timestamptz IS NULL OR n.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR n.created_at < $2::timestamptz) GROUP BY n.channel ORDER BY count DESC ` type AnalyticsNotificationsByChannelParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsNotificationsByChannelRow struct { Channel string `json:"channel"` Count int64 `json:"count"` } func (q *Queries) AnalyticsNotificationsByChannel(ctx context.Context, arg AnalyticsNotificationsByChannelParams) ([]AnalyticsNotificationsByChannelRow, error) { rows, err := q.db.Query(ctx, AnalyticsNotificationsByChannel, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsNotificationsByChannelRow for rows.Next() { var i AnalyticsNotificationsByChannelRow if err := rows.Scan(&i.Channel, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsNotificationsByType = `-- name: AnalyticsNotificationsByType :many SELECT COALESCE(n.type, 'unknown') AS type, COUNT(*)::bigint AS count FROM notifications n WHERE ($1::timestamptz IS NULL OR n.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR n.created_at < $2::timestamptz) GROUP BY n.type ORDER BY count DESC ` type AnalyticsNotificationsByTypeParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsNotificationsByTypeRow struct { Type string `json:"type"` Count int64 `json:"count"` } func (q *Queries) AnalyticsNotificationsByType(ctx context.Context, arg AnalyticsNotificationsByTypeParams) ([]AnalyticsNotificationsByTypeRow, error) { rows, err := q.db.Query(ctx, AnalyticsNotificationsByType, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsNotificationsByTypeRow for rows.Next() { var i AnalyticsNotificationsByTypeRow if err := rows.Scan(&i.Type, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsNotificationsSummary = `-- name: AnalyticsNotificationsSummary :one SELECT COUNT(*)::bigint AS total, COUNT(*) FILTER (WHERE n.is_read = TRUE)::bigint AS read, COUNT(*) FILTER (WHERE n.is_read = FALSE)::bigint AS unread FROM notifications n WHERE ($1::timestamptz IS NULL OR n.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR n.created_at < $2::timestamptz) ` type AnalyticsNotificationsSummaryParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsNotificationsSummaryRow struct { Total int64 `json:"total"` Read int64 `json:"read"` Unread int64 `json:"unread"` } // ===================== // Notification Analytics // ===================== func (q *Queries) AnalyticsNotificationsSummary(ctx context.Context, arg AnalyticsNotificationsSummaryParams) (AnalyticsNotificationsSummaryRow, error) { row := q.db.QueryRow(ctx, AnalyticsNotificationsSummary, arg.RangeStart, arg.RangeEnd) var i AnalyticsNotificationsSummaryRow err := row.Scan(&i.Total, &i.Read, &i.Unread) return i, err } const AnalyticsPaymentsByMethod = `-- name: AnalyticsPaymentsByMethod :many SELECT COALESCE(p.payment_method, 'unknown') AS payment_method, COUNT(*)::bigint AS count, COALESCE(SUM(p.amount), 0)::float8 AS total_amount FROM payments p WHERE p.status = 'SUCCESS' AND ($1::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) >= $1::timestamptz) AND ($2::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) < $2::timestamptz) GROUP BY p.payment_method ORDER BY count DESC ` type AnalyticsPaymentsByMethodParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsPaymentsByMethodRow struct { PaymentMethod string `json:"payment_method"` Count int64 `json:"count"` TotalAmount float64 `json:"total_amount"` } func (q *Queries) AnalyticsPaymentsByMethod(ctx context.Context, arg AnalyticsPaymentsByMethodParams) ([]AnalyticsPaymentsByMethodRow, error) { rows, err := q.db.Query(ctx, AnalyticsPaymentsByMethod, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsPaymentsByMethodRow for rows.Next() { var i AnalyticsPaymentsByMethodRow if err := rows.Scan(&i.PaymentMethod, &i.Count, &i.TotalAmount); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsPaymentsByStatus = `-- name: AnalyticsPaymentsByStatus :many SELECT COALESCE(p.status, 'unknown') AS status, COUNT(*)::bigint AS count, COALESCE(SUM(p.amount), 0)::float8 AS total_amount FROM payments p WHERE ($1::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) >= $1::timestamptz) AND ($2::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) < $2::timestamptz) GROUP BY p.status ORDER BY count DESC ` type AnalyticsPaymentsByStatusParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsPaymentsByStatusRow struct { Status string `json:"status"` Count int64 `json:"count"` TotalAmount float64 `json:"total_amount"` } func (q *Queries) AnalyticsPaymentsByStatus(ctx context.Context, arg AnalyticsPaymentsByStatusParams) ([]AnalyticsPaymentsByStatusRow, error) { rows, err := q.db.Query(ctx, AnalyticsPaymentsByStatus, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsPaymentsByStatusRow for rows.Next() { var i AnalyticsPaymentsByStatusRow if err := rows.Scan(&i.Status, &i.Count, &i.TotalAmount); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsPaymentsSummary = `-- name: AnalyticsPaymentsSummary :one SELECT COALESCE(SUM(p.amount) FILTER (WHERE p.status = 'SUCCESS'), 0)::float8 AS total_revenue, COALESCE(AVG(p.amount) FILTER (WHERE p.status = 'SUCCESS'), 0)::float8 AS avg_value, COUNT(*)::bigint AS total_payments, COUNT(*) FILTER (WHERE p.status = 'SUCCESS')::bigint AS successful_payments FROM payments p WHERE ($1::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) >= $1::timestamptz) AND ($2::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) < $2::timestamptz) ` type AnalyticsPaymentsSummaryParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsPaymentsSummaryRow struct { TotalRevenue float64 `json:"total_revenue"` AvgValue float64 `json:"avg_value"` TotalPayments int64 `json:"total_payments"` SuccessfulPayments int64 `json:"successful_payments"` } // ===================== // Payment Analytics // ===================== func (q *Queries) AnalyticsPaymentsSummary(ctx context.Context, arg AnalyticsPaymentsSummaryParams) (AnalyticsPaymentsSummaryRow, error) { row := q.db.QueryRow(ctx, AnalyticsPaymentsSummary, arg.RangeStart, arg.RangeEnd) var i AnalyticsPaymentsSummaryRow err := row.Scan( &i.TotalRevenue, &i.AvgValue, &i.TotalPayments, &i.SuccessfulPayments, ) return i, err } const AnalyticsQuestionSetsByType = `-- name: AnalyticsQuestionSetsByType :many SELECT COALESCE(qs.set_type, 'unknown') AS set_type, COUNT(*)::bigint AS count FROM question_sets qs WHERE ($1::timestamptz IS NULL OR qs.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR qs.created_at < $2::timestamptz) GROUP BY qs.set_type ORDER BY count DESC ` type AnalyticsQuestionSetsByTypeParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsQuestionSetsByTypeRow struct { SetType string `json:"set_type"` Count int64 `json:"count"` } func (q *Queries) AnalyticsQuestionSetsByType(ctx context.Context, arg AnalyticsQuestionSetsByTypeParams) ([]AnalyticsQuestionSetsByTypeRow, error) { rows, err := q.db.Query(ctx, AnalyticsQuestionSetsByType, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsQuestionSetsByTypeRow for rows.Next() { var i AnalyticsQuestionSetsByTypeRow if err := rows.Scan(&i.SetType, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsQuestionsByType = `-- name: AnalyticsQuestionsByType :many SELECT COALESCE(q.question_type, 'unknown') AS question_type, COUNT(*)::bigint AS count FROM questions q WHERE ($1::timestamptz IS NULL OR q.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR q.created_at < $2::timestamptz) GROUP BY q.question_type ORDER BY count DESC ` type AnalyticsQuestionsByTypeParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsQuestionsByTypeRow struct { QuestionType string `json:"question_type"` Count int64 `json:"count"` } func (q *Queries) AnalyticsQuestionsByType(ctx context.Context, arg AnalyticsQuestionsByTypeParams) ([]AnalyticsQuestionsByTypeRow, error) { rows, err := q.db.Query(ctx, AnalyticsQuestionsByType, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsQuestionsByTypeRow for rows.Next() { var i AnalyticsQuestionsByTypeRow if err := rows.Scan(&i.QuestionType, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsQuestionsCounts = `-- name: AnalyticsQuestionsCounts :one SELECT ( SELECT COUNT(*)::bigint FROM questions q WHERE ($1::timestamptz IS NULL OR q.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR q.created_at < $2::timestamptz) ) AS total_questions, ( SELECT COUNT(*)::bigint FROM question_sets qs WHERE ($1::timestamptz IS NULL OR qs.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR qs.created_at < $2::timestamptz) ) AS total_question_sets ` type AnalyticsQuestionsCountsParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsQuestionsCountsRow struct { TotalQuestions int64 `json:"total_questions"` TotalQuestionSets int64 `json:"total_question_sets"` } // ===================== // Content Analytics // ===================== func (q *Queries) AnalyticsQuestionsCounts(ctx context.Context, arg AnalyticsQuestionsCountsParams) (AnalyticsQuestionsCountsRow, error) { row := q.db.QueryRow(ctx, AnalyticsQuestionsCounts, arg.RangeStart, arg.RangeEnd) var i AnalyticsQuestionsCountsRow err := row.Scan(&i.TotalQuestions, &i.TotalQuestionSets) return i, err } const AnalyticsRevenueByPlan = `-- name: AnalyticsRevenueByPlan :many SELECT sp.name AS plan_name, sp.currency, COUNT(p.id)::bigint AS total_payments, COALESCE(SUM(p.amount), 0)::float8 AS total_revenue FROM payments p JOIN subscription_plans sp ON sp.id = p.plan_id WHERE p.status = 'SUCCESS' AND ($1::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) >= $1::timestamptz) AND ($2::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) < $2::timestamptz) GROUP BY sp.name, sp.currency ORDER BY total_revenue DESC ` type AnalyticsRevenueByPlanParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsRevenueByPlanRow struct { PlanName string `json:"plan_name"` Currency string `json:"currency"` TotalPayments int64 `json:"total_payments"` TotalRevenue float64 `json:"total_revenue"` } func (q *Queries) AnalyticsRevenueByPlan(ctx context.Context, arg AnalyticsRevenueByPlanParams) ([]AnalyticsRevenueByPlanRow, error) { rows, err := q.db.Query(ctx, AnalyticsRevenueByPlan, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsRevenueByPlanRow for rows.Next() { var i AnalyticsRevenueByPlanRow if err := rows.Scan( &i.PlanName, &i.Currency, &i.TotalPayments, &i.TotalRevenue, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsRevenueLast30Days = `-- name: AnalyticsRevenueLast30Days :many SELECT d.date, COALESCE(SUM(p.amount), 0)::float8 AS total_revenue FROM generate_series( $1::date, $2::date, INTERVAL '1 day' ) AS d(date) LEFT JOIN payments p ON COALESCE(p.paid_at, p.created_at)::date = d.date AND p.status = 'SUCCESS' AND ($3::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) >= $3::timestamptz) AND ($4::timestamptz IS NULL OR COALESCE(p.paid_at, p.created_at) < $4::timestamptz) GROUP BY d.date ORDER BY d.date ` type AnalyticsRevenueLast30DaysParams struct { SeriesStart pgtype.Date `json:"series_start"` SeriesEnd pgtype.Date `json:"series_end"` RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsRevenueLast30DaysRow struct { Date interface{} `json:"date"` TotalRevenue float64 `json:"total_revenue"` } func (q *Queries) AnalyticsRevenueLast30Days(ctx context.Context, arg AnalyticsRevenueLast30DaysParams) ([]AnalyticsRevenueLast30DaysRow, error) { rows, err := q.db.Query(ctx, AnalyticsRevenueLast30Days, arg.SeriesStart, arg.SeriesEnd, arg.RangeStart, arg.RangeEnd, ) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsRevenueLast30DaysRow for rows.Next() { var i AnalyticsRevenueLast30DaysRow if err := rows.Scan(&i.Date, &i.TotalRevenue); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsSubscriptionsByStatus = `-- name: AnalyticsSubscriptionsByStatus :many SELECT COALESCE(us.status, 'unknown') AS status, COUNT(*)::bigint AS count FROM user_subscriptions us WHERE ($1::timestamptz IS NULL OR us.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR us.created_at < $2::timestamptz) GROUP BY us.status ORDER BY count DESC ` type AnalyticsSubscriptionsByStatusParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsSubscriptionsByStatusRow struct { Status string `json:"status"` Count int64 `json:"count"` } func (q *Queries) AnalyticsSubscriptionsByStatus(ctx context.Context, arg AnalyticsSubscriptionsByStatusParams) ([]AnalyticsSubscriptionsByStatusRow, error) { rows, err := q.db.Query(ctx, AnalyticsSubscriptionsByStatus, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsSubscriptionsByStatusRow for rows.Next() { var i AnalyticsSubscriptionsByStatusRow if err := rows.Scan(&i.Status, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsSubscriptionsSummary = `-- name: AnalyticsSubscriptionsSummary :one SELECT COUNT(*)::bigint AS total, COUNT(*) FILTER (WHERE us.status = 'ACTIVE')::bigint AS active, COUNT(*) FILTER (WHERE us.created_at::date = $1::date)::bigint AS new_today, COUNT(*) FILTER ( WHERE us.created_at::date >= $1::date - INTERVAL '6 days' AND us.created_at::date <= $1::date )::bigint AS new_this_week, COUNT(*) FILTER ( WHERE us.created_at::date >= $1::date - INTERVAL '29 days' AND us.created_at::date <= $1::date )::bigint AS new_this_month FROM user_subscriptions us WHERE ($2::timestamptz IS NULL OR us.created_at >= $2::timestamptz) AND ($3::timestamptz IS NULL OR us.created_at < $3::timestamptz) ` type AnalyticsSubscriptionsSummaryParams struct { RefDate pgtype.Date `json:"ref_date"` RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsSubscriptionsSummaryRow struct { Total int64 `json:"total"` Active int64 `json:"active"` NewToday int64 `json:"new_today"` NewThisWeek int64 `json:"new_this_week"` NewThisMonth int64 `json:"new_this_month"` } // ===================== // Subscription Analytics // ===================== func (q *Queries) AnalyticsSubscriptionsSummary(ctx context.Context, arg AnalyticsSubscriptionsSummaryParams) (AnalyticsSubscriptionsSummaryRow, error) { row := q.db.QueryRow(ctx, AnalyticsSubscriptionsSummary, arg.RefDate, arg.RangeStart, arg.RangeEnd) var i AnalyticsSubscriptionsSummaryRow err := row.Scan( &i.Total, &i.Active, &i.NewToday, &i.NewThisWeek, &i.NewThisMonth, ) return i, err } const AnalyticsTeamByRole = `-- name: AnalyticsTeamByRole :many SELECT COALESCE(tm.team_role, 'unknown') AS team_role, COUNT(*)::bigint AS count FROM team_members tm WHERE ($1::timestamptz IS NULL OR tm.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR tm.created_at < $2::timestamptz) GROUP BY tm.team_role ORDER BY count DESC ` type AnalyticsTeamByRoleParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsTeamByRoleRow struct { TeamRole string `json:"team_role"` Count int64 `json:"count"` } func (q *Queries) AnalyticsTeamByRole(ctx context.Context, arg AnalyticsTeamByRoleParams) ([]AnalyticsTeamByRoleRow, error) { rows, err := q.db.Query(ctx, AnalyticsTeamByRole, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsTeamByRoleRow for rows.Next() { var i AnalyticsTeamByRoleRow if err := rows.Scan(&i.TeamRole, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsTeamByStatus = `-- name: AnalyticsTeamByStatus :many SELECT COALESCE(tm.status, 'unknown') AS status, COUNT(*)::bigint AS count FROM team_members tm WHERE ($1::timestamptz IS NULL OR tm.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR tm.created_at < $2::timestamptz) GROUP BY tm.status ORDER BY count DESC ` type AnalyticsTeamByStatusParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsTeamByStatusRow struct { Status string `json:"status"` Count int64 `json:"count"` } func (q *Queries) AnalyticsTeamByStatus(ctx context.Context, arg AnalyticsTeamByStatusParams) ([]AnalyticsTeamByStatusRow, error) { rows, err := q.db.Query(ctx, AnalyticsTeamByStatus, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsTeamByStatusRow for rows.Next() { var i AnalyticsTeamByStatusRow if err := rows.Scan(&i.Status, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsTeamSummary = `-- name: AnalyticsTeamSummary :one SELECT COUNT(*)::bigint AS total_members FROM team_members tm WHERE ($1::timestamptz IS NULL OR tm.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR tm.created_at < $2::timestamptz) ` type AnalyticsTeamSummaryParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } // ===================== // Team Analytics // ===================== func (q *Queries) AnalyticsTeamSummary(ctx context.Context, arg AnalyticsTeamSummaryParams) (int64, error) { row := q.db.QueryRow(ctx, AnalyticsTeamSummary, arg.RangeStart, arg.RangeEnd) var total_members int64 err := row.Scan(&total_members) return total_members, err } const AnalyticsUserRegistrationsLast30Days = `-- name: AnalyticsUserRegistrationsLast30Days :many SELECT d.date, COUNT(u.id)::bigint AS count FROM generate_series( $1::date, $2::date, INTERVAL '1 day' ) AS d(date) LEFT JOIN users u ON u.created_at::date = d.date AND ($3::timestamptz IS NULL OR u.created_at >= $3::timestamptz) AND ($4::timestamptz IS NULL OR u.created_at < $4::timestamptz) GROUP BY d.date ORDER BY d.date ` type AnalyticsUserRegistrationsLast30DaysParams struct { SeriesStart pgtype.Date `json:"series_start"` SeriesEnd pgtype.Date `json:"series_end"` RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsUserRegistrationsLast30DaysRow struct { Date interface{} `json:"date"` Count int64 `json:"count"` } func (q *Queries) AnalyticsUserRegistrationsLast30Days(ctx context.Context, arg AnalyticsUserRegistrationsLast30DaysParams) ([]AnalyticsUserRegistrationsLast30DaysRow, error) { rows, err := q.db.Query(ctx, AnalyticsUserRegistrationsLast30Days, arg.SeriesStart, arg.SeriesEnd, arg.RangeStart, arg.RangeEnd, ) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsUserRegistrationsLast30DaysRow for rows.Next() { var i AnalyticsUserRegistrationsLast30DaysRow if err := rows.Scan(&i.Date, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsUsersByAgeGroup = `-- name: AnalyticsUsersByAgeGroup :many SELECT COALESCE(u.age_group, 'unknown') AS age_group, COUNT(*)::bigint AS count FROM users u WHERE ($1::timestamptz IS NULL OR u.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR u.created_at < $2::timestamptz) GROUP BY u.age_group ORDER BY count DESC ` type AnalyticsUsersByAgeGroupParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsUsersByAgeGroupRow struct { AgeGroup string `json:"age_group"` Count int64 `json:"count"` } func (q *Queries) AnalyticsUsersByAgeGroup(ctx context.Context, arg AnalyticsUsersByAgeGroupParams) ([]AnalyticsUsersByAgeGroupRow, error) { rows, err := q.db.Query(ctx, AnalyticsUsersByAgeGroup, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsUsersByAgeGroupRow for rows.Next() { var i AnalyticsUsersByAgeGroupRow if err := rows.Scan(&i.AgeGroup, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsUsersByKnowledgeLevel = `-- name: AnalyticsUsersByKnowledgeLevel :many SELECT COALESCE(u.knowledge_level, 'unknown') AS knowledge_level, COUNT(*)::bigint AS count FROM users u WHERE ($1::timestamptz IS NULL OR u.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR u.created_at < $2::timestamptz) GROUP BY u.knowledge_level ORDER BY count DESC ` type AnalyticsUsersByKnowledgeLevelParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsUsersByKnowledgeLevelRow struct { KnowledgeLevel string `json:"knowledge_level"` Count int64 `json:"count"` } func (q *Queries) AnalyticsUsersByKnowledgeLevel(ctx context.Context, arg AnalyticsUsersByKnowledgeLevelParams) ([]AnalyticsUsersByKnowledgeLevelRow, error) { rows, err := q.db.Query(ctx, AnalyticsUsersByKnowledgeLevel, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsUsersByKnowledgeLevelRow for rows.Next() { var i AnalyticsUsersByKnowledgeLevelRow if err := rows.Scan(&i.KnowledgeLevel, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsUsersByRegion = `-- name: AnalyticsUsersByRegion :many SELECT COALESCE(u.region, 'unknown') AS region, COUNT(*)::bigint AS count FROM users u WHERE ($1::timestamptz IS NULL OR u.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR u.created_at < $2::timestamptz) GROUP BY u.region ORDER BY count DESC ` type AnalyticsUsersByRegionParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsUsersByRegionRow struct { Region string `json:"region"` Count int64 `json:"count"` } func (q *Queries) AnalyticsUsersByRegion(ctx context.Context, arg AnalyticsUsersByRegionParams) ([]AnalyticsUsersByRegionRow, error) { rows, err := q.db.Query(ctx, AnalyticsUsersByRegion, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsUsersByRegionRow for rows.Next() { var i AnalyticsUsersByRegionRow if err := rows.Scan(&i.Region, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsUsersByRole = `-- name: AnalyticsUsersByRole :many SELECT COALESCE(u.role, 'unknown') AS role, COUNT(*)::bigint AS count FROM users u WHERE ($1::timestamptz IS NULL OR u.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR u.created_at < $2::timestamptz) GROUP BY u.role ORDER BY count DESC ` type AnalyticsUsersByRoleParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsUsersByRoleRow struct { Role string `json:"role"` Count int64 `json:"count"` } func (q *Queries) AnalyticsUsersByRole(ctx context.Context, arg AnalyticsUsersByRoleParams) ([]AnalyticsUsersByRoleRow, error) { rows, err := q.db.Query(ctx, AnalyticsUsersByRole, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsUsersByRoleRow for rows.Next() { var i AnalyticsUsersByRoleRow if err := rows.Scan(&i.Role, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsUsersByStatus = `-- name: AnalyticsUsersByStatus :many SELECT COALESCE(u.status, 'unknown') AS status, COUNT(*)::bigint AS count FROM users u WHERE ($1::timestamptz IS NULL OR u.created_at >= $1::timestamptz) AND ($2::timestamptz IS NULL OR u.created_at < $2::timestamptz) GROUP BY u.status ORDER BY count DESC ` type AnalyticsUsersByStatusParams struct { RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsUsersByStatusRow struct { Status string `json:"status"` Count int64 `json:"count"` } func (q *Queries) AnalyticsUsersByStatus(ctx context.Context, arg AnalyticsUsersByStatusParams) ([]AnalyticsUsersByStatusRow, error) { rows, err := q.db.Query(ctx, AnalyticsUsersByStatus, arg.RangeStart, arg.RangeEnd) if err != nil { return nil, err } defer rows.Close() var items []AnalyticsUsersByStatusRow for rows.Next() { var i AnalyticsUsersByStatusRow if err := rows.Scan(&i.Status, &i.Count); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const AnalyticsUsersSummary = `-- name: AnalyticsUsersSummary :one SELECT COUNT(*)::bigint AS total, COUNT(*) FILTER (WHERE u.created_at::date = $1::date)::bigint AS new_today, COUNT(*) FILTER ( WHERE u.created_at::date >= $1::date - INTERVAL '6 days' AND u.created_at::date <= $1::date )::bigint AS new_this_week, COUNT(*) FILTER ( WHERE u.created_at::date >= $1::date - INTERVAL '29 days' AND u.created_at::date <= $1::date )::bigint AS new_this_month FROM users u WHERE ($2::timestamptz IS NULL OR u.created_at >= $2::timestamptz) AND ($3::timestamptz IS NULL OR u.created_at < $3::timestamptz) ` type AnalyticsUsersSummaryParams struct { RefDate pgtype.Date `json:"ref_date"` RangeStart pgtype.Timestamptz `json:"range_start"` RangeEnd pgtype.Timestamptz `json:"range_end"` } type AnalyticsUsersSummaryRow struct { Total int64 `json:"total"` NewToday int64 `json:"new_today"` NewThisWeek int64 `json:"new_this_week"` NewThisMonth int64 `json:"new_this_month"` } // ===================== // Analytics (date-filtered) // ===================== // Shared optional params (nullable = all-time): // // range_start, range_end (exclusive upper bound) // // Required chart params: // // series_start, series_end (inclusive dates) // // Relative window anchor: // // ref_date (inclusive date used for new_today/week/month) // // ===================== // User Analytics // ===================== func (q *Queries) AnalyticsUsersSummary(ctx context.Context, arg AnalyticsUsersSummaryParams) (AnalyticsUsersSummaryRow, error) { row := q.db.QueryRow(ctx, AnalyticsUsersSummary, arg.RefDate, arg.RangeStart, arg.RangeEnd) var i AnalyticsUsersSummaryRow err := row.Scan( &i.Total, &i.NewToday, &i.NewThisWeek, &i.NewThisMonth, ) return i, err }