From c927d917ec312d54e5d5157f2b3f9fe02da3890c Mon Sep 17 00:00:00 2001 From: Tim Wundenberg Date: Fri, 26 Dec 2025 07:11:39 +0100 Subject: [PATCH] feat: extract dashboard --- .../dashboard.go => dashboard/handler.go} | 42 ++++++++-------- .../dashboard.go => dashboard/service.go} | 49 ++++++++++--------- .../template}/dashboard.templ | 2 +- internal/dashboard/template/default.go | 1 + .../dashboard.go => dashboard/types.go} | 2 +- internal/default.go | 5 +- internal/service/treasure_chest.go | 4 +- internal/template/dashboard/default.go | 2 - test/auth_it_test.go | 3 +- 9 files changed, 55 insertions(+), 55 deletions(-) rename internal/{handler/dashboard.go => dashboard/handler.go} (79%) rename internal/{service/dashboard.go => dashboard/service.go} (73%) rename internal/{template/dashboard => dashboard/template}/dashboard.templ (98%) create mode 100644 internal/dashboard/template/default.go rename internal/{types/dashboard.go => dashboard/types.go} (97%) delete mode 100644 internal/template/dashboard/default.go diff --git a/internal/handler/dashboard.go b/internal/dashboard/handler.go similarity index 79% rename from internal/handler/dashboard.go rename to internal/dashboard/handler.go index 1e14b7b..4c89fa5 100644 --- a/internal/handler/dashboard.go +++ b/internal/dashboard/handler.go @@ -1,12 +1,12 @@ -package handler +package dashboard import ( "fmt" "log/slog" "net/http" "spend-sparrow/internal/core" + "spend-sparrow/internal/dashboard/template" "spend-sparrow/internal/service" - "spend-sparrow/internal/template/dashboard" "spend-sparrow/internal/utils" "strings" "time" @@ -14,32 +14,32 @@ import ( "github.com/google/uuid" ) -type Dashboard interface { +type Handler interface { Handle(router *http.ServeMux) } -type DashboardImpl struct { +type HandlerImpl struct { r *core.Render - d *service.Dashboard + s *Service treasureChest service.TreasureChest } -func NewDashboard(r *core.Render, d *service.Dashboard, treasureChest service.TreasureChest) Dashboard { - return DashboardImpl{ +func NewHandler(r *core.Render, s *Service, treasureChest service.TreasureChest) Handler { + return HandlerImpl{ r: r, - d: d, + s: s, treasureChest: treasureChest, } } -func (handler DashboardImpl) Handle(router *http.ServeMux) { - router.Handle("GET /dashboard", handler.handleDashboard()) - router.Handle("GET /dashboard/main-chart", handler.handleDashboardMainChart()) - router.Handle("GET /dashboard/treasure-chests", handler.handleDashboardTreasureChests()) - router.Handle("GET /dashboard/treasure-chest", handler.handleDashboardTreasureChest()) +func (handler HandlerImpl) Handle(router *http.ServeMux) { + router.Handle("GET /dashboard", handler.handleHandler()) + router.Handle("GET /dashboard/main-chart", handler.handleHandlerMainChart()) + router.Handle("GET /dashboard/treasure-chests", handler.handleHandlerTreasureChests()) + router.Handle("GET /dashboard/treasure-chest", handler.handleHandlerTreasureChest()) } -func (handler DashboardImpl) handleDashboard() http.HandlerFunc { +func (handler HandlerImpl) handleHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { core.UpdateSpan(r) @@ -55,18 +55,18 @@ func (handler DashboardImpl) handleDashboard() http.HandlerFunc { return } - comp := dashboard.Dashboard(treasureChests) + comp := template.Dashboard(treasureChests) handler.r.RenderLayoutWithStatus(r, w, comp, user, http.StatusOK) } } -func (handler DashboardImpl) handleDashboardMainChart() http.HandlerFunc { +func (handler HandlerImpl) handleHandlerMainChart() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { core.UpdateSpan(r) user := core.GetUser(r) - series, err := handler.d.MainChart(r.Context(), user) + series, err := handler.s.MainChart(r.Context(), user) if err != nil { core.HandleError(w, r, err) return @@ -126,13 +126,13 @@ func (handler DashboardImpl) handleDashboardMainChart() http.HandlerFunc { } } -func (handler DashboardImpl) handleDashboardTreasureChests() http.HandlerFunc { +func (handler HandlerImpl) handleHandlerTreasureChests() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { core.UpdateSpan(r) user := core.GetUser(r) - treeList, err := handler.d.TreasureChests(r.Context(), user) + treeList, err := handler.s.TreasureChests(r.Context(), user) if err != nil { core.HandleError(w, r, err) return @@ -181,7 +181,7 @@ func (handler DashboardImpl) handleDashboardTreasureChests() http.HandlerFunc { } } -func (handler DashboardImpl) handleDashboardTreasureChest() http.HandlerFunc { +func (handler HandlerImpl) handleHandlerTreasureChest() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { core.UpdateSpan(r) @@ -200,7 +200,7 @@ func (handler DashboardImpl) handleDashboardTreasureChest() http.HandlerFunc { treasureChestId = &id } - series, err := handler.d.TreasureChest(r.Context(), user, treasureChestId) + series, err := handler.s.TreasureChest(r.Context(), user, treasureChestId) if err != nil { core.HandleError(w, r, err) return diff --git a/internal/service/dashboard.go b/internal/dashboard/service.go similarity index 73% rename from internal/service/dashboard.go rename to internal/dashboard/service.go index 3ffbf94..06c131b 100644 --- a/internal/service/dashboard.go +++ b/internal/dashboard/service.go @@ -1,9 +1,10 @@ -package service +package dashboard import ( "context" "spend-sparrow/internal/auth_types" "spend-sparrow/internal/core" + "spend-sparrow/internal/service" "spend-sparrow/internal/types" "time" @@ -11,20 +12,20 @@ import ( "github.com/jmoiron/sqlx" ) -type Dashboard struct { +type Service struct { db *sqlx.DB } -func NewDashboard(db *sqlx.DB) *Dashboard { - return &Dashboard{ +func NewService(db *sqlx.DB) *Service { + return &Service{ db: db, } } -func (s Dashboard) MainChart( +func (s Service) MainChart( ctx context.Context, user *auth_types.User, -) ([]types.DashboardMainChartEntry, error) { +) ([]DashboardMainChartEntry, error) { if user == nil { return nil, core.ErrUnauthorized } @@ -40,9 +41,9 @@ func (s Dashboard) MainChart( return nil, err } - timeEntries := make([]types.DashboardMainChartEntry, 0) + timeEntries := make([]DashboardMainChartEntry, 0) - var lastEntry *types.DashboardMainChartEntry + var lastEntry *DashboardMainChartEntry for _, t := range transactions { if t.Error != nil { @@ -51,14 +52,14 @@ func (s Dashboard) MainChart( newDay := t.Timestamp.Truncate(24 * time.Hour) if lastEntry == nil { - lastEntry = &types.DashboardMainChartEntry{ + lastEntry = &DashboardMainChartEntry{ Day: newDay, Value: 0, Savings: 0, } } else if lastEntry.Day != newDay { timeEntries = append(timeEntries, *lastEntry) - lastEntry = &types.DashboardMainChartEntry{ + lastEntry = &DashboardMainChartEntry{ Day: newDay, Value: lastEntry.Value, Savings: lastEntry.Savings, @@ -81,10 +82,10 @@ func (s Dashboard) MainChart( return timeEntries, nil } -func (s Dashboard) TreasureChests( +func (s Service) TreasureChests( ctx context.Context, user *auth_types.User, -) ([]*types.DashboardTreasureChest, error) { +) ([]*DashboardTreasureChest, error) { if user == nil { return nil, core.ErrUnauthorized } @@ -96,22 +97,22 @@ func (s Dashboard) TreasureChests( return nil, err } - treasureChests = sortTreasureChests(treasureChests) + treasureChests = service.SortTreasureChests(treasureChests) - result := make([]*types.DashboardTreasureChest, 0) + result := make([]*DashboardTreasureChest, 0) for _, t := range treasureChests { if t.ParentId == nil { - result = append(result, &types.DashboardTreasureChest{ + result = append(result, &DashboardTreasureChest{ Name: t.Name, Value: t.CurrentBalance, - Children: make([]types.DashboardTreasureChest, 0), + Children: make([]DashboardTreasureChest, 0), }) } else { - result[len(result)-1].Children = append(result[len(result)-1].Children, types.DashboardTreasureChest{ + result[len(result)-1].Children = append(result[len(result)-1].Children, DashboardTreasureChest{ Name: t.Name, Value: t.CurrentBalance, - Children: make([]types.DashboardTreasureChest, 0), + Children: make([]DashboardTreasureChest, 0), }) } } @@ -119,11 +120,11 @@ func (s Dashboard) TreasureChests( return result, nil } -func (s Dashboard) TreasureChest( +func (s Service) TreasureChest( ctx context.Context, user *auth_types.User, treausureChestId *uuid.UUID, -) ([]types.DashboardMainChartEntry, error) { +) ([]DashboardMainChartEntry, error) { if user == nil { return nil, core.ErrUnauthorized } @@ -140,9 +141,9 @@ func (s Dashboard) TreasureChest( return nil, err } - timeEntries := make([]types.DashboardMainChartEntry, 0) + timeEntries := make([]DashboardMainChartEntry, 0) - var lastEntry *types.DashboardMainChartEntry + var lastEntry *DashboardMainChartEntry for _, t := range transactions { if t.Error != nil { @@ -151,13 +152,13 @@ func (s Dashboard) TreasureChest( newDay := t.Timestamp.Truncate(24 * time.Hour) if lastEntry == nil { - lastEntry = &types.DashboardMainChartEntry{ + lastEntry = &DashboardMainChartEntry{ Day: newDay, Value: 0, } } else if lastEntry.Day != newDay { timeEntries = append(timeEntries, *lastEntry) - lastEntry = &types.DashboardMainChartEntry{ + lastEntry = &DashboardMainChartEntry{ Day: newDay, Value: lastEntry.Value, } diff --git a/internal/template/dashboard/dashboard.templ b/internal/dashboard/template/dashboard.templ similarity index 98% rename from internal/template/dashboard/dashboard.templ rename to internal/dashboard/template/dashboard.templ index 28821d5..9fe8241 100644 --- a/internal/template/dashboard/dashboard.templ +++ b/internal/dashboard/template/dashboard.templ @@ -1,4 +1,4 @@ -package dashboard +package template import "spend-sparrow/internal/types" diff --git a/internal/dashboard/template/default.go b/internal/dashboard/template/default.go new file mode 100644 index 0000000..38cdfe4 --- /dev/null +++ b/internal/dashboard/template/default.go @@ -0,0 +1 @@ +package template diff --git a/internal/types/dashboard.go b/internal/dashboard/types.go similarity index 97% rename from internal/types/dashboard.go rename to internal/dashboard/types.go index 2a6484b..b27ebf3 100644 --- a/internal/types/dashboard.go +++ b/internal/dashboard/types.go @@ -1,4 +1,4 @@ -package types +package dashboard import "time" diff --git a/internal/default.go b/internal/default.go index 29b5cf2..6dffd69 100644 --- a/internal/default.go +++ b/internal/default.go @@ -10,6 +10,7 @@ import ( "spend-sparrow/internal/account" "spend-sparrow/internal/authentication" "spend-sparrow/internal/core" + "spend-sparrow/internal/dashboard" "spend-sparrow/internal/handler" "spend-sparrow/internal/handler/middleware" "spend-sparrow/internal/log" @@ -118,11 +119,11 @@ func createHandlerWithServices(ctx context.Context, d *sqlx.DB, serverSettings * treasureChestService := service.NewTreasureChest(d, randomService, clockService) transactionService := service.NewTransaction(d, randomService, clockService) transactionRecurringService := service.NewTransactionRecurring(d, randomService, clockService, transactionService) - dashboardService := service.NewDashboard(d) + dashboardService := dashboard.NewService(d) render := core.NewRender() indexHandler := handler.NewIndex(render, clockService) - dashboardHandler := handler.NewDashboard(render, dashboardService, treasureChestService) + dashboardHandler := dashboard.NewHandler(render, dashboardService, treasureChestService) authHandler := authentication.NewHandler(authService, render) accountHandler := account.NewHandler(accountService, render) treasureChestHandler := handler.NewTreasureChest(treasureChestService, transactionRecurringService, render) diff --git a/internal/service/treasure_chest.go b/internal/service/treasure_chest.go index 53c838f..c9bcc00 100644 --- a/internal/service/treasure_chest.go +++ b/internal/service/treasure_chest.go @@ -206,7 +206,7 @@ func (s TreasureChestImpl) GetAll(ctx context.Context, user *auth_types.User) ([ return nil, err } - return sortTreasureChests(treasureChests), nil + return SortTreasureChests(treasureChests), nil } func (s TreasureChestImpl) Delete(ctx context.Context, user *auth_types.User, idStr string) error { @@ -278,7 +278,7 @@ func (s TreasureChestImpl) Delete(ctx context.Context, user *auth_types.User, id return nil } -func sortTreasureChests(nodes []*types.TreasureChest) []*types.TreasureChest { +func SortTreasureChests(nodes []*types.TreasureChest) []*types.TreasureChest { var ( roots []*types.TreasureChest ) diff --git a/internal/template/dashboard/default.go b/internal/template/dashboard/default.go deleted file mode 100644 index 7d2270a..0000000 --- a/internal/template/dashboard/default.go +++ /dev/null @@ -1,2 +0,0 @@ -package dashboard - diff --git a/test/auth_it_test.go b/test/auth_it_test.go index 59d71d4..352ac83 100644 --- a/test/auth_it_test.go +++ b/test/auth_it_test.go @@ -5,7 +5,6 @@ import ( "spend-sparrow/internal/auth_types" "spend-sparrow/internal/authentication" "spend-sparrow/internal/core" - "spend-sparrow/internal/db" "testing" "time" @@ -29,7 +28,7 @@ func setupDb(t *testing.T) *sqlx.DB { } }) - err = db.RunMigrations(context.Background(), d, "../") + err = core.RunMigrations(context.Background(), d, "../") if err != nil { t.Fatalf("Error running migrations: %v", err) }