Yimaru-BackEnd/internal/web_server/handlers/analytics_params.go
Yared Yemane 024a69b74b Add date-range filtering to analytics dashboard API.
Support all-time, year, year+month, and custom from/to query params with filtered metrics and time-series charts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 02:15:15 -07:00

114 lines
5.0 KiB
Go

package handlers
import (
dbgen "Yimaru-Backend/gen/db"
"Yimaru-Backend/internal/domain"
"time"
"github.com/jackc/pgx/v5/pgtype"
)
type analyticsQueryParams struct {
UsersSummary dbgen.AnalyticsUsersSummaryParams
UsersByRole dbgen.AnalyticsUsersByRoleParams
UsersByStatus dbgen.AnalyticsUsersByStatusParams
UsersByAgeGroup dbgen.AnalyticsUsersByAgeGroupParams
UsersByKnowledgeLevel dbgen.AnalyticsUsersByKnowledgeLevelParams
UsersByRegion dbgen.AnalyticsUsersByRegionParams
UserRegistrationsSeries dbgen.AnalyticsUserRegistrationsLast30DaysParams
SubscriptionsSummary dbgen.AnalyticsSubscriptionsSummaryParams
SubscriptionsByStatus dbgen.AnalyticsSubscriptionsByStatusParams
RevenueByPlan dbgen.AnalyticsRevenueByPlanParams
NewSubscriptionsSeries dbgen.AnalyticsNewSubscriptionsLast30DaysParams
PaymentsSummary dbgen.AnalyticsPaymentsSummaryParams
PaymentsByStatus dbgen.AnalyticsPaymentsByStatusParams
PaymentsByMethod dbgen.AnalyticsPaymentsByMethodParams
RevenueSeries dbgen.AnalyticsRevenueLast30DaysParams
QuestionsCounts dbgen.AnalyticsQuestionsCountsParams
QuestionsByType dbgen.AnalyticsQuestionsByTypeParams
QuestionSetsByType dbgen.AnalyticsQuestionSetsByTypeParams
NotificationsSummary dbgen.AnalyticsNotificationsSummaryParams
NotificationsChannel dbgen.AnalyticsNotificationsByChannelParams
NotificationsType dbgen.AnalyticsNotificationsByTypeParams
IssuesSummary dbgen.AnalyticsIssuesSummaryParams
IssuesByStatus dbgen.AnalyticsIssuesByStatusParams
IssuesByType dbgen.AnalyticsIssuesByTypeParams
TeamSummary dbgen.AnalyticsTeamSummaryParams
TeamByRole dbgen.AnalyticsTeamByRoleParams
TeamByStatus dbgen.AnalyticsTeamByStatusParams
}
func newAnalyticsQueryParams(f domain.AnalyticsDateFilter) analyticsQueryParams {
ref := pgAnalyticsDate(f.RefDate)
rs, re := pgAnalyticsTimestamptzPtr(f.RangeStart), pgAnalyticsTimestamptzPtr(f.RangeEnd)
series := dbgen.AnalyticsUserRegistrationsLast30DaysParams{
SeriesStart: pgAnalyticsDate(f.SeriesStart),
SeriesEnd: pgAnalyticsDate(f.SeriesEnd),
RangeStart: rs,
RangeEnd: re,
}
return analyticsQueryParams{
UsersSummary: dbgen.AnalyticsUsersSummaryParams{RefDate: ref, RangeStart: rs, RangeEnd: re},
UsersByRole: dbgen.AnalyticsUsersByRoleParams{RangeStart: rs, RangeEnd: re},
UsersByStatus: dbgen.AnalyticsUsersByStatusParams{RangeStart: rs, RangeEnd: re},
UsersByAgeGroup: dbgen.AnalyticsUsersByAgeGroupParams{RangeStart: rs, RangeEnd: re},
UsersByKnowledgeLevel: dbgen.AnalyticsUsersByKnowledgeLevelParams{RangeStart: rs, RangeEnd: re},
UsersByRegion: dbgen.AnalyticsUsersByRegionParams{RangeStart: rs, RangeEnd: re},
UserRegistrationsSeries: series,
SubscriptionsSummary: dbgen.AnalyticsSubscriptionsSummaryParams{RefDate: ref, RangeStart: rs, RangeEnd: re},
SubscriptionsByStatus: dbgen.AnalyticsSubscriptionsByStatusParams{RangeStart: rs, RangeEnd: re},
RevenueByPlan: dbgen.AnalyticsRevenueByPlanParams{RangeStart: rs, RangeEnd: re},
NewSubscriptionsSeries: dbgen.AnalyticsNewSubscriptionsLast30DaysParams{
SeriesStart: series.SeriesStart,
SeriesEnd: series.SeriesEnd,
RangeStart: rs,
RangeEnd: re,
},
PaymentsSummary: dbgen.AnalyticsPaymentsSummaryParams{RangeStart: rs, RangeEnd: re},
PaymentsByStatus: dbgen.AnalyticsPaymentsByStatusParams{RangeStart: rs, RangeEnd: re},
PaymentsByMethod: dbgen.AnalyticsPaymentsByMethodParams{RangeStart: rs, RangeEnd: re},
RevenueSeries: dbgen.AnalyticsRevenueLast30DaysParams{
SeriesStart: series.SeriesStart,
SeriesEnd: series.SeriesEnd,
RangeStart: rs,
RangeEnd: re,
},
QuestionsCounts: dbgen.AnalyticsQuestionsCountsParams{RangeStart: rs, RangeEnd: re},
QuestionsByType: dbgen.AnalyticsQuestionsByTypeParams{RangeStart: rs, RangeEnd: re},
QuestionSetsByType: dbgen.AnalyticsQuestionSetsByTypeParams{RangeStart: rs, RangeEnd: re},
NotificationsSummary: dbgen.AnalyticsNotificationsSummaryParams{RangeStart: rs, RangeEnd: re},
NotificationsChannel: dbgen.AnalyticsNotificationsByChannelParams{RangeStart: rs, RangeEnd: re},
NotificationsType: dbgen.AnalyticsNotificationsByTypeParams{RangeStart: rs, RangeEnd: re},
IssuesSummary: dbgen.AnalyticsIssuesSummaryParams{RangeStart: rs, RangeEnd: re},
IssuesByStatus: dbgen.AnalyticsIssuesByStatusParams{RangeStart: rs, RangeEnd: re},
IssuesByType: dbgen.AnalyticsIssuesByTypeParams{RangeStart: rs, RangeEnd: re},
TeamSummary: dbgen.AnalyticsTeamSummaryParams{RangeStart: rs, RangeEnd: re},
TeamByRole: dbgen.AnalyticsTeamByRoleParams{RangeStart: rs, RangeEnd: re},
TeamByStatus: dbgen.AnalyticsTeamByStatusParams{RangeStart: rs, RangeEnd: re},
}
}
func pgAnalyticsDate(t time.Time) pgtype.Date {
return pgtype.Date{Time: t.UTC(), Valid: true}
}
func pgAnalyticsTimestamptzPtr(t *time.Time) pgtype.Timestamptz {
if t == nil {
return pgtype.Timestamptz{Valid: false}
}
return pgtype.Timestamptz{Time: t.UTC(), Valid: true}
}