Commit: Bulk unfinished work

This commit is contained in:
2026-01-22 17:39:04 +01:00
parent 6c46b4efcc
commit 3a9acc42a2
68 changed files with 5047 additions and 1064 deletions

View File

@@ -0,0 +1,125 @@
package projectv1
import (
"context"
"errors"
"slices"
"connectrpc.com/connect"
"git.kocoder.xyz/kocoded/vt/fx"
projectv1 "git.kocoder.xyz/kocoded/vt/gen/project/v1"
"git.kocoder.xyz/kocoded/vt/gen/project/v1/projectv1connect"
"git.kocoder.xyz/kocoded/vt/interceptors"
"git.kocoder.xyz/kocoded/vt/model"
"git.kocoder.xyz/kocoded/vt/query"
"gorm.io/gorm"
)
func NewProjectRoute(db *gorm.DB, oidcInterceptor *interceptors.AuthenticationInterceptor) fx.Handler {
path, handler := projectv1connect.NewProjectServiceHandler(&projectService{db: db}, connect.WithInterceptors(oidcInterceptor))
return fx.NewRoute(path, handler)
}
type projectService struct{ db *gorm.DB }
// ListProjects implements projectv1connect.ProjectServiceHandler.
func (s *projectService) ListProjects(ctx context.Context, req *projectv1.ListProjectsRequest) (*projectv1.ListProjectsResponse, error) {
session, ok := interceptors.SessionFromContext(ctx)
if !ok {
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
}
p := query.Use(s.db).Projekt
query := p.Where(p.MandantID.Eq(session.MandantId)).Limit(int(req.PerPage)).Offset(int(req.Page))
if req.OrberBy != "" {
f, ok := p.GetFieldByName(req.OrberBy)
if ok {
if !req.Asc {
query = query.Order(f.Desc())
} else {
query = query.Order(f.Asc())
}
}
} else {
query = query.Order(p.ID.Asc())
}
projects, err := query.Find()
if err != nil {
return nil, connect.NewError(connect.CodeUnknown, err)
}
cnt, err := p.Where(p.MandantID.Eq(session.MandantId)).Count()
if err != nil {
return nil, connect.NewError(connect.CodeUnimplemented, err)
}
data := make([]*projectv1.GetProjectResponse, len(projects))
for i, p := range projects {
data[i] = &projectv1.GetProjectResponse{
Id: int64(p.ID),
Name: p.Name,
Description: p.Description,
IsMaterialized: newPointerBoolean(true),
IsPersonalized: newPointerBoolean(true),
IsConfirmed: newPointerBoolean(true),
IsPaid: nil,
IsDone: s.IsDone(p),
}
}
return &projectv1.ListProjectsResponse{
Data: data,
Meta: &projectv1.Metadata{TotalCount: int32(cnt)},
}, nil
}
func newPointerBoolean(val bool) *bool {
b := val
return &b
}
func (s *projectService) IsDone(p *model.Projekt) *bool {
t := query.Use(s.db).Task
tasks, err := t.Where(t.ProjektID.Eq(p.ID)).Find()
if err != nil {
panic(err)
}
if len(tasks) == 0 {
return nil
}
if i := slices.IndexFunc(tasks, func(t *model.Task) bool {
return !t.Status.IsDone()
}); i != -1 {
return newPointerBoolean(false)
}
return newPointerBoolean(true)
}
func (s *projectService) GetProject(ctx context.Context, req *projectv1.GetProjectRequest) (*projectv1.GetProjectResponse, error) {
session, ok := interceptors.SessionFromContext(ctx)
if !ok {
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("No session set in interceptor"))
}
p := query.Use(s.db).Projekt
query, err := p.Where(p.ID.Eq(uint(req.Id))).Where(p.MandantID.Eq(session.MandantId)).First()
if err != nil {
return nil, err
}
return &projectv1.GetProjectResponse{
Id: int64(query.ID),
Name: query.Name,
Description: query.Description,
IsMaterialized: newPointerBoolean(true),
IsPersonalized: newPointerBoolean(true),
IsConfirmed: newPointerBoolean(true),
IsPaid: newPointerBoolean(true),
IsDone: newPointerBoolean(true),
}, nil
}