feat: unifood base with GET dishes #1

Merged
bissendorf merged 6 commits from feat/base into dev 2025-07-20 17:29:04 +00:00
25 changed files with 724 additions and 0 deletions
Showing only changes of commit 45712dacf6 - Show all commits

5
.vscode/launch.json vendored
View File

@ -11,7 +11,10 @@
"mode": "debug", "mode": "debug",
"program": "${workspaceFolder}/main.go", "program": "${workspaceFolder}/main.go",
"args": [ "args": [
"get", "menu", "-o", "yaml", "--print-config", "true" "get", "dishes",
"-o", "yaml",
"-d", "2025-07-21",
"--print-config"
] ]
} }
] ]

View File

@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"git.bissendorf.co/bissendorf/unifood/m/v2/core/handler/menu" "git.bissendorf.co/bissendorf/unifood/m/v2/core/handler/dishes"
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces" "git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
"git.bissendorf.co/bissendorf/unifood/m/v2/core/services/stwhbclient" "git.bissendorf.co/bissendorf/unifood/m/v2/core/services/stwhbclient"
"git.bissendorf.co/bissendorf/unifood/m/v2/model/external/stwbremen" "git.bissendorf.co/bissendorf/unifood/m/v2/model/external/stwbremen"
@ -9,10 +9,10 @@ import (
var availableResources = []interfaces.ResourceCommand[any]{ var availableResources = []interfaces.ResourceCommand[any]{
{ {
Name: "menu", Name: "dishes",
Aliases: []string{"m"}, Aliases: []string{"dish", "d"},
Verbs: []interfaces.Verb{interfaces.VerbGet}, Verbs: []interfaces.Verb{interfaces.VerbGet},
Handler: &menu.MenuHandler{ Handler: &dishes.DishesHandler{
QueryClient: stwhbclient.New[[]stwbremen.Dish](), QueryClient: stwhbclient.New[[]stwbremen.Dish](),
}, },
}, },

View File

@ -37,7 +37,5 @@ func initRootCmd() {
logger := jlog.New(slog.LevelDebug) logger := jlog.New(slog.LevelDebug)
ctx := jlog.ContextWith(context.Background(), logger) ctx := jlog.ContextWith(context.Background(), logger)
logger.Debug("Register verb commands")
rootCmd.AddCommand(getVerbs(ctx, &appConfig)...) rootCmd.AddCommand(getVerbs(ctx, &appConfig)...)
logger.Debug("Verb commands registered successfully")
} }

View File

@ -33,8 +33,8 @@ var verbs = []VerbItem{
return fmt.Errorf("resource does not support GET") return fmt.Errorf("resource does not support GET")
} }
// Get item // Get items
item, err := h.Get(ctx, params) items, err := h.Get(ctx, params)
if err != nil { if err != nil {
return fmt.Errorf("retrieving item failed: %w", err) return fmt.Errorf("retrieving item failed: %w", err)
} }
@ -46,7 +46,7 @@ var verbs = []VerbItem{
} }
// Format and output // Format and output
formatted, err := formatter.Format(item) formatted, err := formatter.Format(items)
if err != nil { if err != nil {
return fmt.Errorf("failed to format output: %w", err) return fmt.Errorf("failed to format output: %w", err)
} }
@ -61,8 +61,6 @@ var verbs = []VerbItem{
} }
func getVerbs(ctx context.Context, config *AppConfig) (commands []*cobra.Command) { func getVerbs(ctx context.Context, config *AppConfig) (commands []*cobra.Command) {
logger := jlog.FromContext(ctx)
for _, v := range verbs { for _, v := range verbs {
verbCommand := &cobra.Command{ verbCommand := &cobra.Command{
Use: strings.ToLower(string(v.Name)), Use: strings.ToLower(string(v.Name)),
@ -115,8 +113,6 @@ func getVerbs(ctx context.Context, config *AppConfig) (commands []*cobra.Command
) )
} }
verbCommand.AddCommand(resourceCommand) verbCommand.AddCommand(resourceCommand)
logger.Debug(fmt.Sprintf("Registered %s %s", strings.ToUpper(string(v.Name)), r.Name))
} }
commands = append(commands, verbCommand) commands = append(commands, verbCommand)

View File

@ -1,4 +1,4 @@
package menu package dishes
import ( import (
"context" "context"
@ -12,7 +12,7 @@ import (
"git.bissendorf.co/bissendorf/unifood/m/v2/util" "git.bissendorf.co/bissendorf/unifood/m/v2/util"
) )
type MenuHandler struct { type DishesHandler struct {
interfaces.ResourceHandler interfaces.ResourceHandler
interfaces.GetHandler interfaces.GetHandler
@ -24,7 +24,7 @@ const (
paramLocation = "location" paramLocation = "location"
) )
func (h *MenuHandler) Get(ctx context.Context, params params.Container) (any, error) { func (h *DishesHandler) Get(ctx context.Context, params params.Container) ([]any, error) {
// Read parameters // Read parameters
p, err := params.GetValue(paramDate) p, err := params.GetValue(paramDate)
if err != nil { if err != nil {
@ -55,20 +55,18 @@ func (h *MenuHandler) Get(ctx context.Context, params params.Container) (any, er
} }
// Return // Return
return &resources.Menu{ return util.Transform(*dishes, func(i *stwbremen.Dish) any {
Location: location.(string),
Dishes: util.Transform(*dishes, func(i *stwbremen.Dish) resources.Dish {
d, err := resources.DishFromDTO(*i) d, err := resources.DishFromDTO(*i)
if err != nil { if err != nil {
return resources.Dish{} return resources.Dish{}
} }
return *d return *d
}), }), nil
}, nil
} }
func (h *MenuHandler) GetParametersForVerb(verb interfaces.Verb) []params.Registration { func (h *DishesHandler) GetParametersForVerb(verb interfaces.Verb) []params.Registration {
return []params.Registration{ return []params.Registration{
{ {
Name: paramDate, Name: paramDate,

View File

@ -19,7 +19,7 @@ type ResourceHandler interface {
} }
type GetHandler interface { type GetHandler interface {
Get(ctx context.Context, params params.Container) (any, error) Get(ctx context.Context, params params.Container) ([]any, error)
} }
type Verb string type Verb string

View File

@ -3,5 +3,5 @@ package interfaces
import "io" import "io"
type Formatter interface { type Formatter interface {
Format(object any) (io.Reader, error) Format(object []any) (io.Reader, error)
} }

View File

@ -8,6 +8,6 @@ import (
type GoFormatter struct{} type GoFormatter struct{}
func (f *GoFormatter) Format(object any) (io.Reader, error) { func (f *GoFormatter) Format(objects []any) (io.Reader, error) {
return strings.NewReader(fmt.Sprintf("%#v", object)), nil return strings.NewReader(fmt.Sprintf("%#v", objects)), nil
} }

View File

@ -8,8 +8,8 @@ import (
type JsonFormatter struct{} type JsonFormatter struct{}
func (f *JsonFormatter) Format(object any) (io.Reader, error) { func (f *JsonFormatter) Format(objects []any) (io.Reader, error) {
var buffer = make([]byte, 0, 1024) var buffer = make([]byte, 0, 1024)
outputBuffer := bytes.NewBuffer(buffer) outputBuffer := bytes.NewBuffer(buffer)
return outputBuffer, json.NewEncoder(outputBuffer).Encode(object) return outputBuffer, json.NewEncoder(outputBuffer).Encode(objects)
} }

View File

@ -9,8 +9,8 @@ import (
type YamlFormatter struct{} type YamlFormatter struct{}
func (f *YamlFormatter) Format(object any) (io.Reader, error) { func (f *YamlFormatter) Format(objects []any) (io.Reader, error) {
buffer, err := yaml.Marshal(object) buffer, err := yaml.Marshal(objects)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -10,11 +10,6 @@ import (
"git.bissendorf.co/bissendorf/unifood/m/v2/util" "git.bissendorf.co/bissendorf/unifood/m/v2/util"
) )
type Menu struct {
Location string
Dishes []Dish
}
func DishFromDTO(dish stwbremen.Dish) (*Dish, error) { func DishFromDTO(dish stwbremen.Dish) (*Dish, error) {
date, err := time.Parse(time.DateOnly, dish.Date) date, err := time.Parse(time.DateOnly, dish.Date)
if err != nil { if err != nil {