feat: move treasure_chest to seperate module
All checks were successful
Build and Push Docker Image / Build-And-Push-Docker-Image (push) Successful in 1m18s

This commit is contained in:
2025-12-27 10:18:20 +01:00
parent 0325fe101c
commit 28113d27d0
13 changed files with 123 additions and 112 deletions

View File

@@ -6,7 +6,7 @@ import (
"net/http"
"spend-sparrow/internal/core"
"spend-sparrow/internal/dashboard/template"
"spend-sparrow/internal/service"
"spend-sparrow/internal/treasure_chest"
"spend-sparrow/internal/utils"
"strings"
"time"
@@ -21,10 +21,10 @@ type Handler interface {
type HandlerImpl struct {
r *core.Render
s *Service
treasureChest service.TreasureChest
treasureChest treasure_chest.Service
}
func NewHandler(r *core.Render, s *Service, treasureChest service.TreasureChest) Handler {
func NewHandler(r *core.Render, s *Service, treasureChest treasure_chest.Service) Handler {
return HandlerImpl{
r: r,
s: s,

View File

@@ -4,7 +4,8 @@ import (
"context"
"spend-sparrow/internal/auth_types"
"spend-sparrow/internal/core"
"spend-sparrow/internal/service"
"spend-sparrow/internal/treasure_chest"
"spend-sparrow/internal/treasure_chest_types"
"spend-sparrow/internal/types"
"time"
@@ -90,14 +91,14 @@ func (s Service) TreasureChests(
return nil, core.ErrUnauthorized
}
treasureChests := make([]*types.TreasureChest, 0)
treasureChests := make([]*treasure_chest_types.TreasureChest, 0)
err := s.db.SelectContext(ctx, &treasureChests, `SELECT * FROM treasure_chest WHERE user_id = ?`, user.Id)
err = core.TransformAndLogDbError(ctx, "dashboard TreasureChests", nil, err)
if err != nil {
return nil, err
}
treasureChests = service.SortTreasureChests(treasureChests)
treasureChests = treasure_chest.SortTreasureChests(treasureChests)
result := make([]*DashboardTreasureChest, 0)

View File

@@ -1,8 +1,8 @@
package template
import "spend-sparrow/internal/types"
import "spend-sparrow/internal/treasure_chest_types"
templ Dashboard(treasureChests []*types.TreasureChest) {
templ Dashboard(treasureChests []*treasure_chest_types.TreasureChest) {
<div class="mt-10 h-full">
<div id="main-chart" class="h-96 mt-10"></div>
<div id="treasure-chests" class="h-96 mt-10"></div>

View File

@@ -15,6 +15,7 @@ import (
"spend-sparrow/internal/handler/middleware"
"spend-sparrow/internal/log"
"spend-sparrow/internal/service"
"spend-sparrow/internal/treasure_chest"
"spend-sparrow/internal/types"
"sync"
"syscall"
@@ -116,7 +117,7 @@ func createHandlerWithServices(ctx context.Context, d *sqlx.DB, serverSettings *
authService := authentication.NewService(authDb, randomService, clockService, mailService, serverSettings)
accountService := account.NewServiceImpl(d, randomService, clockService)
treasureChestService := service.NewTreasureChest(d, randomService, clockService)
treasureChestService := treasure_chest.NewService(d, randomService, clockService)
transactionService := service.NewTransaction(d, randomService, clockService)
transactionRecurringService := service.NewTransactionRecurring(d, randomService, clockService, transactionService)
dashboardService := dashboard.NewService(d)
@@ -126,7 +127,7 @@ func createHandlerWithServices(ctx context.Context, d *sqlx.DB, serverSettings *
dashboardHandler := dashboard.NewHandler(render, dashboardService, treasureChestService)
authHandler := authentication.NewHandler(authService, render)
accountHandler := account.NewHandler(accountService, render)
treasureChestHandler := handler.NewTreasureChest(treasureChestService, transactionRecurringService, render)
treasureChestHandler := treasure_chest.NewHandler(treasureChestService, transactionRecurringService, render)
transactionHandler := handler.NewTransaction(transactionService, accountService, treasureChestService, render)
transactionRecurringHandler := handler.NewTransactionRecurring(transactionRecurringService, render)

View File

@@ -8,6 +8,8 @@ import (
"spend-sparrow/internal/core"
"spend-sparrow/internal/service"
t "spend-sparrow/internal/template/transaction"
"spend-sparrow/internal/treasure_chest"
"spend-sparrow/internal/treasure_chest_types"
"spend-sparrow/internal/types"
"spend-sparrow/internal/utils"
"strconv"
@@ -24,11 +26,11 @@ type Transaction interface {
type TransactionImpl struct {
s service.Transaction
account account.Service
treasureChest service.TreasureChest
treasureChest treasure_chest.Service
r *core.Render
}
func NewTransaction(s service.Transaction, account account.Service, treasureChest service.TreasureChest, r *core.Render) Transaction {
func NewTransaction(s service.Transaction, account account.Service, treasureChest treasure_chest.Service, r *core.Render) Transaction {
return TransactionImpl{
s: s,
account: account,
@@ -280,7 +282,7 @@ func (h TransactionImpl) handleDeleteTransaction() http.HandlerFunc {
}
}
func (h TransactionImpl) getTransactionData(accounts []*account.Account, treasureChests []*types.TreasureChest) (map[uuid.UUID]string, map[uuid.UUID]string) {
func (h TransactionImpl) getTransactionData(accounts []*account.Account, treasureChests []*treasure_chest_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

View File

@@ -7,6 +7,7 @@ import (
"log/slog"
"spend-sparrow/internal/auth_types"
"spend-sparrow/internal/core"
"spend-sparrow/internal/treasure_chest_types"
"spend-sparrow/internal/types"
"strconv"
"time"
@@ -485,7 +486,7 @@ func (s TransactionImpl) validateAndEnrichTransaction(ctx context.Context, tx *s
}
if input.TreasureChestId != nil {
var treasureChest types.TreasureChest
var treasureChest treasure_chest_types.TreasureChest
err = tx.GetContext(ctx, &treasureChest, `SELECT * FROM treasure_chest WHERE id = ? AND user_id = ?`, input.TreasureChestId, userId)
err = core.TransformAndLogDbError(ctx, "transaction validate", nil, err)
if err != nil {

View File

@@ -8,6 +8,7 @@ import (
"math"
"spend-sparrow/internal/auth_types"
"spend-sparrow/internal/core"
"spend-sparrow/internal/treasure_chest_types"
"spend-sparrow/internal/types"
"strconv"
"time"
@@ -444,7 +445,7 @@ func (s TransactionRecurringImpl) validateAndEnrichTransactionRecurring(
return nil, fmt.Errorf("could not parse treasureChestId: %w", core.ErrBadRequest)
}
treasureChestUuid = &temp
var treasureChest types.TreasureChest
var treasureChest treasure_chest_types.TreasureChest
err = tx.GetContext(ctx, &treasureChest, `SELECT * FROM treasure_chest WHERE id = ? AND user_id = ?`, treasureChestUuid, userId)
err = core.TransformAndLogDbError(ctx, "transactionRecurring validate", nil, err)
if err != nil {

View File

@@ -1,13 +1,16 @@
package transaction
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"
import (
"fmt"
"github.com/google/uuid"
"spend-sparrow/internal/account"
"spend-sparrow/internal/template/svg"
"spend-sparrow/internal/treasure_chest_types"
"spend-sparrow/internal/types"
"time"
)
templ Transaction(items templ.Component, filter types.TransactionItemsFilter, accounts []*account.Account, treasureChests []*types.TreasureChest) {
templ Transaction(items templ.Component, filter types.TransactionItemsFilter, accounts []*account.Account, treasureChests []*treasure_chest_types.TreasureChest) {
<div class="max-w-6xl mt-10 mx-auto">
<div class="flex items-center gap-4">
<form
@@ -96,7 +99,7 @@ templ TransactionItems(transactions []*types.Transaction, accounts, treasureChes
</div>
}
templ EditTransaction(transaction *types.Transaction, accounts []*account.Account, treasureChests []*types.TreasureChest) {
templ EditTransaction(transaction *types.Transaction, accounts []*account.Account, treasureChests []*treasure_chest_types.TreasureChest) {
{{
var (
timestamp time.Time

View File

@@ -1 +0,0 @@
package treasurechest

View File

@@ -1,11 +1,11 @@
package handler
package treasure_chest
import (
"net/http"
"spend-sparrow/internal/core"
"spend-sparrow/internal/service"
tr "spend-sparrow/internal/template/transaction_recurring"
t "spend-sparrow/internal/template/treasurechest"
"spend-sparrow/internal/treasure_chest_types"
"spend-sparrow/internal/types"
"spend-sparrow/internal/utils"
@@ -13,32 +13,32 @@ import (
"github.com/google/uuid"
)
type TreasureChest interface {
type Handler interface {
Handle(router *http.ServeMux)
}
type TreasureChestImpl struct {
s service.TreasureChest
type HandlerImpl struct {
s Service
transactionRecurring service.TransactionRecurring
r *core.Render
}
func NewTreasureChest(s service.TreasureChest, transactionRecurring service.TransactionRecurring, r *core.Render) TreasureChest {
return TreasureChestImpl{
func NewHandler(s Service, transactionRecurring service.TransactionRecurring, r *core.Render) Handler {
return HandlerImpl{
s: s,
transactionRecurring: transactionRecurring,
r: r,
}
}
func (h TreasureChestImpl) Handle(r *http.ServeMux) {
r.Handle("GET /treasurechest", h.handleTreasureChestPage())
r.Handle("GET /treasurechest/{id}", h.handleTreasureChestItemComp())
r.Handle("POST /treasurechest/{id}", h.handleUpdateTreasureChest())
r.Handle("DELETE /treasurechest/{id}", h.handleDeleteTreasureChest())
func (h HandlerImpl) Handle(r *http.ServeMux) {
r.Handle("GET /treasurechest", h.handleHandlerPage())
r.Handle("GET /treasurechest/{id}", h.handleHandlerItemComp())
r.Handle("POST /treasurechest/{id}", h.handleUpdateHandler())
r.Handle("DELETE /treasurechest/{id}", h.handleDeleteHandler())
}
func (h TreasureChestImpl) handleTreasureChestPage() http.HandlerFunc {
func (h HandlerImpl) handleHandlerPage() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
@@ -62,12 +62,12 @@ func (h TreasureChestImpl) handleTreasureChestPage() http.HandlerFunc {
monthlySums := h.calculateMonthlySums(treasureChests, transactionsRecurring)
comp := t.TreasureChest(treasureChests, monthlySums)
comp := TreasureChestComp(treasureChests, monthlySums)
h.r.RenderLayout(r, w, comp, user)
}
}
func (h TreasureChestImpl) handleTreasureChestItemComp() http.HandlerFunc {
func (h HandlerImpl) handleHandlerItemComp() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
@@ -85,7 +85,7 @@ func (h TreasureChestImpl) handleTreasureChestItemComp() http.HandlerFunc {
id := r.PathValue("id")
if id == "new" {
comp := t.EditTreasureChest(nil, treasureChests, nil)
comp := EditTreasureChest(nil, treasureChests, nil)
h.r.Render(r, w, comp)
return
}
@@ -105,16 +105,16 @@ func (h TreasureChestImpl) handleTreasureChestItemComp() http.HandlerFunc {
var comp templ.Component
if r.URL.Query().Get("edit") == "true" {
comp = t.EditTreasureChest(treasureChest, treasureChests, transactionsRec)
comp = EditTreasureChest(treasureChest, treasureChests, transactionsRec)
} else {
monthlySums := h.calculateMonthlySums(treasureChests, transactionsRecurring)
comp = t.TreasureChestItem(treasureChest, monthlySums)
comp = TreasureChestItem(treasureChest, monthlySums)
}
h.r.Render(r, w, comp)
}
}
func (h TreasureChestImpl) handleUpdateTreasureChest() http.HandlerFunc {
func (h HandlerImpl) handleUpdateHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
@@ -125,7 +125,7 @@ func (h TreasureChestImpl) handleUpdateTreasureChest() http.HandlerFunc {
}
var (
treasureChest *types.TreasureChest
treasureChest *treasure_chest_types.TreasureChest
err error
)
id := r.PathValue("id")
@@ -151,15 +151,15 @@ func (h TreasureChestImpl) handleUpdateTreasureChest() http.HandlerFunc {
return
}
treasureChests := make([]*types.TreasureChest, 1)
treasureChests := make([]*treasure_chest_types.TreasureChest, 1)
treasureChests[0] = treasureChest
monthlySums := h.calculateMonthlySums(treasureChests, transactionsRecurring)
comp := t.TreasureChestItem(treasureChest, monthlySums)
comp := TreasureChestItem(treasureChest, monthlySums)
h.r.Render(r, w, comp)
}
}
func (h TreasureChestImpl) handleDeleteTreasureChest() http.HandlerFunc {
func (h HandlerImpl) handleDeleteHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
@@ -179,8 +179,8 @@ func (h TreasureChestImpl) handleDeleteTreasureChest() http.HandlerFunc {
}
}
func (h TreasureChestImpl) calculateMonthlySums(
treasureChests []*types.TreasureChest,
func (h HandlerImpl) calculateMonthlySums(
treasureChests []*treasure_chest_types.TreasureChest,
transactionsRecurring []*types.TransactionRecurring,
) map[uuid.UUID]int64 {
monthlySums := make(map[uuid.UUID]int64)

View File

@@ -1,4 +1,4 @@
package service
package treasure_chest
import (
"context"
@@ -8,35 +8,35 @@ import (
"slices"
"spend-sparrow/internal/auth_types"
"spend-sparrow/internal/core"
"spend-sparrow/internal/types"
"spend-sparrow/internal/treasure_chest_types"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
)
type TreasureChest interface {
Add(ctx context.Context, user *auth_types.User, parentId, name string) (*types.TreasureChest, error)
Update(ctx context.Context, user *auth_types.User, id, parentId, name string) (*types.TreasureChest, error)
Get(ctx context.Context, user *auth_types.User, id string) (*types.TreasureChest, error)
GetAll(ctx context.Context, user *auth_types.User) ([]*types.TreasureChest, error)
type Service interface {
Add(ctx context.Context, user *auth_types.User, parentId, name string) (*treasure_chest_types.TreasureChest, error)
Update(ctx context.Context, user *auth_types.User, id, parentId, name string) (*treasure_chest_types.TreasureChest, error)
Get(ctx context.Context, user *auth_types.User, id string) (*treasure_chest_types.TreasureChest, error)
GetAll(ctx context.Context, user *auth_types.User) ([]*treasure_chest_types.TreasureChest, error)
Delete(ctx context.Context, user *auth_types.User, id string) error
}
type TreasureChestImpl struct {
type ServiceImpl struct {
db *sqlx.DB
clock core.Clock
random core.Random
}
func NewTreasureChest(db *sqlx.DB, random core.Random, clock core.Clock) TreasureChest {
return TreasureChestImpl{
func NewService(db *sqlx.DB, random core.Random, clock core.Clock) Service {
return ServiceImpl{
db: db,
clock: clock,
random: random,
}
}
func (s TreasureChestImpl) Add(ctx context.Context, user *auth_types.User, parentId, name string) (*types.TreasureChest, error) {
func (s ServiceImpl) Add(ctx context.Context, user *auth_types.User, parentId, name string) (*treasure_chest_types.TreasureChest, error) {
if user == nil {
return nil, core.ErrUnauthorized
}
@@ -63,7 +63,7 @@ func (s TreasureChestImpl) Add(ctx context.Context, user *auth_types.User, paren
parentUuid = &parent.Id
}
treasureChest := &types.TreasureChest{
treasureChest := &treasure_chest_types.TreasureChest{
Id: newId,
ParentId: parentUuid,
UserId: user.Id,
@@ -89,7 +89,7 @@ func (s TreasureChestImpl) Add(ctx context.Context, user *auth_types.User, paren
return treasureChest, nil
}
func (s TreasureChestImpl) Update(ctx context.Context, user *auth_types.User, idStr, parentId, name string) (*types.TreasureChest, error) {
func (s ServiceImpl) Update(ctx context.Context, user *auth_types.User, idStr, parentId, name string) (*treasure_chest_types.TreasureChest, error) {
if user == nil {
return nil, core.ErrUnauthorized
}
@@ -112,7 +112,7 @@ func (s TreasureChestImpl) Update(ctx context.Context, user *auth_types.User, id
_ = tx.Rollback()
}()
treasureChest := &types.TreasureChest{}
treasureChest := &treasure_chest_types.TreasureChest{}
err = tx.GetContext(ctx, treasureChest, `SELECT * FROM treasure_chest WHERE user_id = ? AND id = ?`, user.Id, id)
err = core.TransformAndLogDbError(ctx, "treasureChest Update", nil, err)
if err != nil {
@@ -171,7 +171,7 @@ func (s TreasureChestImpl) Update(ctx context.Context, user *auth_types.User, id
return treasureChest, nil
}
func (s TreasureChestImpl) Get(ctx context.Context, user *auth_types.User, id string) (*types.TreasureChest, error) {
func (s ServiceImpl) Get(ctx context.Context, user *auth_types.User, id string) (*treasure_chest_types.TreasureChest, error) {
if user == nil {
return nil, core.ErrUnauthorized
}
@@ -181,7 +181,7 @@ func (s TreasureChestImpl) Get(ctx context.Context, user *auth_types.User, id st
return nil, fmt.Errorf("could not parse Id: %w", core.ErrBadRequest)
}
var treasureChest types.TreasureChest
var treasureChest treasure_chest_types.TreasureChest
err = s.db.GetContext(ctx, &treasureChest, `SELECT * FROM treasure_chest WHERE user_id = ? AND id = ?`, user.Id, uuid)
err = core.TransformAndLogDbError(ctx, "treasureChest Get", nil, err)
if err != nil {
@@ -194,12 +194,12 @@ func (s TreasureChestImpl) Get(ctx context.Context, user *auth_types.User, id st
return &treasureChest, nil
}
func (s TreasureChestImpl) GetAll(ctx context.Context, user *auth_types.User) ([]*types.TreasureChest, error) {
func (s ServiceImpl) GetAll(ctx context.Context, user *auth_types.User) ([]*treasure_chest_types.TreasureChest, error) {
if user == nil {
return nil, core.ErrUnauthorized
}
treasureChests := make([]*types.TreasureChest, 0)
treasureChests := make([]*treasure_chest_types.TreasureChest, 0)
err := s.db.SelectContext(ctx, &treasureChests, `SELECT * FROM treasure_chest WHERE user_id = ?`, user.Id)
err = core.TransformAndLogDbError(ctx, "treasureChest GetAll", nil, err)
if err != nil {
@@ -209,7 +209,7 @@ func (s TreasureChestImpl) GetAll(ctx context.Context, user *auth_types.User) ([
return SortTreasureChests(treasureChests), nil
}
func (s TreasureChestImpl) Delete(ctx context.Context, user *auth_types.User, idStr string) error {
func (s ServiceImpl) Delete(ctx context.Context, user *auth_types.User, idStr string) error {
if user == nil {
return core.ErrUnauthorized
}
@@ -278,12 +278,12 @@ func (s TreasureChestImpl) Delete(ctx context.Context, user *auth_types.User, id
return nil
}
func SortTreasureChests(nodes []*types.TreasureChest) []*types.TreasureChest {
func SortTreasureChests(nodes []*treasure_chest_types.TreasureChest) []*treasure_chest_types.TreasureChest {
var (
roots []*types.TreasureChest
roots []*treasure_chest_types.TreasureChest
)
children := make(map[uuid.UUID][]*types.TreasureChest)
result := make([]*types.TreasureChest, 0)
children := make(map[uuid.UUID][]*treasure_chest_types.TreasureChest)
result := make([]*treasure_chest_types.TreasureChest, 0)
for _, node := range nodes {
if node.ParentId == nil {
@@ -293,7 +293,7 @@ func SortTreasureChests(nodes []*types.TreasureChest) []*types.TreasureChest {
}
}
slices.SortFunc(roots, func(a, b *types.TreasureChest) int {
slices.SortFunc(roots, func(a, b *treasure_chest_types.TreasureChest) int {
return compareStrings(a.Name, b.Name)
})
@@ -302,7 +302,7 @@ func SortTreasureChests(nodes []*types.TreasureChest) []*types.TreasureChest {
childList := children[root.Id]
slices.SortFunc(childList, func(a, b *types.TreasureChest) int {
slices.SortFunc(childList, func(a, b *treasure_chest_types.TreasureChest) int {
return compareStrings(a.Name, b.Name)
})
result = append(result, childList...)

View File

@@ -1,10 +1,13 @@
package treasurechest
package treasure_chest
import "spend-sparrow/internal/template/svg"
import "spend-sparrow/internal/types"
import "github.com/google/uuid"
import (
"github.com/google/uuid"
"spend-sparrow/internal/template/svg"
"spend-sparrow/internal/treasure_chest_types"
"spend-sparrow/internal/types"
)
templ TreasureChest(treasureChests []*types.TreasureChest, monthlySums map[uuid.UUID]int64) {
templ TreasureChestComp(treasureChests []*treasure_chest_types.TreasureChest, monthlySums map[uuid.UUID]int64) {
<div class="max-w-6xl mt-10 mx-auto">
<button
hx-get="/treasurechest/new"
@@ -23,30 +26,30 @@ templ TreasureChest(treasureChests []*types.TreasureChest, monthlySums map[uuid.
</div>
}
templ EditTreasureChest(treasureChest *types.TreasureChest, parents []*types.TreasureChest, transactionsRecurring templ.Component) {
templ EditTreasureChest(treasureChest *treasure_chest_types.TreasureChest, parents []*treasure_chest_types.TreasureChest, transactionsRecurring templ.Component) {
{{
var (
id string
name string
parentId uuid.UUID
cancelUrl string
)
var (
id string
name string
parentId uuid.UUID
cancelUrl string
)
indentation := " mt-10"
if treasureChest == nil {
id = "new"
name = ""
parentId = uuid.Nil
cancelUrl = "/empty"
} else {
id = treasureChest.Id.String()
name = treasureChest.Name
if treasureChest.ParentId != nil {
parentId = *treasureChest.ParentId
indentation = " mt-2 ml-14"
indentation := " mt-10"
if treasureChest == nil {
id = "new"
name = ""
parentId = uuid.Nil
cancelUrl = "/empty"
} else {
id = treasureChest.Id.String()
name = treasureChest.Name
if treasureChest.ParentId != nil {
parentId = *treasureChest.ParentId
indentation = " mt-2 ml-14"
}
cancelUrl = "/treasurechest/" + id
}
cancelUrl = "/treasurechest/" + id
}
}}
<div id={ "treasurechest-" + id } class={ "border-1 border-gray-300 p-4 bg-gray-50 rounded-lg" + indentation }>
<form
@@ -115,16 +118,16 @@ templ EditTreasureChest(treasureChest *types.TreasureChest, parents []*types.Tre
</div>
}
templ TreasureChestItem(treasureChest *types.TreasureChest, monthlySums map[uuid.UUID]int64) {
templ TreasureChestItem(treasureChest *treasure_chest_types.TreasureChest, monthlySums map[uuid.UUID]int64) {
{{
var indentation string
viewTransactions := ""
if treasureChest.ParentId != nil {
indentation = " mt-2 ml-14"
} else {
indentation = " mt-10"
viewTransactions = "hidden"
}
var indentation string
viewTransactions := ""
if treasureChest.ParentId != nil {
indentation = " mt-2 ml-14"
} else {
indentation = " mt-10"
viewTransactions = "hidden"
}
}}
<div id={ "treasurechest-" + treasureChest.Id.String() } class={ "border-1 border-gray-300 p-4 bg-gray-50 rounded-lg" + indentation }>
<div class="text-xl flex justify-end items-center gap-4">
@@ -177,8 +180,8 @@ templ TreasureChestItem(treasureChest *types.TreasureChest, monthlySums map[uuid
</div>
}
func filterNoChildNoSelf(nodes []*types.TreasureChest, selfId string) []*types.TreasureChest {
var result []*types.TreasureChest
func filterNoChildNoSelf(nodes []*treasure_chest_types.TreasureChest, selfId string) []*treasure_chest_types.TreasureChest {
var result []*treasure_chest_types.TreasureChest
for _, node := range nodes {
if node.ParentId == nil && node.Id.String() != selfId {

View File

@@ -1,4 +1,4 @@
package types
package treasure_chest_types
import (
"time"