From 31a6c7c499b80ce2f239a64e345edbe4fdaf15ce Mon Sep 17 00:00:00 2001 From: gearnode Date: Thu, 6 Feb 2025 11:36:26 -0800 Subject: [PATCH] Add create evidence Signed-off-by: gearnode --- pkg/probo/coredata/evidence.go | 39 ++++++++ .../coredata/evidence_state_transition.go | 39 ++++++++ pkg/probo/create_evidence.go | 99 +++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 pkg/probo/create_evidence.go diff --git a/pkg/probo/coredata/evidence.go b/pkg/probo/coredata/evidence.go index d62141cf1..bbc0d9737 100644 --- a/pkg/probo/coredata/evidence.go +++ b/pkg/probo/coredata/evidence.go @@ -59,6 +59,45 @@ func (e *Evidence) scan(r pgx.Row) error { ) } +func (e Evidence) Insert( + ctx context.Context, + conn pg.Conn, +) error { + q := ` +INSERT INTO + evidences ( + id, + task_id, + object_key, + mime_type, + size, + created_at, + updated_at, + ) +VALUES ( + @evidence_id, + @task_id, + @object_key, + @mime_type, + @size, + @created_at, + @updated_at +) +` + + args := pgx.NamedArgs{ + "evidence_id": e.ID, + "task_id": e.TaskID, + "object_key": e.ObjectKey, + "mime_type": e.MimeType, + "size": e.Size, + "created_at": e.CreatedAt, + "updated_at": e.UpdatedAt, + } + _, err := conn.Exec(ctx, q, args) + return err +} + func (e *Evidence) LoadByID( ctx context.Context, conn pg.Conn, diff --git a/pkg/probo/coredata/evidence_state_transition.go b/pkg/probo/coredata/evidence_state_transition.go index 9811ba11c..82460068f 100644 --- a/pkg/probo/coredata/evidence_state_transition.go +++ b/pkg/probo/coredata/evidence_state_transition.go @@ -52,6 +52,45 @@ func (cst *EvidenceStateTransition) scan(r pgx.Row) error { ) } +func (est EvidenceStateTransition) Insert( + ctx context.Context, + conn pg.Conn, +) error { + q := ` +INSERT INTO + evidence_state_transitions ( + id, + control_id, + from_state + to_state, + reason, + created_at, + updated_at + ) +VALUES ( + @evidence_state_transition_id, + @evidence_id, + @from_state, + @to_state, + @reason, + @created_at, + @updated_at +); +` + + args := pgx.NamedArgs{ + "evidence_state_transition_id": est.ID, + "evidence_id": est.EvidenceID, + "from_state": est.FromState, + "to_state": est.ToState, + "reason": est.Reason, + "created_at": est.CreatedAt, + "updated_at": est.UpdatedAt, + } + _, err := conn.Exec(ctx, q, args) + return err +} + func (cst *EvidenceStateTransitions) LoadByEvidenceID( ctx context.Context, conn pg.Conn, diff --git a/pkg/probo/create_evidence.go b/pkg/probo/create_evidence.go new file mode 100644 index 000000000..5625e3445 --- /dev/null +++ b/pkg/probo/create_evidence.go @@ -0,0 +1,99 @@ +// Copyright (c) 2025 Probo Inc . +// +// 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" + "io" + "time" + + "gearno.de/ref" + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/probo/coredata" + "go.gearno.de/kit/pg" +) + +type ( + CreateEvidenceRequest struct { + TaskID gid.GID + Name string + File io.Reader + } +) + +func (s Service) CreateEvidence( + ctx context.Context, + req CreateEvidenceRequest, +) (*coredata.Evidence, error) { + now := time.Now() + evidenceID, err := gid.NewGID(coredata.EvidenceEntityType) + if err != nil { + return nil, fmt.Errorf("cannot create vendor global id: %w", err) + } + evidenceStateTransitionID, err := gid.NewGID(coredata.EvidenceStateTransitionEntityType) + if err != nil { + return nil, fmt.Errorf("cannot create evidence state transition: %w", err) + } + + task := &coredata.Organization{} + evidence := &coredata.Evidence{ + ID: evidenceID, + TaskID: req.TaskID, + State: coredata.EvidenceStateValid, + ObjectKey: "", // TODO upload file + MimeType: "", + Size: 0, + CreatedAt: now, + UpdatedAt: now, + } + + evidenceStateTransition := coredata.EvidenceStateTransition{ + StateTransition: coredata.StateTransition[coredata.EvidenceState]{ + ID: evidenceStateTransitionID, + FromState: nil, + ToState: evidence.State, + Reason: ref.Ref("Initial state"), + CreatedAt: now, + UpdatedAt: now, + }, + EvidenceID: evidence.ID, + } + + err = s.pg.WithTx( + ctx, + func(conn pg.Conn) error { + if err := task.LoadByID(ctx, conn, s.scope, req.TaskID); err != nil { + return fmt.Errorf("cannot load task %q: %w", req.TaskID, err) + } + + if err := evidence.Insert(ctx, conn); err != nil { + return fmt.Errorf("cannot insert vendor: %w", err) + } + + if err := evidenceStateTransition.Insert(ctx, conn); err != nil { + return fmt.Errorf("cannot insert evidence state transition: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return evidence, nil +}