Add control importance

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-13 08:46:51 +01:00
parent 4ede969b04
commit d4280b1111
16 changed files with 1162 additions and 186 deletions

View File

@@ -29,16 +29,17 @@ import (
type (
Control struct {
ID gid.GID `db:"id"`
FrameworkID gid.GID `db:"framework_id"`
Category string `db:"category"`
Name string `db:"name"`
Description string `db:"description"`
State ControlState `db:"state"`
ContentRef string `db:"content_ref"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
Version int `db:"version"`
ID gid.GID `db:"id"`
FrameworkID gid.GID `db:"framework_id"`
Category string `db:"category"`
Name string `db:"name"`
Description string `db:"description"`
Importance ControlImportance `db:"importance"`
State ControlState `db:"state"`
ContentRef string `db:"content_ref"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
Version int `db:"version"`
}
Controls []*Control
@@ -49,6 +50,7 @@ type (
Description *string
Category *string
State *ControlState
Importance *ControlImportance
}
)
@@ -70,6 +72,7 @@ SELECT
name,
description,
state,
importance,
content_ref,
created_at,
updated_at,
@@ -115,6 +118,7 @@ INSERT INTO
framework_id,
category,
name,
importance,
state,
description,
content_ref,
@@ -128,6 +132,7 @@ VALUES (
@framework_id,
@category,
@name,
@importance,
@state,
@description,
@content_ref,
@@ -149,6 +154,7 @@ VALUES (
"created_at": c.CreatedAt,
"updated_at": c.UpdatedAt,
"state": c.State,
"importance": c.Importance,
}
_, err := conn.Exec(ctx, q, args)
return err
@@ -169,6 +175,7 @@ SELECT
name,
description,
state,
importance,
content_ref,
created_at,
updated_at,
@@ -213,6 +220,7 @@ UPDATE controls SET
description = COALESCE(@description, description),
category = COALESCE(@category, category),
state = COALESCE(@state, state),
importance = COALESCE(@importance, importance),
updated_at = @updated_at,
version = version + 1
WHERE %s
@@ -224,6 +232,7 @@ RETURNING
category,
name,
description,
importance,
state,
content_ref,
created_at,
@@ -235,23 +244,16 @@ RETURNING
args := pgx.NamedArgs{
"control_id": c.ID,
"expected_version": params.ExpectedVersion,
"name": params.Name,
"description": params.Description,
"category": params.Category,
"state": params.State,
"importance": params.Importance,
"updated_at": time.Now(),
}
maps.Copy(args, scope.SQLArguments())
if params.Name != nil {
args["name"] = *params.Name
}
if params.Description != nil {
args["description"] = *params.Description
}
if params.Category != nil {
args["category"] = *params.Category
}
maps.Copy(args, scope.SQLArguments())
rows, err := conn.Query(ctx, q, args)
if err != nil {
return fmt.Errorf("cannot query controls: %w", err)

View File

@@ -0,0 +1,100 @@
// 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 coredata
import (
"database/sql/driver"
"encoding/json"
"fmt"
)
type ControlImportance uint8
const (
ControlImportanceMandatory ControlImportance = iota
ControlImportancePreferred
ControlImportanceAdvanced
)
func (i ControlImportance) String() string {
return []string{"MANDATORY", "PREFERRED", "ADVANCED"}[i]
}
func (i *ControlImportance) Scan(value interface{}) error {
switch v := value.(type) {
case uint8:
*i = ControlImportance(v)
case string:
switch v {
case "MANDATORY":
*i = ControlImportanceMandatory
case "PREFERRED":
*i = ControlImportancePreferred
case "ADVANCED":
*i = ControlImportanceAdvanced
default:
return fmt.Errorf("invalid ControlImportance value: %q", v)
}
default:
return fmt.Errorf("unsupported type for ControlImportance: %T", value)
}
return nil
}
func (i ControlImportance) Value() (driver.Value, error) {
return i.String(), nil
}
func (i ControlImportance) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
func (i *ControlImportance) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
switch s {
case "MANDATORY":
*i = ControlImportanceMandatory
case "PREFERRED":
*i = ControlImportancePreferred
case "ADVANCED":
*i = ControlImportanceAdvanced
default:
return fmt.Errorf("invalid ControlImportance value: %q", s)
}
return nil
}
func (i *ControlImportance) UnmarshalText(text []byte) error {
var s string
if err := json.Unmarshal(text, &s); err != nil {
return err
}
switch s {
case "MANDATORY":
*i = ControlImportanceMandatory
case "PREFERRED":
*i = ControlImportancePreferred
case "ADVANCED":
*i = ControlImportanceAdvanced
default:
return fmt.Errorf("invalid ControlImportance value: %q", s)
}
return nil
}

View File

@@ -0,0 +1,8 @@
CREATE TYPE control_importance AS ENUM ('MANDATORY', 'PREFERRED', 'ADVANCED');
ALTER TABLE controls ADD COLUMN importance control_importance NOT NULL DEFAULT 'MANDATORY';
ALTER TABLE controls ALTER COLUMN importance DROP DEFAULT;
ALTER TABLE tasks ADD COLUMN time_estimate INTERVAL NOT NULL DEFAULT '00:30:00';
ALTER TABLE tasks ALTER COLUMN time_estimate DROP DEFAULT;