Yimaru-BackEnd/internal/domain/analytics.go
Yared Yemane 56089fa8fd Add users by country to analytics dashboard.
Expose by_country breakdown on GET /api/v1/analytics/dashboard from users.country.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 01:47:41 -07:00

169 lines
6.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package domain
import "time"
type AnalyticsLabelCount struct {
Label string `json:"label"`
Count int64 `json:"count"`
}
type AnalyticsLabelAmount struct {
Label string `json:"label"`
Count int64 `json:"count"`
Amount float64 `json:"amount"`
}
type AnalyticsRevenueByPlan struct {
PlanName string `json:"plan_name"`
Currency string `json:"currency"`
Revenue float64 `json:"revenue"`
}
type AnalyticsTimePoint struct {
Date time.Time `json:"date"`
Count int64 `json:"count"`
}
type AnalyticsRevenueTimePoint struct {
Date time.Time `json:"date"`
Revenue float64 `json:"revenue"`
}
// AnalyticsMonthlyRevenuePoint is one calendar month bucket (UTC month start) within a dashboard year query.
type AnalyticsMonthlyRevenuePoint struct {
Month int `json:"month"` // 112
MonthStart time.Time `json:"month_start"` // UTC date of month start (for sorting / tooltips)
Label string `json:"label"` // Short English month label, e.g. Jan
Currency string `json:"currency"`
Revenue float64 `json:"revenue"` // SUCCESS payments aggregate for that bucket
}
type AnalyticsUsersSection struct {
TotalUsers int64 `json:"total_users"`
NewToday int64 `json:"new_today"`
NewWeek int64 `json:"new_week"`
NewMonth int64 `json:"new_month"`
ByRole []AnalyticsLabelCount `json:"by_role"`
ByStatus []AnalyticsLabelCount `json:"by_status"`
ByAgeGroup []AnalyticsLabelCount `json:"by_age_group"`
ByEducationLevel []AnalyticsLabelCount `json:"by_education_level"`
ByOccupation []AnalyticsLabelCount `json:"by_occupation"`
ByLearningGoal []AnalyticsLabelCount `json:"by_learning_goal"`
ByLanguageChallange []AnalyticsLabelCount `json:"by_language_challange"`
ByKnowledgeLevel []AnalyticsLabelCount `json:"by_knowledge_level"`
ByCountry []AnalyticsLabelCount `json:"by_country"`
ByRegion []AnalyticsLabelCount `json:"by_region"`
RegistrationsLast30Days []AnalyticsTimePoint `json:"registrations_last_30_days"`
}
type AnalyticsSubscriptionsSection struct {
TotalSubscriptions int64 `json:"total_subscriptions"`
ActiveSubscriptions int64 `json:"active_subscriptions"`
NewToday int64 `json:"new_today"`
NewWeek int64 `json:"new_week"`
NewMonth int64 `json:"new_month"`
ByStatus []AnalyticsLabelCount `json:"by_status"`
RevenueByPlan []AnalyticsRevenueByPlan `json:"revenue_by_plan"`
NewSubscriptionsLast30Days []AnalyticsTimePoint `json:"new_subscriptions_last_30_days"`
}
type AnalyticsPaymentsSection struct {
TotalRevenue float64 `json:"total_revenue"`
AvgTransactionValue float64 `json:"avg_transaction_value"`
TotalPayments int64 `json:"total_payments"`
SuccessfulPayments int64 `json:"successful_payments"`
ByStatus []AnalyticsLabelAmount `json:"by_status"`
ByMethod []AnalyticsLabelAmount `json:"by_method"`
RevenueLast30Days []AnalyticsRevenueTimePoint `json:"revenue_last_30_days"`
// RevenueMonthly is populated only when the request includes year=..., with 12 months (possibly multiple currencies per month).
RevenueMonthly []AnalyticsMonthlyRevenuePoint `json:"revenue_monthly,omitempty"`
// MonthlyRevenueYear is set when RevenueMonthly is non-empty (the calendar year of those buckets).
MonthlyRevenueYear *int `json:"monthly_revenue_year,omitempty"`
}
// AnalyticsLMSContentCounts reflects the LMS hierarchy (Learn English): programs → courses → modules → lessons.
type AnalyticsLMSContentCounts struct {
Programs int64 `json:"programs"`
Courses int64 `json:"courses"`
Modules int64 `json:"modules"`
Lessons int64 `json:"lessons"`
LessonsWithVideo int64 `json:"lessons_with_video"`
Practices int64 `json:"practices"`
PracticesAtCourse int64 `json:"practices_at_course"`
PracticesAtModule int64 `json:"practices_at_module"`
PracticesAtLesson int64 `json:"practices_at_lesson"`
}
// AnalyticsExamPrepContentCounts reflects the exam_prep schema: catalog_courses → units → unit_modules → lessons → lesson_practices.
type AnalyticsExamPrepContentCounts struct {
CatalogCourses int64 `json:"catalog_courses"`
Units int64 `json:"units"`
UnitModules int64 `json:"unit_modules"`
Lessons int64 `json:"lessons"`
LessonsWithVideo int64 `json:"lessons_with_video"`
LessonPractices int64 `json:"lesson_practices"`
}
type AnalyticsCoursesSection struct {
// Top-level keys preserved for existing clients: map to LMS programs, courses, modules, and all video lessons (LMS + exam prep).
TotalCategories int64 `json:"total_categories"`
TotalCourses int64 `json:"total_courses"`
TotalSubCourses int64 `json:"total_sub_courses"`
TotalVideos int64 `json:"total_videos"`
LMS AnalyticsLMSContentCounts `json:"lms"`
ExamPrep AnalyticsExamPrepContentCounts `json:"exam_prep"`
}
type AnalyticsContentSection struct {
TotalQuestions int64 `json:"total_questions"`
TotalQuestionSets int64 `json:"total_question_sets"`
QuestionsByType []AnalyticsLabelCount `json:"questions_by_type"`
QuestionSetsByType []AnalyticsLabelCount `json:"question_sets_by_type"`
}
type AnalyticsNotificationsSection struct {
TotalSent int64 `json:"total_sent"`
ReadCount int64 `json:"read_count"`
UnreadCount int64 `json:"unread_count"`
ByChannel []AnalyticsLabelCount `json:"by_channel"`
ByType []AnalyticsLabelCount `json:"by_type"`
}
type AnalyticsIssuesSection struct {
TotalIssues int64 `json:"total_issues"`
ResolvedIssues int64 `json:"resolved_issues"`
ResolutionRate float64 `json:"resolution_rate"`
ByStatus []AnalyticsLabelCount `json:"by_status"`
ByType []AnalyticsLabelCount `json:"by_type"`
}
type AnalyticsTeamSection struct {
TotalMembers int64 `json:"total_members"`
ByRole []AnalyticsLabelCount `json:"by_role"`
ByStatus []AnalyticsLabelCount `json:"by_status"`
}
type AnalyticsDashboard struct {
GeneratedAt time.Time `json:"generated_at"`
DateFilter AnalyticsDateFilter `json:"date_filter"`
Users AnalyticsUsersSection `json:"users"`
Subscriptions AnalyticsSubscriptionsSection `json:"subscriptions"`
Payments AnalyticsPaymentsSection `json:"payments"`
Courses AnalyticsCoursesSection `json:"courses"`
Content AnalyticsContentSection `json:"content"`
Notifications AnalyticsNotificationsSection `json:"notifications"`
Issues AnalyticsIssuesSection `json:"issues"`
Team AnalyticsTeamSection `json:"team"`
}