Skip to content

Commit

Permalink
refactor: remove unused components, interfaces, models and apis
Browse files Browse the repository at this point in the history
  • Loading branch information
calisio authored Jan 24, 2025
1 parent 508dbda commit e276654
Show file tree
Hide file tree
Showing 32 changed files with 39 additions and 1,467 deletions.
109 changes: 6 additions & 103 deletions backend/src/database/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,33 @@ import (
"math"
"sort"
"time"

log "github.com/sirupsen/logrus"
)

type DailyActivity struct {
Date time.Time `json:"date"`
TotalTime int64 `json:"total_time"`
Quartile int64 `json:"quartile"`
Activities []models.Activity `json:"activities"`
}

func (db *DB) GetDailyActivityByUserID(userID int, startDate time.Time, endDate time.Time) ([]DailyActivity, error) {
func (db *DB) GetDailyActivityByUserID(userID int, startDate time.Time, endDate time.Time) ([]models.DailyActivity, error) {
days := int(math.Ceil(endDate.Sub(startDate).Hours() / 24))
activities := make([]models.Activity, 0, days)
if err := db.Where("user_id = ? AND created_at BETWEEN ? AND ?", userID, startDate, endDate).Find(&activities).Error; err != nil {
return nil, newGetRecordsDBError(err, "activities")
}
// Combine activities based on date
dailyActivities := make(map[time.Time]DailyActivity, days)
dailyActivities := make(map[time.Time]models.DailyActivity, days)
for _, activity := range activities {
date := activity.CreatedAt.Truncate(24 * time.Hour)
if dailyActivity, ok := dailyActivities[date]; ok {
dailyActivity.TotalTime += activity.TimeDelta
dailyActivity.TotalTime += uint(activity.TimeDelta)
dailyActivity.Activities = append(dailyActivity.Activities, activity)
dailyActivities[date] = dailyActivity
} else {
dailyActivities[date] = DailyActivity{
dailyActivities[date] = models.DailyActivity{
Date: date,
TotalTime: activity.TimeDelta,
TotalTime: uint(activity.TimeDelta),
Activities: []models.Activity{activity},
}
}
}

// Convert map to slice
var dailyActivityList []DailyActivity
var dailyActivityList []models.DailyActivity
for _, dailyActivity := range dailyActivities {
dailyActivityList = append(dailyActivityList, dailyActivity)
}
Expand Down Expand Up @@ -90,94 +81,6 @@ func (db *DB) DeleteActivity(activityID int) error {
return db.Delete(&models.Activity{}, activityID).Error
}

func (db *DB) GetAdminDashboardInfo(facilityID uint) (models.AdminDashboardJoin, error) {
var dashboard models.AdminDashboardJoin

// facility name
err := db.Table("facilities f").
Select("f.name as facility_name").
Where("f.id = ?", facilityID).
Find(&dashboard.FacilityName).Error
if err != nil {
return dashboard, NewDBError(err, "error getting admin dashboard info")
}

// Monthly Activity
if db.Dialector.Name() == "sqlite" {
err = db.Table("activities a").
Select("STRFTIME('%Y-%m-%d', a.created_at) as date, ROUND(SUM(a.time_delta) / 3600.0,2) as delta").
Joins("JOIN users u ON a.user_id = u.id").
Where("u.facility_id = ? AND a.created_at >= ?", facilityID, time.Now().AddDate(0, -1, 0)).
Group("STRFTIME('%Y-%m-%d', 'YYYY-MM-DD')").
Order("date ").
Find(&dashboard.MonthlyActivity).Error

} else {
err = db.Table("activities a").
Select("TO_CHAR(a.created_at, 'YYYY-MM-DD') as date, ROUND(SUM(a.time_delta) / 3600.0,2) as delta").
Joins("JOIN users u ON a.user_id = u.id").
Where("u.facility_id = ? AND a.created_at >= ?", facilityID, time.Now().AddDate(0, -1, 0)).
Group("TO_CHAR(a.created_at, 'YYYY-MM-DD')").
Order("date ").
Find(&dashboard.MonthlyActivity).Error
}
if err != nil {
return dashboard, NewDBError(err, "error getting admin dashboard info")
}

// Weekly Active Users, Average Daily Activity, Total Weekly Activity
var result struct {
WeeklyActiveUsers int64
AvgDailyActivity float64
TotalWeeklyActivity int64
}

err = db.Table("activities a").
Select(`
COUNT(DISTINCT a.user_id) as weekly_active_users,
AVG(a.time_delta) as avg_daily_activity,
SUM(a.time_delta) as total_weekly_activity`).
Joins("JOIN users u ON a.user_id = u.id").
Where("u.facility_id = ? AND a.created_at >= ?", facilityID, time.Now().AddDate(0, 0, -7)).
Find(&result).Error
if err != nil {
log.Errorf("Query failed: %v", err)
return dashboard, NewDBError(err, "error getting admin dashboard info")
}

dashboard.WeeklyActiveUsers = int64(math.Abs(float64(result.WeeklyActiveUsers)))
dashboard.AvgDailyActivity = int64(math.Abs(result.AvgDailyActivity))
dashboard.TotalWeeklyActivity = int64(math.Abs(float64(result.TotalWeeklyActivity)))

// Course Milestones
err = db.Table("courses c").
Select("c.name as name, COUNT(m.id) as milestones").
Joins("INNER JOIN milestones m ON m.course_id = c.id AND m.created_at >= ?", time.Now().AddDate(0, 0, -7)).
Joins("INNER JOIN users u ON m.user_id = u.id AND u.facility_id = ?", facilityID).
Group("c.name").
Order("milestones DESC").
Limit(5).
Find(&dashboard.CourseMilestones).Error
if err != nil {
return dashboard, NewDBError(err, "error getting admin dashboard info")
}

// Top 5 Courses by Hours Engaged
err = db.Table("activities a").
Select("c.name as course_name, c.alt_name as alt_name, SUM(a.time_delta) / 3600.0 as hours_engaged").
Joins("JOIN courses c ON a.course_id = c.id").
Joins("JOIN users u ON a.user_id = u.id").
Where("u.facility_id = ? AND a.created_at >= ?", facilityID, time.Now().AddDate(0, 0, -7)).
Group("c.id").
Order("hours_engaged DESC").
Limit(5).
Find(&dashboard.TopCourseActivity).Error
if err != nil {
return dashboard, NewDBError(err, "error getting admin dashboard info")
}

return dashboard, nil
}
func (db *DB) GetTotalCoursesOffered(facilityID *uint) (int, error) {
var totalCourses int
subQry := db.Table("courses c").
Expand Down
5 changes: 2 additions & 3 deletions backend/src/handlers/activity_handler_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package handlers

import (
"UnlockEdv2/src/database"
"UnlockEdv2/src/models"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -51,13 +50,13 @@ func TestHandleGetDailyActivityByUserID(t *testing.T) {
if err != nil {
t.Error("unable to marshal response daily activities, error is ", err)
}
responseActivities := []database.DailyActivity{}
responseActivities := []models.DailyActivity{}
err = json.Unmarshal(jsonStr, &responseActivities)
if err != nil {
t.Error("unable to unmarshal response daily activities, error is ", err)
}
for _, dailyActivity := range dailyActivities {
if !slices.ContainsFunc(responseActivities, func(dailyAct database.DailyActivity) bool {
if !slices.ContainsFunc(responseActivities, func(dailyAct models.DailyActivity) bool {
isGood := true
for _, activity := range dailyActivity.Activities {
if !slices.ContainsFunc(dailyAct.Activities, func(act models.Activity) bool {
Expand Down
11 changes: 0 additions & 11 deletions backend/src/handlers/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,12 @@ func (srv *Server) registerDashboardRoutes() []routeDef {
axx := models.Feature(models.ProviderAccess)
return []routeDef{
{"GET /api/login-metrics", srv.handleLoginMetrics, true, models.Feature()},
{"GET /api/users/{id}/admin-dashboard", srv.handleAdminDashboard, true, models.Feature()},
{"GET /api/users/{id}/admin-layer2", srv.handleAdminLayer2, true, models.Feature()},
{"GET /api/users/{id}/catalog", srv.handleUserCatalog, false, axx},
{"GET /api/users/{id}/courses", srv.handleUserCourses, false, axx},
}
}

func (srv *Server) handleAdminDashboard(w http.ResponseWriter, r *http.Request, log sLog) error {
claims := r.Context().Value(ClaimsKey).(*Claims)
adminDashboard, err := srv.Db.GetAdminDashboardInfo(claims.FacilityID)
if err != nil {
log.add("facilityId", claims.FacilityID)
return newDatabaseServiceError(err)
}
return writeJsonResponse(w, http.StatusOK, adminDashboard)
}

func (srv *Server) handleAdminLayer2(w http.ResponseWriter, r *http.Request, log sLog) error {
facility := r.URL.Query().Get("facility")
claims := r.Context().Value(ClaimsKey).(*Claims)
Expand Down
33 changes: 0 additions & 33 deletions backend/src/handlers/dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,6 @@ import (
"github.com/google/go-cmp/cmp"
)

func TestHandleAdminDashboard(t *testing.T) {
httpTests := []httpTest{
{"TestAdminDashboardAsAdmin", "admin", map[string]any{"id": "1"}, http.StatusOK, ""},
{"TestAdminDashboardAsUser", "student", map[string]any{"id": "4"}, http.StatusUnauthorized, ""},
}
for _, test := range httpTests {
t.Run(test.testName, func(t *testing.T) {
req, err := http.NewRequest(http.MethodGet, "/api/users/{id}/admin-dashboard", nil)
if err != nil {
t.Fatalf("unable to create new request, error is %v", err)
}
req.SetPathValue("id", test.mapKeyValues["id"].(string))
handler := getHandlerByRoleWithMiddleware(server.handleAdminDashboard, test.role)
rr := executeRequest(t, req, handler, test)
id, _ := strconv.Atoi(test.mapKeyValues["id"].(string))
if test.expectedStatusCode == http.StatusOK {
dashboard, err := server.Db.GetAdminDashboardInfo(uint(id))
if err != nil {
t.Fatalf("unable to get student dashboard, error is %v", err)
}
received := rr.Body.String()
resource := models.Resource[models.AdminDashboardJoin]{}
if err := json.Unmarshal([]byte(received), &resource); err != nil {
t.Errorf("failed to unmarshal resource, error is %v", err)
}
if diff := cmp.Diff(&dashboard, &resource.Data); diff != "" {
t.Errorf("handler returned unexpected response body: %v", diff)
}
}
})
}
}

func TestHandleAdminLayer2(t *testing.T) {
httpTests := []httpTest{
{"TestAdminDashboardAsAdmin", "admin", map[string]any{"id": "1"}, http.StatusOK, ""},
Expand Down
8 changes: 0 additions & 8 deletions backend/src/models/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,6 @@ func (UserCourseActivityTotals) TableName() string {
return "user_course_activity_totals"
}

type ImportActivity struct {
ExternalUserID string `json:"external_user_id"`
ExternalCourseID string `json:"external_course_id"`
Type string `json:"type"`
TotalTime int `json:"total_time"`
Date string `json:"date"`
}

type DailyActivity struct {
Date time.Time `json:"date"`
TotalTime uint `json:"total_time"`
Expand Down
34 changes: 0 additions & 34 deletions backend/src/models/course.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,6 @@ type RecentActivity struct {
Delta float64 `json:"delta"`
}

type ImportCourse struct {
ProviderPlatformID int `json:"provider_platform_id"`
Name string `json:"name"`
Description string `json:"description"`
ExternalID string `json:"external_id"`
ThumbnailURL string `json:"thumbnail_url"`
Type string `json:"type"`
OutcomeTypes []string `json:"outcome_types"`
ExternalURL string `json:"external_url"`
TotalProgressMilestones int `json:"total_progress_milestones"`
}

// ADMIN STRUCTS
type AdminDashboardJoin struct {
FacilityName string `json:"facility_name"`
MonthlyActivity []RecentActivity `json:"monthly_activity"`
WeeklyActiveUsers int64 `json:"weekly_active_users"`
AvgDailyActivity int64 `json:"avg_daily_activity"`
TotalWeeklyActivity int64 `json:"total_weekly_activity"`
CourseMilestones []CourseMilestones `json:"course_milestones"`
TopCourseActivity []CourseActivity `json:"top_course_activity"`
}

type LearningInsight struct {
CourseName string `json:"course_name"`
TotalStudentsEnrolled int64 `json:"total_students_enrolled"`
Expand All @@ -90,14 +67,3 @@ type AdminLayer2Join struct {
TotalHourlyActivity int64 `json:"total_hourly_activity"`
LearningInsights []LearningInsight `json:"learning_insights"`
}

type CourseMilestones struct {
Name string `json:"name"`
Milestones int `json:"milestones"`
}

type CourseActivity struct {
CourseName string `json:"course_name"`
AltName string `json:"alt_name"`
HoursEngaged float32 `json:"hours_engaged"`
}
8 changes: 0 additions & 8 deletions backend/src/models/milestones.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,6 @@ type Milestone struct {
Course *Course `gorm:"foreignKey:CourseID" json:"-"`
}

type ImportMilestone struct {
UserID int `json:"user_id"`
ExternalCourseID string `json:"external_course_id"`
ExternalID string `json:"external_id"`
Type string `json:"type"`
IsCompleted bool `json:"is_completed"`
}

func (Milestone) TableName() string {
return "milestones"
}
4 changes: 0 additions & 4 deletions backend/src/models/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,3 @@ func UpdateStruct(dst, src interface{}) {
func StringPtr(s string) *string {
return &s
}

func UIntPtr(u uint) *uint {
return &u
}
9 changes: 0 additions & 9 deletions backend/src/models/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,3 @@ func (user *User) GetTraits() map[string]interface{} {
func (user *User) IsAdmin() bool {
return slices.Contains(AdminRoles, user.Role)
}

func (user *User) GetExternalIDFromProvider(db *gorm.DB, providerId uint) (string, error) {
var mapping ProviderUserMapping
err := db.Model(ProviderUserMapping{}).Where("provider_platform_id = ?", providerId).Where("user_id = ?", user.ID).Find(&mapping).Error
if err != nil {
return "", err
}
return mapping.ExternalUserID, nil
}
Loading

0 comments on commit e276654

Please sign in to comment.