diff --git a/internal/types/account.go b/internal/account/type.go
similarity index 97%
rename from internal/types/account.go
rename to internal/account/type.go
index 75d949d..d5b3cff 100644
--- a/internal/types/account.go
+++ b/internal/account/type.go
@@ -1,9 +1,8 @@
-package types
+package account
import (
- "time"
-
"github.com/google/uuid"
+ "time"
)
// The Account holds money.
diff --git a/internal/core/auth.go b/internal/core/auth.go
new file mode 100644
index 0000000..f51574d
--- /dev/null
+++ b/internal/core/auth.go
@@ -0,0 +1,39 @@
+package core
+
+import (
+ "net/http"
+ "spend-sparrow/internal/types"
+)
+
+type ContextKey string
+
+var SessionKey ContextKey = "session"
+var UserKey ContextKey = "user"
+
+func GetUser(r *http.Request) *types.User {
+ obj := r.Context().Value(UserKey)
+ if obj == nil {
+ return nil
+ }
+
+ user, ok := obj.(*types.User)
+ if !ok {
+ return nil
+ }
+
+ return user
+}
+
+func GetSession(r *http.Request) *types.Session {
+ obj := r.Context().Value(SessionKey)
+ if obj == nil {
+ return nil
+ }
+
+ session, ok := obj.(*types.Session)
+ if !ok {
+ return nil
+ }
+
+ return session
+}
diff --git a/internal/handler/default.go b/internal/core/default.go
similarity index 91%
rename from internal/handler/default.go
rename to internal/core/default.go
index c1b5f8b..5b8a1ab 100644
--- a/internal/handler/default.go
+++ b/internal/core/default.go
@@ -1,4 +1,4 @@
-package handler
+package core
import (
"errors"
@@ -12,7 +12,7 @@ import (
"go.opentelemetry.io/otel/trace"
)
-func handleError(w http.ResponseWriter, r *http.Request, err error) {
+func HandleError(w http.ResponseWriter, r *http.Request, err error) {
switch {
case errors.Is(err, service.ErrUnauthorized):
utils.TriggerToastWithStatus(r.Context(), w, r, "error", "You are not autorized to perform this operation.", http.StatusUnauthorized)
@@ -37,7 +37,7 @@ func extractErrorMessage(err error) string {
return strings.SplitN(errMsg, ":", 2)[0]
}
-func updateSpan(r *http.Request) {
+func UpdateSpan(r *http.Request) {
currentSpan := trace.SpanFromContext(r.Context())
if currentSpan != nil {
currentSpan.SetAttributes(attribute.String("http.pattern", r.Pattern))
diff --git a/internal/template/layout.templ b/internal/core/layout.templ
similarity index 99%
rename from internal/template/layout.templ
rename to internal/core/layout.templ
index 499e380..a0f53c5 100644
--- a/internal/template/layout.templ
+++ b/internal/core/layout.templ
@@ -1,4 +1,4 @@
-package template
+package core
import "spend-sparrow/internal/template/svg"
diff --git a/internal/handler/render.go b/internal/core/render.go
similarity index 84%
rename from internal/handler/render.go
rename to internal/core/render.go
index 4e78403..a380a49 100644
--- a/internal/handler/render.go
+++ b/internal/core/render.go
@@ -1,13 +1,10 @@
-package handler
+package core
import (
+ "github.com/a-h/templ"
"log/slog"
"net/http"
- "spend-sparrow/internal/template"
- "spend-sparrow/internal/template/auth"
"spend-sparrow/internal/types"
-
- "github.com/a-h/templ"
)
type Render struct {
@@ -37,15 +34,15 @@ func (render *Render) RenderLayout(r *http.Request, w http.ResponseWriter, slot
func (render *Render) RenderLayoutWithStatus(r *http.Request, w http.ResponseWriter, slot templ.Component, user *types.User, status int) {
userComp := render.getUserComp(user)
- layout := template.Layout(slot, userComp, user != nil, r.URL.Path)
+ layout := Layout(slot, userComp, user != nil, r.URL.Path)
render.RenderWithStatus(r, w, layout, status)
}
func (render *Render) getUserComp(user *types.User) templ.Component {
if user != nil {
- return auth.UserComp(user.Email)
+ return UserComp(user.Email)
} else {
- return auth.UserComp("")
+ return UserComp("")
}
}
diff --git a/internal/template/auth/user.templ b/internal/core/user.templ
similarity index 99%
rename from internal/template/auth/user.templ
rename to internal/core/user.templ
index 364dda7..38e3f3c 100644
--- a/internal/template/auth/user.templ
+++ b/internal/core/user.templ
@@ -1,4 +1,4 @@
-package auth
+package core
templ UserComp(user string) {
diff --git a/internal/default.go b/internal/default.go
index 6134e82..277c75d 100644
--- a/internal/default.go
+++ b/internal/default.go
@@ -1,19 +1,20 @@
package internal
import (
+ "context"
"errors"
"fmt"
"log/slog"
+ "net/http"
+ "os/signal"
+ "spend-sparrow/internal/account"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/db"
"spend-sparrow/internal/handler"
"spend-sparrow/internal/handler/middleware"
"spend-sparrow/internal/log"
"spend-sparrow/internal/service"
"spend-sparrow/internal/types"
-
- "context"
- "net/http"
- "os/signal"
"sync"
"syscall"
"time"
@@ -113,17 +114,17 @@ func createHandlerWithServices(ctx context.Context, d *sqlx.DB, serverSettings *
mailService := service.NewMail(serverSettings)
authService := service.NewAuth(authDb, randomService, clockService, mailService, serverSettings)
- accountService := service.NewAccount(d, randomService, clockService)
+ accountService := account.NewServiceImpl(d, randomService, clockService)
treasureChestService := service.NewTreasureChest(d, randomService, clockService)
transactionService := service.NewTransaction(d, randomService, clockService)
transactionRecurringService := service.NewTransactionRecurring(d, randomService, clockService, transactionService)
dashboardService := service.NewDashboard(d)
- render := handler.NewRender()
+ render := core.NewRender()
indexHandler := handler.NewIndex(render, clockService)
dashboardHandler := handler.NewDashboard(render, dashboardService, treasureChestService)
authHandler := handler.NewAuth(authService, render)
- accountHandler := handler.NewAccount(accountService, render)
+ accountHandler := account.NewHandler(accountService, render)
treasureChestHandler := handler.NewTreasureChest(treasureChestService, transactionRecurringService, render)
transactionHandler := handler.NewTransaction(transactionService, accountService, treasureChestService, render)
transactionRecurringHandler := handler.NewTransactionRecurring(transactionRecurringService, render)
diff --git a/internal/handler/auth.go b/internal/handler/auth.go
index 95558f9..7370b98 100644
--- a/internal/handler/auth.go
+++ b/internal/handler/auth.go
@@ -5,6 +5,7 @@ import (
"log/slog"
"net/http"
"net/url"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/handler/middleware"
"spend-sparrow/internal/service"
"spend-sparrow/internal/template/auth"
@@ -19,10 +20,10 @@ type Auth interface {
type AuthImpl struct {
service service.Auth
- render *Render
+ render *core.Render
}
-func NewAuth(service service.Auth, render *Render) Auth {
+func NewAuth(service service.Auth, render *core.Render) Auth {
return AuthImpl{
service: service,
render: render,
@@ -58,9 +59,9 @@ var (
func (handler AuthImpl) handleSignInPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user != nil {
if !user.EmailVerified {
utils.DoRedirect(w, r, "/auth/verify")
@@ -78,10 +79,10 @@ func (handler AuthImpl) handleSignInPage() http.HandlerFunc {
func (handler AuthImpl) handleSignIn() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
user, err := utils.WaitMinimumTime(securityWaitDuration, func() (*types.User, error) {
- session := middleware.GetSession(r)
+ session := core.GetSession(r)
email := r.FormValue("email")
password := r.FormValue("password")
@@ -115,9 +116,9 @@ func (handler AuthImpl) handleSignIn() http.HandlerFunc {
func (handler AuthImpl) handleSignUpPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user != nil {
if !user.EmailVerified {
@@ -135,9 +136,9 @@ func (handler AuthImpl) handleSignUpPage() http.HandlerFunc {
func (handler AuthImpl) handleSignUpVerifyPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -155,9 +156,9 @@ func (handler AuthImpl) handleSignUpVerifyPage() http.HandlerFunc {
func (handler AuthImpl) handleVerifyResendComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -174,7 +175,7 @@ func (handler AuthImpl) handleVerifyResendComp() http.HandlerFunc {
func (handler AuthImpl) handleSignUpVerifyResponsePage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
token := r.URL.Query().Get("token")
@@ -196,7 +197,7 @@ func (handler AuthImpl) handleSignUpVerifyResponsePage() http.HandlerFunc {
func (handler AuthImpl) handleSignUp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
var email = r.FormValue("email")
var password = r.FormValue("password")
@@ -234,9 +235,9 @@ func (handler AuthImpl) handleSignUp() http.HandlerFunc {
func (handler AuthImpl) handleSignOut() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- session := middleware.GetSession(r)
+ session := core.GetSession(r)
if session != nil {
err := handler.service.SignOut(r.Context(), session.Id)
@@ -263,9 +264,9 @@ func (handler AuthImpl) handleSignOut() http.HandlerFunc {
func (handler AuthImpl) handleDeleteAccountPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -278,9 +279,9 @@ func (handler AuthImpl) handleDeleteAccountPage() http.HandlerFunc {
func (handler AuthImpl) handleDeleteAccountComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -304,11 +305,11 @@ func (handler AuthImpl) handleDeleteAccountComp() http.HandlerFunc {
func (handler AuthImpl) handleChangePasswordPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
isPasswordReset := r.URL.Query().Has("token")
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil && !isPasswordReset {
utils.DoRedirect(w, r, "/auth/signin")
@@ -322,10 +323,10 @@ func (handler AuthImpl) handleChangePasswordPage() http.HandlerFunc {
func (handler AuthImpl) handleChangePasswordComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- session := middleware.GetSession(r)
- user := middleware.GetUser(r)
+ session := core.GetSession(r)
+ user := core.GetUser(r)
if session == nil || user == nil {
utils.TriggerToastWithStatus(r.Context(), w, r, "error", "Unathorized", http.StatusUnauthorized)
return
@@ -346,9 +347,9 @@ func (handler AuthImpl) handleChangePasswordComp() http.HandlerFunc {
func (handler AuthImpl) handleForgotPasswordPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user != nil {
utils.DoRedirect(w, r, "/")
return
@@ -361,7 +362,7 @@ func (handler AuthImpl) handleForgotPasswordPage() http.HandlerFunc {
func (handler AuthImpl) handleForgotPasswordComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
email := r.FormValue("email")
if email == "" {
@@ -384,7 +385,7 @@ func (handler AuthImpl) handleForgotPasswordComp() http.HandlerFunc {
func (handler AuthImpl) handleForgotPasswordResponseComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
pageUrl, err := url.Parse(r.Header.Get("Hx-Current-Url"))
if err != nil {
diff --git a/internal/handler/dashboard.go b/internal/handler/dashboard.go
index f38cdd8..8bc4525 100644
--- a/internal/handler/dashboard.go
+++ b/internal/handler/dashboard.go
@@ -4,7 +4,7 @@ import (
"fmt"
"log/slog"
"net/http"
- "spend-sparrow/internal/handler/middleware"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/service"
"spend-sparrow/internal/template/dashboard"
"spend-sparrow/internal/utils"
@@ -19,12 +19,12 @@ type Dashboard interface {
}
type DashboardImpl struct {
- r *Render
+ r *core.Render
d *service.Dashboard
treasureChest service.TreasureChest
}
-func NewDashboard(r *Render, d *service.Dashboard, treasureChest service.TreasureChest) Dashboard {
+func NewDashboard(r *core.Render, d *service.Dashboard, treasureChest service.TreasureChest) Dashboard {
return DashboardImpl{
r: r,
d: d,
@@ -41,9 +41,9 @@ func (handler DashboardImpl) Handle(router *http.ServeMux) {
func (handler DashboardImpl) handleDashboard() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -51,7 +51,7 @@ func (handler DashboardImpl) handleDashboard() http.HandlerFunc {
treasureChests, err := handler.treasureChest.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -62,13 +62,13 @@ func (handler DashboardImpl) handleDashboard() http.HandlerFunc {
func (handler DashboardImpl) handleDashboardMainChart() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
series, err := handler.d.MainChart(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -128,13 +128,13 @@ func (handler DashboardImpl) handleDashboardMainChart() http.HandlerFunc {
func (handler DashboardImpl) handleDashboardTreasureChests() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
treeList, err := handler.d.TreasureChests(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -183,9 +183,9 @@ func (handler DashboardImpl) handleDashboardTreasureChests() http.HandlerFunc {
func (handler DashboardImpl) handleDashboardTreasureChest() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
var treasureChestId *uuid.UUID
@@ -193,7 +193,7 @@ func (handler DashboardImpl) handleDashboardTreasureChest() http.HandlerFunc {
if treasureChestStr != "" {
id, err := uuid.Parse(treasureChestStr)
if err != nil {
- handleError(w, r, fmt.Errorf("could not parse treasure chest: %w", service.ErrBadRequest))
+ core.HandleError(w, r, fmt.Errorf("could not parse treasure chest: %w", service.ErrBadRequest))
return
}
@@ -202,7 +202,7 @@ func (handler DashboardImpl) handleDashboardTreasureChest() http.HandlerFunc {
series, err := handler.d.TreasureChest(r.Context(), user, treasureChestId)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
diff --git a/internal/handler/middleware/authenticate.go b/internal/handler/middleware/authenticate.go
index 226d840..d20a0b7 100644
--- a/internal/handler/middleware/authenticate.go
+++ b/internal/handler/middleware/authenticate.go
@@ -3,17 +3,11 @@ package middleware
import (
"context"
"net/http"
- "strings"
-
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/service"
- "spend-sparrow/internal/types"
+ "strings"
)
-type ContextKey string
-
-var SessionKey ContextKey = "session"
-var UserKey ContextKey = "user"
-
func Authenticate(service service.Auth) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -41,42 +35,14 @@ func Authenticate(service service.Auth) func(http.Handler) http.Handler {
http.SetCookie(w, &cookie)
}
- ctx = context.WithValue(ctx, UserKey, user)
- ctx = context.WithValue(ctx, SessionKey, session)
+ ctx = context.WithValue(ctx, core.UserKey, user)
+ ctx = context.WithValue(ctx, core.SessionKey, session)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}
-func GetUser(r *http.Request) *types.User {
- obj := r.Context().Value(UserKey)
- if obj == nil {
- return nil
- }
-
- user, ok := obj.(*types.User)
- if !ok {
- return nil
- }
-
- return user
-}
-
-func GetSession(r *http.Request) *types.Session {
- obj := r.Context().Value(SessionKey)
- if obj == nil {
- return nil
- }
-
- session, ok := obj.(*types.Session)
- if !ok {
- return nil
- }
-
- return session
-}
-
func getSessionID(r *http.Request) string {
cookie, err := r.Cookie("id")
if err != nil {
diff --git a/internal/handler/middleware/cross_site_request_forgery.go b/internal/handler/middleware/cross_site_request_forgery.go
index 2e70ddc..4601b56 100644
--- a/internal/handler/middleware/cross_site_request_forgery.go
+++ b/internal/handler/middleware/cross_site_request_forgery.go
@@ -3,6 +3,7 @@ package middleware
import (
"log/slog"
"net/http"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/service"
"spend-sparrow/internal/utils"
"strings"
@@ -40,7 +41,7 @@ func CrossSiteRequestForgery(auth service.Auth) func(http.Handler) http.Handler
return
}
- session := GetSession(r)
+ session := core.GetSession(r)
if r.Method == http.MethodPost ||
r.Method == http.MethodPut ||
diff --git a/internal/handler/root_and_404.go b/internal/handler/root_and_404.go
index 291ee0f..19ad051 100644
--- a/internal/handler/root_and_404.go
+++ b/internal/handler/root_and_404.go
@@ -2,7 +2,7 @@ package handler
import (
"net/http"
- "spend-sparrow/internal/handler/middleware"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/service"
"spend-sparrow/internal/template"
"spend-sparrow/internal/utils"
@@ -15,11 +15,11 @@ type Index interface {
}
type IndexImpl struct {
- r *Render
+ r *core.Render
c service.Clock
}
-func NewIndex(r *Render, c service.Clock) Index {
+func NewIndex(r *core.Render, c service.Clock) Index {
return IndexImpl{
r: r,
c: c,
@@ -33,9 +33,9 @@ func (handler IndexImpl) Handle(router *http.ServeMux) {
func (handler IndexImpl) handleRootAnd404() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
htmx := utils.IsHtmx(r)
@@ -65,7 +65,7 @@ func (handler IndexImpl) handleRootAnd404() http.HandlerFunc {
func (handler IndexImpl) handleEmpty() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
// Return nothing
}
diff --git a/internal/handler/transaction.go b/internal/handler/transaction.go
index 45f3d54..bae53ca 100644
--- a/internal/handler/transaction.go
+++ b/internal/handler/transaction.go
@@ -4,7 +4,8 @@ import (
"fmt"
"math"
"net/http"
- "spend-sparrow/internal/handler/middleware"
+ "spend-sparrow/internal/account"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/service"
t "spend-sparrow/internal/template/transaction"
"spend-sparrow/internal/types"
@@ -22,12 +23,12 @@ type Transaction interface {
type TransactionImpl struct {
s service.Transaction
- account service.Account
+ account account.Service
treasureChest service.TreasureChest
- r *Render
+ r *core.Render
}
-func NewTransaction(s service.Transaction, account service.Account, treasureChest service.TreasureChest, r *Render) Transaction {
+func NewTransaction(s service.Transaction, account account.Service, treasureChest service.TreasureChest, r *core.Render) Transaction {
return TransactionImpl{
s: s,
account: account,
@@ -46,9 +47,9 @@ func (h TransactionImpl) Handle(r *http.ServeMux) {
func (h TransactionImpl) handleTransactionPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -63,19 +64,19 @@ func (h TransactionImpl) handleTransactionPage() http.HandlerFunc {
transactions, err := h.s.GetAll(r.Context(), user, filter)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
accounts, err := h.account.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
treasureChests, err := h.treasureChest.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -93,9 +94,9 @@ func (h TransactionImpl) handleTransactionPage() http.HandlerFunc {
func (h TransactionImpl) handleTransactionItemComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -103,13 +104,13 @@ func (h TransactionImpl) handleTransactionItemComp() http.HandlerFunc {
accounts, err := h.account.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
treasureChests, err := h.treasureChest.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -122,7 +123,7 @@ func (h TransactionImpl) handleTransactionItemComp() http.HandlerFunc {
transaction, err := h.s.Get(r.Context(), user, id)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -139,9 +140,9 @@ func (h TransactionImpl) handleTransactionItemComp() http.HandlerFunc {
func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -156,7 +157,7 @@ func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc {
if idStr != "new" {
id, err = uuid.Parse(idStr)
if err != nil {
- handleError(w, r, fmt.Errorf("could not parse Id: %w", service.ErrBadRequest))
+ core.HandleError(w, r, fmt.Errorf("could not parse Id: %w", service.ErrBadRequest))
return
}
}
@@ -166,7 +167,7 @@ func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc {
if accountIdStr != "" {
i, err := uuid.Parse(accountIdStr)
if err != nil {
- handleError(w, r, fmt.Errorf("could not parse account id: %w", service.ErrBadRequest))
+ core.HandleError(w, r, fmt.Errorf("could not parse account id: %w", service.ErrBadRequest))
return
}
accountId = &i
@@ -177,7 +178,7 @@ func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc {
if treasureChestIdStr != "" {
i, err := uuid.Parse(treasureChestIdStr)
if err != nil {
- handleError(w, r, fmt.Errorf("could not parse treasure chest id: %w", service.ErrBadRequest))
+ core.HandleError(w, r, fmt.Errorf("could not parse treasure chest id: %w", service.ErrBadRequest))
return
}
treasureChestId = &i
@@ -185,14 +186,14 @@ func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc {
valueF, err := strconv.ParseFloat(r.FormValue("value"), 64)
if err != nil {
- handleError(w, r, fmt.Errorf("could not parse value: %w", service.ErrBadRequest))
+ core.HandleError(w, r, fmt.Errorf("could not parse value: %w", service.ErrBadRequest))
return
}
value := int64(math.Round(valueF * service.DECIMALS_MULTIPLIER))
timestamp, err := time.Parse("2006-01-02", r.FormValue("timestamp"))
if err != nil {
- handleError(w, r, fmt.Errorf("could not parse timestamp: %w", service.ErrBadRequest))
+ core.HandleError(w, r, fmt.Errorf("could not parse timestamp: %w", service.ErrBadRequest))
return
}
@@ -210,26 +211,26 @@ func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc {
if idStr == "new" {
transaction, err = h.s.Add(r.Context(), nil, user, input)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
} else {
transaction, err = h.s.Update(r.Context(), user, input)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
}
accounts, err := h.account.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
treasureChests, err := h.treasureChest.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -241,9 +242,9 @@ func (h TransactionImpl) handleUpdateTransaction() http.HandlerFunc {
func (h TransactionImpl) handleRecalculate() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -251,7 +252,7 @@ func (h TransactionImpl) handleRecalculate() http.HandlerFunc {
err := h.s.RecalculateBalances(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -261,9 +262,9 @@ func (h TransactionImpl) handleRecalculate() http.HandlerFunc {
func (h TransactionImpl) handleDeleteTransaction() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -273,13 +274,13 @@ func (h TransactionImpl) handleDeleteTransaction() http.HandlerFunc {
err := h.s.Delete(r.Context(), user, id)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
}
}
-func (h TransactionImpl) getTransactionData(accounts []*types.Account, treasureChests []*types.TreasureChest) (map[uuid.UUID]string, map[uuid.UUID]string) {
+func (h TransactionImpl) getTransactionData(accounts []*account.Account, treasureChests []*types.TreasureChest) (map[uuid.UUID]string, map[uuid.UUID]string) {
accountMap := make(map[uuid.UUID]string, 0)
for _, account := range accounts {
accountMap[account.Id] = account.Name
diff --git a/internal/handler/transaction_recurring.go b/internal/handler/transaction_recurring.go
index 5d1582f..33f8a39 100644
--- a/internal/handler/transaction_recurring.go
+++ b/internal/handler/transaction_recurring.go
@@ -2,7 +2,7 @@ package handler
import (
"net/http"
- "spend-sparrow/internal/handler/middleware"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/service"
t "spend-sparrow/internal/template/transaction_recurring"
"spend-sparrow/internal/types"
@@ -15,10 +15,10 @@ type TransactionRecurring interface {
type TransactionRecurringImpl struct {
s service.TransactionRecurring
- r *Render
+ r *core.Render
}
-func NewTransactionRecurring(s service.TransactionRecurring, r *Render) TransactionRecurring {
+func NewTransactionRecurring(s service.TransactionRecurring, r *core.Render) TransactionRecurring {
return TransactionRecurringImpl{
s: s,
r: r,
@@ -33,9 +33,9 @@ func (h TransactionRecurringImpl) Handle(r *http.ServeMux) {
func (h TransactionRecurringImpl) handleTransactionRecurringItemComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -50,9 +50,9 @@ func (h TransactionRecurringImpl) handleTransactionRecurringItemComp() http.Hand
func (h TransactionRecurringImpl) handleUpdateTransactionRecurring() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -72,13 +72,13 @@ func (h TransactionRecurringImpl) handleUpdateTransactionRecurring() http.Handle
if input.Id == "new" {
_, err := h.s.Add(r.Context(), user, input)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
} else {
_, err := h.s.Update(r.Context(), user, input)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
}
@@ -89,9 +89,9 @@ func (h TransactionRecurringImpl) handleUpdateTransactionRecurring() http.Handle
func (h TransactionRecurringImpl) handleDeleteTransactionRecurring() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -103,7 +103,7 @@ func (h TransactionRecurringImpl) handleDeleteTransactionRecurring() http.Handle
err := h.s.Delete(r.Context(), user, id)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -120,13 +120,13 @@ func (h TransactionRecurringImpl) renderItems(w http.ResponseWriter, r *http.Req
if accountId != "" {
transactionsRecurring, err = h.s.GetAllByAccount(r.Context(), user, accountId)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
} else {
transactionsRecurring, err = h.s.GetAllByTreasureChest(r.Context(), user, treasureChestId)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
}
diff --git a/internal/handler/treasure_chest.go b/internal/handler/treasure_chest.go
index a044610..9cff221 100644
--- a/internal/handler/treasure_chest.go
+++ b/internal/handler/treasure_chest.go
@@ -2,7 +2,7 @@ package handler
import (
"net/http"
- "spend-sparrow/internal/handler/middleware"
+ "spend-sparrow/internal/core"
"spend-sparrow/internal/service"
tr "spend-sparrow/internal/template/transaction_recurring"
t "spend-sparrow/internal/template/treasurechest"
@@ -20,10 +20,10 @@ type TreasureChest interface {
type TreasureChestImpl struct {
s service.TreasureChest
transactionRecurring service.TransactionRecurring
- r *Render
+ r *core.Render
}
-func NewTreasureChest(s service.TreasureChest, transactionRecurring service.TransactionRecurring, r *Render) TreasureChest {
+func NewTreasureChest(s service.TreasureChest, transactionRecurring service.TransactionRecurring, r *core.Render) TreasureChest {
return TreasureChestImpl{
s: s,
transactionRecurring: transactionRecurring,
@@ -40,9 +40,9 @@ func (h TreasureChestImpl) Handle(r *http.ServeMux) {
func (h TreasureChestImpl) handleTreasureChestPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -50,13 +50,13 @@ func (h TreasureChestImpl) handleTreasureChestPage() http.HandlerFunc {
treasureChests, err := h.s.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
transactionsRecurring, err := h.transactionRecurring.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -69,9 +69,9 @@ func (h TreasureChestImpl) handleTreasureChestPage() http.HandlerFunc {
func (h TreasureChestImpl) handleTreasureChestItemComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -79,7 +79,7 @@ func (h TreasureChestImpl) handleTreasureChestItemComp() http.HandlerFunc {
treasureChests, err := h.s.GetAll(r.Context(), user)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -92,13 +92,13 @@ func (h TreasureChestImpl) handleTreasureChestItemComp() http.HandlerFunc {
treasureChest, err := h.s.Get(r.Context(), user, id)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
transactionsRecurring, err := h.transactionRecurring.GetAllByTreasureChest(r.Context(), user, treasureChest.Id.String())
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
transactionsRec := tr.TransactionRecurringItems(transactionsRecurring, "", "", treasureChest.Id.String())
@@ -116,9 +116,9 @@ func (h TreasureChestImpl) handleTreasureChestItemComp() http.HandlerFunc {
func (h TreasureChestImpl) handleUpdateTreasureChest() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -134,20 +134,20 @@ func (h TreasureChestImpl) handleUpdateTreasureChest() http.HandlerFunc {
if id == "new" {
treasureChest, err = h.s.Add(r.Context(), user, parentId, name)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
} else {
treasureChest, err = h.s.Update(r.Context(), user, id, parentId, name)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
}
transactionsRecurring, err := h.transactionRecurring.GetAllByTreasureChest(r.Context(), user, treasureChest.Id.String())
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
@@ -161,9 +161,9 @@ func (h TreasureChestImpl) handleUpdateTreasureChest() http.HandlerFunc {
func (h TreasureChestImpl) handleDeleteTreasureChest() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- updateSpan(r)
+ core.UpdateSpan(r)
- user := middleware.GetUser(r)
+ user := core.GetUser(r)
if user == nil {
utils.DoRedirect(w, r, "/auth/signin")
return
@@ -173,7 +173,7 @@ func (h TreasureChestImpl) handleDeleteTreasureChest() http.HandlerFunc {
err := h.s.Delete(r.Context(), user, id)
if err != nil {
- handleError(w, r, err)
+ core.HandleError(w, r, err)
return
}
}
diff --git a/internal/service/default.go b/internal/service/default.go
index b1ada14..72d8261 100644
--- a/internal/service/default.go
+++ b/internal/service/default.go
@@ -13,7 +13,7 @@ var (
safeInputRegex = regexp.MustCompile(`^[a-zA-Z0-9ÄÖÜäöüß,&'". \-\?]+$`)
)
-func validateString(value string, fieldName string) error {
+func ValidateString(value string, fieldName string) error {
switch {
case value == "":
return fmt.Errorf("field \"%s\" needs to be set: %w", fieldName, ErrBadRequest)
diff --git a/internal/service/transaction.go b/internal/service/transaction.go
index 8278182..f950447 100644
--- a/internal/service/transaction.go
+++ b/internal/service/transaction.go
@@ -499,13 +499,13 @@ func (s TransactionImpl) validateAndEnrichTransaction(ctx context.Context, tx *s
}
if input.Party != "" {
- err = validateString(input.Party, "party")
+ err = ValidateString(input.Party, "party")
if err != nil {
return nil, err
}
}
if input.Description != "" {
- err = validateString(input.Description, "description")
+ err = ValidateString(input.Description, "description")
if err != nil {
return nil, err
}
diff --git a/internal/service/transaction_recurring.go b/internal/service/transaction_recurring.go
index c377840..6982ebc 100644
--- a/internal/service/transaction_recurring.go
+++ b/internal/service/transaction_recurring.go
@@ -471,13 +471,13 @@ func (s TransactionRecurringImpl) validateAndEnrichTransactionRecurring(
value := int64(math.Round(valueFloat * DECIMALS_MULTIPLIER))
if input.Party != "" {
- err = validateString(input.Party, "party")
+ err = ValidateString(input.Party, "party")
if err != nil {
return nil, err
}
}
if input.Description != "" {
- err = validateString(input.Description, "description")
+ err = ValidateString(input.Description, "description")
if err != nil {
return nil, err
}
diff --git a/internal/service/treasure_chest.go b/internal/service/treasure_chest.go
index 54e0ed5..cdc60b5 100644
--- a/internal/service/treasure_chest.go
+++ b/internal/service/treasure_chest.go
@@ -45,7 +45,7 @@ func (s TreasureChestImpl) Add(ctx context.Context, user *types.User, parentId,
return nil, types.ErrInternal
}
- err = validateString(name, "name")
+ err = ValidateString(name, "name")
if err != nil {
return nil, err
}
@@ -92,7 +92,7 @@ func (s TreasureChestImpl) Update(ctx context.Context, user *types.User, idStr,
if user == nil {
return nil, ErrUnauthorized
}
- err := validateString(name, "name")
+ err := ValidateString(name, "name")
if err != nil {
return nil, err
}
diff --git a/internal/template/account/default.go b/internal/template/account/default.go
deleted file mode 100644
index 0bc7635..0000000
--- a/internal/template/account/default.go
+++ /dev/null
@@ -1 +0,0 @@
-package account
diff --git a/internal/template/transaction/transaction.templ b/internal/template/transaction/transaction.templ
index 97a446b..e55b208 100644
--- a/internal/template/transaction/transaction.templ
+++ b/internal/template/transaction/transaction.templ
@@ -4,9 +4,10 @@ import "fmt"
import "time"
import "spend-sparrow/internal/template/svg"
import "spend-sparrow/internal/types"
+import "spend-sparrow/internal/account"
import "github.com/google/uuid"
-templ Transaction(items templ.Component, filter types.TransactionItemsFilter, accounts []*types.Account, treasureChests []*types.TreasureChest) {
+templ Transaction(items templ.Component, filter types.TransactionItemsFilter, accounts []*account.Account, treasureChests []*types.TreasureChest) {