183 lines
4.6 KiB
Go
183 lines
4.6 KiB
Go
package todov1
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
"strconv"
|
|
|
|
"connectrpc.com/connect"
|
|
"git.kocoder.xyz/kocoded/vt/fx"
|
|
todov1 "git.kocoder.xyz/kocoded/vt/gen/todo/v1"
|
|
"git.kocoder.xyz/kocoded/vt/gen/todo/v1/todov1connect"
|
|
"git.kocoder.xyz/kocoded/vt/interceptors"
|
|
"git.kocoder.xyz/kocoded/vt/query"
|
|
"gorm.io/gen/field"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func NewTodoRoute(db *gorm.DB, logger *slog.Logger, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
|
|
path, handler := todov1connect.NewTodoServiceHandler(&todoService{logger: logger, db: db}, connect.WithInterceptors(oidcInterceptor))
|
|
|
|
return fx.NewRoute(path, handler)
|
|
}
|
|
|
|
type todoService struct {
|
|
logger *slog.Logger
|
|
db *gorm.DB
|
|
}
|
|
|
|
func (ts *todoService) GetTodo(ctx context.Context, req *todov1.GetTodosRequest) (*todov1.GetTodosResponse, error) {
|
|
s, ok := interceptors.SessionFromContext(ctx)
|
|
if !ok {
|
|
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
|
}
|
|
|
|
t := query.Use(ts.db).Task
|
|
res, err := t.Where(t.ID.Eq(uint(req.Id))).Where(t.MandantID.Eq(s.MandantId)).First()
|
|
if err != nil {
|
|
return nil, connect.NewError(connect.CodeInternal, err)
|
|
}
|
|
|
|
tres := &todov1.GetTodosResponse{
|
|
Id: int64(res.ID),
|
|
Title: res.Titel,
|
|
Description: res.Description,
|
|
Status: todov1.Status(res.Status),
|
|
}
|
|
|
|
return tres, nil
|
|
|
|
// return &todov1.GetTodosResponse{
|
|
// Id: 1,
|
|
// Title: "Sample Todo",
|
|
// Description: "This is a sample todo item.",
|
|
// Status: todov1.Status_Doing,
|
|
// }, nil
|
|
}
|
|
|
|
func (ts *todoService) ContributeToQuery(f *todov1.Filter, q query.ITaskDo) query.ITaskDo {
|
|
t := query.Use(ts.db).Task
|
|
|
|
switch f.Field {
|
|
case todov1.Field_FieldDescription, todov1.Field_FieldTitle:
|
|
var field field.String
|
|
if f.Field == todov1.Field_FieldDescription {
|
|
field = t.Description
|
|
} else {
|
|
field = t.Titel
|
|
}
|
|
switch f.Operation {
|
|
case todov1.Operation_Equals:
|
|
q = q.Where(field.Eq(f.Value))
|
|
case todov1.Operation_NotEquals:
|
|
q = q.Where(field.Neq(f.Value))
|
|
case todov1.Operation_GreaterThan:
|
|
q = q.Where(field.Gt(f.Value))
|
|
case todov1.Operation_LessThan:
|
|
q = q.Where(field.Lt(f.Value))
|
|
case todov1.Operation_Like:
|
|
q = q.Where(field.Like(f.Value))
|
|
}
|
|
case todov1.Field_FieldId:
|
|
i, err := strconv.Atoi(f.Value)
|
|
if err != nil {
|
|
slog.Warn("Value not an int", "err", err)
|
|
return q
|
|
}
|
|
switch f.Operation {
|
|
case todov1.Operation_Equals:
|
|
q = q.Where(t.ID.Eq(uint(i)))
|
|
case todov1.Operation_NotEquals:
|
|
q = q.Where(t.ID.Neq(uint(i)))
|
|
case todov1.Operation_GreaterThan:
|
|
q = q.Where(t.ID.Gt(uint(i)))
|
|
case todov1.Operation_LessThan:
|
|
q = q.Where(t.ID.Lt(uint(i)))
|
|
}
|
|
case todov1.Field_FieldStatus:
|
|
i, err := strconv.Atoi(f.Value)
|
|
if err != nil {
|
|
slog.Warn("Value not an int", "err", err)
|
|
return q
|
|
}
|
|
switch f.Operation {
|
|
case todov1.Operation_Equals:
|
|
q = q.Where(t.Status.Eq(i))
|
|
case todov1.Operation_NotEquals:
|
|
q = q.Where(t.Status.Neq(i))
|
|
case todov1.Operation_GreaterThan:
|
|
q = q.Where(t.Status.Gt(i))
|
|
case todov1.Operation_LessThan:
|
|
q = q.Where(t.Status.Lt(i))
|
|
}
|
|
default:
|
|
return q
|
|
}
|
|
return q
|
|
}
|
|
|
|
func (ts *todoService) ListTodos(ctx context.Context, req *todov1.ListTodosRequest) (*todov1.ListTodosResponse, error) {
|
|
ts.logger.Info("ListTodos called", "request", req)
|
|
s, ok := interceptors.SessionFromContext(ctx)
|
|
if !ok {
|
|
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set."))
|
|
}
|
|
|
|
t := query.Use(ts.db).Task
|
|
taskQuery := t.Where(t.MandantID.Eq(s.MandantId))
|
|
|
|
for _, v := range req.Filters {
|
|
taskQuery = ts.ContributeToQuery(v, taskQuery)
|
|
}
|
|
|
|
taskQuery = taskQuery.Limit(int(req.PerPage)).Offset(int(req.Page))
|
|
if req.OrberBy != "" {
|
|
f, ok := t.GetFieldByName(req.OrberBy)
|
|
if ok {
|
|
if !req.Asc {
|
|
taskQuery = taskQuery.Order(f.Desc())
|
|
} else {
|
|
taskQuery = taskQuery.Order(f.Asc())
|
|
}
|
|
}
|
|
} else {
|
|
taskQuery = taskQuery.Order(t.ID.Asc())
|
|
}
|
|
|
|
tasks, err := taskQuery.Find()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
taskQuery = t.Where(t.MandantID.Eq(s.MandantId))
|
|
|
|
for _, v := range req.Filters {
|
|
taskQuery = ts.ContributeToQuery(v, taskQuery)
|
|
}
|
|
|
|
cnt, err := taskQuery.Count()
|
|
|
|
if err != nil {
|
|
ts.logger.Info("Counting Todos failed", "request", req, "err", err)
|
|
panic(err)
|
|
}
|
|
|
|
data := make([]*todov1.GetTodosResponse, len(tasks))
|
|
for i, p := range tasks {
|
|
data[i] = &todov1.GetTodosResponse{
|
|
Id: int64(p.ID),
|
|
Title: p.Titel,
|
|
Description: p.Description,
|
|
Status: todov1.Status(p.Status),
|
|
}
|
|
}
|
|
|
|
return &todov1.ListTodosResponse{
|
|
Data: data,
|
|
Meta: &todov1.Metadata{
|
|
TotalCount: int32(cnt),
|
|
},
|
|
}, nil
|
|
}
|