Add create task

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-02-05 11:14:17 -08:00
parent 2723d34592
commit 1142bf9b32
3 changed files with 185 additions and 0 deletions

View File

@@ -135,6 +135,55 @@ LIMIT 1;
return nil
}
func (t Task) Insert(
ctx context.Context,
conn pg.Conn,
) error {
q := `
WITH task_insert AS (
INSERT INTO tasks (
id,
name,
description,
content_ref,
created_at,
updated_at
)
VALUES (
@task_id,
@name,
@description,
@content_ref,
@created_at,
@updated_at
)
RETURNING id
)
INSERT INTO controls_tasks (
task_id,
control_id,
created_at
)
VALUES (
(SELECT id FROM task_insert),
@control_id,
@created_at
);
`
args := pgx.NamedArgs{
"control_id": t.ID,
"framework_id": t.ControlID,
"name": t.Name,
"description": t.Description,
"content_ref": t.ContentRef,
"created_at": t.CreatedAt,
"updated_at": t.UpdatedAt,
}
_, err := conn.Exec(ctx, q, args)
return err
}
func (t *Tasks) LoadByControlID(
ctx context.Context,
conn pg.Conn,

View File

@@ -52,6 +52,45 @@ func (tst *TaskStateTransition) scan(r pgx.Row) error {
)
}
func (tst TaskStateTransition) Insert(
ctx context.Context,
conn pg.Conn,
) error {
q := `
INSERT INTO
task_state_transitions (
id,
control_id,
from_state
to_state,
reason,
created_at,
updated_at
)
VALUES (
@task_state_transition_id,
@task_id,
@from_state,
@to_state,
@reason,
@created_at,
@updated_at
);
`
args := pgx.NamedArgs{
"task_state_transition_id": tst.ID,
"task_id": tst.TaskID,
"from_state": tst.FromState,
"to_state": tst.ToState,
"reason": tst.Reason,
"created_at": tst.CreatedAt,
"updated_at": tst.UpdatedAt,
}
_, err := conn.Exec(ctx, q, args)
return err
}
func (tst *TaskStateTransitions) LoadByTaskID(
ctx context.Context,
conn pg.Conn,

97
pkg/probo/create_task.go Normal file
View File

@@ -0,0 +1,97 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package probo
import (
"context"
"fmt"
"time"
"gearno.de/ref"
"github.com/getprobo/probo/pkg/gid"
"github.com/getprobo/probo/pkg/probo/coredata"
"go.gearno.de/kit/pg"
)
type (
CreateTaskRequest struct {
ControlID gid.GID
Name string
ContentRef string
}
)
func (s Service) CreateTask(
ctx context.Context,
req CreateTaskRequest,
) (*coredata.Task, error) {
now := time.Now()
taskID, err := gid.NewGID(coredata.TaskEntityType)
if err != nil {
return nil, fmt.Errorf("cannot create task global id: %w", err)
}
taskStateTransitionID, err := gid.NewGID(coredata.TaskStateTransitionEntityType)
if err != nil {
return nil, fmt.Errorf("cannot create task state transition global id: %w", err)
}
control := &coredata.Control{}
task := &coredata.Task{
ID: taskID,
ControlID: req.ControlID,
Name: req.Name,
ContentRef: req.ContentRef,
State: coredata.TaskStateTodo,
CreatedAt: now,
UpdatedAt: now,
}
taskStateTransition := coredata.TaskStateTransition{
StateTransition: coredata.StateTransition[coredata.TaskState]{
ID: taskStateTransitionID,
FromState: nil,
ToState: task.State,
Reason: ref.Ref("Initial state"),
CreatedAt: now,
UpdatedAt: now,
},
TaskID: task.ID,
}
err = s.pg.WithTx(
ctx,
func(conn pg.Conn) error {
if err := control.LoadByID(ctx, conn, s.scope, req.ControlID); err != nil {
return fmt.Errorf("cannot laod control %q: %w", req.ControlID, err)
}
if err := task.Insert(ctx, conn); err != nil {
return fmt.Errorf("cannot insert task: %w", err)
}
if err := taskStateTransition.Insert(ctx, conn); err != nil {
return fmt.Errorf("cannot insert task state transition: %w", err)
}
return nil
},
)
if err != nil {
return nil, err
}
return task, nil
}