package todo import ( "cmp" "context" "net/http" "slices" "time" "connectrpc.com/connect" "connectrpc.com/validate" "github.com/<@var(context.project.name)>/<@var(context.project.name)>/db" todov1 "<@var(context.project.goprefix)>/<@var(context.project.name)>/gen/todo/v1" "<@var(context.project.goprefix)>/<@var(context.project.name)>/gen/todo/v1/todov1connect" . "<@var(context.project.goprefix)>/glstack-test/utils" "github.com/jackc/pgx/v5/pgtype" ) type TodoServer struct{} func (srv *TodoServer) CreateTodo(ctx context.Context, req *connect.Request[todov1.CreateTodoRequest]) (*connect.Response[todov1.CreateTodoResponse], error) { var id pgtype.UUID err := id.Scan(*req.Msg.Todo.Id) if err != nil { return nil, err } todo, err := db.Q.CreateTodo(ctx, db.CreateTodoParams{ ID: id, Task: req.Msg.Todo.Task, }) if err != nil { return nil, err } return &connect.Response[todov1.CreateTodoResponse]{ Msg: &todov1.CreateTodoResponse{ Todo: &todov1.Todo{ Id: StrPtr(todo.ID.String()), Task: todo.Task, CreatedAt: StrPtr(todo.CreatedAt.Time.Format(time.RFC3339)), UpdatesAt: StrPtr(todo.UpdatedAt.Time.Format(time.RFC3339)), Done: BoolPtr(todo.Done.Bool), }, }, }, nil } func (srv *TodoServer) ListTodos(ctx context.Context, req *connect.Request[todov1.ListTodosRequest]) (*connect.Response[todov1.ListTodosResponse], error) { todos, err := db.Q.ListTodos(ctx) if err != nil { return nil, err } responseTodos := []*todov1.Todo{} for _, todo := range todos { responseTodos = append(responseTodos, &todov1.Todo{ Id: StrPtr(todo.ID.String()), Task: todo.Task, CreatedAt: StrPtr(todo.CreatedAt.Time.Format(time.RFC3339)), UpdatesAt: StrPtr(todo.UpdatedAt.Time.Format(time.RFC3339)), Done: BoolPtr(todo.Done.Bool), }) } slices.SortFunc(responseTodos, func(a, b *todov1.Todo) int { dateCmp := cmp.Compare(a.GetCreatedAt(), b.GetCreatedAt()) return dateCmp }) slices.SortFunc(responseTodos, func(a, b *todov1.Todo) int { var boolToInt = func(b bool) int { if b { return 1 } else { return 0 } } doneCmp := cmp.Compare(boolToInt(*a.Done), boolToInt(*b.Done)) return doneCmp }) return &connect.Response[todov1.ListTodosResponse]{ Msg: &todov1.ListTodosResponse{ Todos: responseTodos, }, }, nil } func (srv *TodoServer) UpdateTodo(ctx context.Context, req *connect.Request[todov1.UpdateTodoRequest]) (*connect.Response[todov1.UpdateTodoResponse], error) { var id pgtype.UUID err := id.Scan(*req.Msg.Todo.Id) if err != nil { return nil, err } todo, err := db.Q.UpdateTodo(ctx, db.UpdateTodoParams{ Task: req.Msg.Todo.Task, Done: pgtype.Bool{ Bool: *req.Msg.Todo.Done, Valid: true, }, ID: id, }) if err != nil { return nil, err } return &connect.Response[todov1.UpdateTodoResponse]{ Msg: &todov1.UpdateTodoResponse{ Todo: &todov1.Todo{ Id: StrPtr(todo.ID.String()), Task: todo.Task, CreatedAt: StrPtr(todo.CreatedAt.Time.Format(time.RFC3339)), UpdatesAt: StrPtr(todo.UpdatedAt.Time.Format(time.RFC3339)), Done: BoolPtr(todo.Done.Bool), }, }, }, nil } func (srv *TodoServer) DeleteTodo(ctx context.Context, req *connect.Request[todov1.DeleteTodoRequest]) (*connect.Response[todov1.DeleteTodoResponse], error) { var id pgtype.UUID err := id.Scan(*req.Msg.Todo.Id) if err != nil { return nil, err } err = db.Q.DeleteTodo(ctx, id) if err != nil { return nil, err } return &connect.Response[todov1.DeleteTodoResponse]{ Msg: &todov1.DeleteTodoResponse{}, }, nil } func GetPathHandler() (path string, handler http.Handler) { path, handler = todov1connect.NewTodoServiceHandler(&TodoServer{}, connect.WithInterceptors(validate.NewInterceptor())) return }