Rename policy to document
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -56,11 +56,11 @@ func (c Control) CursorKey(orderBy ControlOrderField) page.CursorKey {
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (c *Controls) LoadByPolicyID(
|
||||
func (c *Controls) LoadByDocumentID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyID gid.GID,
|
||||
documentID gid.GID,
|
||||
cursor *page.Cursor[ControlOrderField],
|
||||
) error {
|
||||
q := `
|
||||
@@ -77,9 +77,9 @@ WITH ctrl AS (
|
||||
FROM
|
||||
controls c
|
||||
INNER JOIN
|
||||
controls_policies cp ON c.id = cp.control_id
|
||||
controls_documents cp ON c.id = cp.control_id
|
||||
WHERE
|
||||
cp.policy_id = @policy_id
|
||||
cp.document_id = @document_id
|
||||
)
|
||||
SELECT
|
||||
id,
|
||||
@@ -97,7 +97,7 @@ WHERE %s
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
||||
|
||||
args := pgx.NamedArgs{"policy_id": policyID}
|
||||
args := pgx.NamedArgs{"document_id": documentID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
maps.Copy(args, cursor.SQLArguments())
|
||||
|
||||
@@ -196,9 +196,9 @@ WITH ctrl AS (
|
||||
FROM
|
||||
controls c
|
||||
LEFT JOIN
|
||||
controls_policies cp ON c.id = cp.control_id
|
||||
controls_documents cp ON c.id = cp.control_id
|
||||
LEFT JOIN
|
||||
risks_policies rp ON cp.policy_id = rp.policy_id
|
||||
risks_documents rp ON cp.document_id = rp.document_id
|
||||
LEFT JOIN
|
||||
controls_measures cm ON c.id = cm.control_id
|
||||
LEFT JOIN
|
||||
@@ -449,7 +449,7 @@ UPDATE controls SET
|
||||
updated_at = @updated_at
|
||||
WHERE %s
|
||||
AND id = @control_id
|
||||
RETURNING
|
||||
RETURNING
|
||||
id,
|
||||
framework_id,
|
||||
tenant_id,
|
||||
|
||||
@@ -26,67 +26,67 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
ControlPolicy struct {
|
||||
ControlID gid.GID `db:"control_id"`
|
||||
PolicyID gid.GID `db:"policy_id"`
|
||||
TenantID gid.TenantID `db:"tenant_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
ControlDocument struct {
|
||||
ControlID gid.GID `db:"control_id"`
|
||||
DocumentID gid.GID `db:"document_id"`
|
||||
TenantID gid.TenantID `db:"tenant_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
}
|
||||
|
||||
ControlPolicies []*ControlPolicy
|
||||
ControlDocuments []*ControlDocument
|
||||
)
|
||||
|
||||
func (cp ControlPolicy) Insert(
|
||||
func (cp ControlDocument) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO
|
||||
controls_policies (
|
||||
controls_documents (
|
||||
control_id,
|
||||
policy_id,
|
||||
document_id,
|
||||
tenant_id,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
@control_id,
|
||||
@policy_id,
|
||||
@document_id,
|
||||
@tenant_id,
|
||||
@created_at
|
||||
);
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"control_id": cp.ControlID,
|
||||
"policy_id": cp.PolicyID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"created_at": cp.CreatedAt,
|
||||
"control_id": cp.ControlID,
|
||||
"document_id": cp.DocumentID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"created_at": cp.CreatedAt,
|
||||
}
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cp ControlPolicy) Delete(
|
||||
func (cp ControlDocument) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
controlID gid.GID,
|
||||
policyID gid.GID,
|
||||
documentID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
DELETE
|
||||
FROM
|
||||
controls_policies
|
||||
controls_documents
|
||||
WHERE
|
||||
%s
|
||||
AND control_id = @control_id
|
||||
AND policy_id = @policy_id;
|
||||
AND document_id = @document_id;
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"control_id": controlID,
|
||||
"policy_id": policyID,
|
||||
"control_id": controlID,
|
||||
"document_id": documentID,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
Policy struct {
|
||||
Document struct {
|
||||
ID gid.GID `db:"id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
OwnerID gid.GID `db:"owner_id"`
|
||||
@@ -37,25 +37,25 @@ type (
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
Policies []*Policy
|
||||
Documents []*Document
|
||||
)
|
||||
|
||||
func (p Policy) CursorKey(orderBy PolicyOrderField) page.CursorKey {
|
||||
func (p Document) CursorKey(orderBy DocumentOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case PolicyOrderFieldCreatedAt:
|
||||
case DocumentOrderFieldCreatedAt:
|
||||
return page.NewCursorKey(p.ID, p.CreatedAt)
|
||||
case PolicyOrderFieldTitle:
|
||||
case DocumentOrderFieldTitle:
|
||||
return page.NewCursorKey(p.ID, p.Title)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (p *Policy) LoadByID(
|
||||
func (p *Document) LoadByID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyID gid.GID,
|
||||
documentID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
@@ -67,39 +67,39 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policies
|
||||
documents
|
||||
WHERE
|
||||
%s
|
||||
AND id = @policy_id
|
||||
AND id = @document_id
|
||||
LIMIT 1;
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"policy_id": policyID}
|
||||
args := pgx.StrictNamedArgs{"document_id": documentID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policies: %w", err)
|
||||
return fmt.Errorf("cannot query documents: %w", err)
|
||||
}
|
||||
|
||||
policy, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[Policy])
|
||||
document, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[Document])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy: %w", err)
|
||||
return fmt.Errorf("cannot collect document: %w", err)
|
||||
}
|
||||
|
||||
*p = policy
|
||||
*p = document
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Policies) LoadByOrganizationID(
|
||||
func (p *Documents) LoadByOrganizationID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
cursor *page.Cursor[PolicyOrderField],
|
||||
cursor *page.Cursor[DocumentOrderField],
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
@@ -111,7 +111,7 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policies
|
||||
documents
|
||||
WHERE
|
||||
%s
|
||||
AND organization_id = @organization_id
|
||||
@@ -126,27 +126,27 @@ WHERE
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policies: %w", err)
|
||||
return fmt.Errorf("cannot query documents: %w", err)
|
||||
}
|
||||
|
||||
policies, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[Policy])
|
||||
documents, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[Document])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policies: %w", err)
|
||||
return fmt.Errorf("cannot collect documents: %w", err)
|
||||
}
|
||||
|
||||
*p = policies
|
||||
*p = documents
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p Policy) Insert(
|
||||
func (p Document) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO
|
||||
policies (
|
||||
documents (
|
||||
tenant_id,
|
||||
id,
|
||||
organization_id,
|
||||
@@ -158,7 +158,7 @@ INSERT INTO
|
||||
)
|
||||
VALUES (
|
||||
@tenant_id,
|
||||
@policy_id,
|
||||
@document_id,
|
||||
@organization_id,
|
||||
@owner_id,
|
||||
@title,
|
||||
@@ -170,7 +170,7 @@ VALUES (
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"policy_id": p.ID,
|
||||
"document_id": p.ID,
|
||||
"organization_id": p.OrganizationID,
|
||||
"owner_id": p.OwnerID,
|
||||
"title": p.Title,
|
||||
@@ -182,44 +182,44 @@ VALUES (
|
||||
return err
|
||||
}
|
||||
|
||||
func (p Policy) Delete(
|
||||
func (p Document) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
DELETE FROM policies WHERE %s AND id = @policy_id
|
||||
DELETE FROM documents WHERE %s AND id = @document_id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"policy_id": p.ID}
|
||||
args := pgx.StrictNamedArgs{"document_id": p.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Policy) Update(
|
||||
func (p *Document) Update(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
UPDATE
|
||||
policies
|
||||
documents
|
||||
SET
|
||||
title = @title,
|
||||
current_published_version = @current_published_version,
|
||||
owner_id = @owner_id,
|
||||
updated_at = @updated_at
|
||||
WHERE %s
|
||||
AND id = @policy_id
|
||||
AND id = @document_id
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"policy_id": p.ID,
|
||||
"document_id": p.ID,
|
||||
"updated_at": time.Now(),
|
||||
"title": p.Title,
|
||||
"current_published_version": p.CurrentPublishedVersion,
|
||||
@@ -229,18 +229,18 @@ WHERE %s
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update policy: %w", err)
|
||||
return fmt.Errorf("cannot update document: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Policies) LoadByControlID(
|
||||
func (p *Documents) LoadByControlID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
controlID gid.GID,
|
||||
cursor *page.Cursor[PolicyOrderField],
|
||||
cursor *page.Cursor[DocumentOrderField],
|
||||
) error {
|
||||
q := `
|
||||
WITH plcs AS (
|
||||
@@ -254,9 +254,9 @@ WITH plcs AS (
|
||||
p.created_at,
|
||||
p.updated_at
|
||||
FROM
|
||||
policies p
|
||||
documents p
|
||||
INNER JOIN
|
||||
controls_policies cp ON p.id = cp.policy_id
|
||||
controls_documents cp ON p.id = cp.document_id
|
||||
WHERE
|
||||
cp.control_id = @control_id
|
||||
)
|
||||
@@ -281,25 +281,25 @@ WHERE %s
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policies: %w", err)
|
||||
return fmt.Errorf("cannot query documents: %w", err)
|
||||
}
|
||||
|
||||
policies, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[Policy])
|
||||
documents, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[Document])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policies: %w", err)
|
||||
return fmt.Errorf("cannot collect documents: %w", err)
|
||||
}
|
||||
|
||||
*p = policies
|
||||
*p = documents
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Policies) LoadByRiskID(
|
||||
func (p *Documents) LoadByRiskID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
riskID gid.GID,
|
||||
cursor *page.Cursor[PolicyOrderField],
|
||||
cursor *page.Cursor[DocumentOrderField],
|
||||
) error {
|
||||
q := `
|
||||
WITH plcs AS (
|
||||
@@ -313,9 +313,9 @@ WITH plcs AS (
|
||||
p.created_at,
|
||||
p.updated_at
|
||||
FROM
|
||||
policies p
|
||||
documents p
|
||||
INNER JOIN
|
||||
risks_policies rp ON p.id = rp.policy_id
|
||||
risks_documents rp ON p.id = rp.document_id
|
||||
WHERE
|
||||
rp.risk_id = @risk_id
|
||||
)
|
||||
@@ -340,15 +340,15 @@ WHERE %s
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policies: %w", err)
|
||||
return fmt.Errorf("cannot query documents: %w", err)
|
||||
}
|
||||
|
||||
policies, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[Policy])
|
||||
documents, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[Document])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policies: %w", err)
|
||||
return fmt.Errorf("cannot collect documents: %w", err)
|
||||
}
|
||||
|
||||
*p = policies
|
||||
*p = documents
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -15,27 +15,27 @@
|
||||
package coredata
|
||||
|
||||
type (
|
||||
PolicyOrderField string
|
||||
DocumentOrderField string
|
||||
)
|
||||
|
||||
const (
|
||||
PolicyOrderFieldCreatedAt PolicyOrderField = "CREATED_AT"
|
||||
PolicyOrderFieldTitle PolicyOrderField = "TITLE"
|
||||
DocumentOrderFieldCreatedAt DocumentOrderField = "CREATED_AT"
|
||||
DocumentOrderFieldTitle DocumentOrderField = "TITLE"
|
||||
)
|
||||
|
||||
func (p PolicyOrderField) Column() string {
|
||||
func (p DocumentOrderField) Column() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (p PolicyOrderField) String() string {
|
||||
func (p DocumentOrderField) String() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (p PolicyOrderField) MarshalText() ([]byte, error) {
|
||||
func (p DocumentOrderField) MarshalText() ([]byte, error) {
|
||||
return []byte(p.String()), nil
|
||||
}
|
||||
|
||||
func (p *PolicyOrderField) UnmarshalText(text []byte) error {
|
||||
*p = PolicyOrderField(text)
|
||||
func (p *DocumentOrderField) UnmarshalText(text []byte) error {
|
||||
*p = DocumentOrderField(text)
|
||||
return nil
|
||||
}
|
||||
@@ -20,55 +20,55 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyStatus uint8
|
||||
DocumentStatus uint8
|
||||
)
|
||||
|
||||
const (
|
||||
PolicyStatusDraft PolicyStatus = iota
|
||||
PolicyStatusPublished
|
||||
DocumentStatusDraft DocumentStatus = iota
|
||||
DocumentStatusPublished
|
||||
)
|
||||
|
||||
func (ps PolicyStatus) MarshalText() ([]byte, error) {
|
||||
func (ps DocumentStatus) MarshalText() ([]byte, error) {
|
||||
return []byte(ps.String()), nil
|
||||
}
|
||||
|
||||
func (ps *PolicyStatus) UnmarshalText(data []byte) error {
|
||||
func (ps *DocumentStatus) UnmarshalText(data []byte) error {
|
||||
val := string(data)
|
||||
|
||||
switch val {
|
||||
case PolicyStatusDraft.String():
|
||||
*ps = PolicyStatusDraft
|
||||
case PolicyStatusPublished.String():
|
||||
*ps = PolicyStatusPublished
|
||||
case DocumentStatusDraft.String():
|
||||
*ps = DocumentStatusDraft
|
||||
case DocumentStatusPublished.String():
|
||||
*ps = DocumentStatusPublished
|
||||
default:
|
||||
return fmt.Errorf("invalid PolicyStatus value: %q", val)
|
||||
return fmt.Errorf("invalid DocumentStatus value: %q", val)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ps PolicyStatus) String() string {
|
||||
func (ps DocumentStatus) String() string {
|
||||
var val string
|
||||
|
||||
switch ps {
|
||||
case PolicyStatusDraft:
|
||||
case DocumentStatusDraft:
|
||||
val = "DRAFT"
|
||||
case PolicyStatusPublished:
|
||||
case DocumentStatusPublished:
|
||||
val = "PUBLISHED"
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func (ps *PolicyStatus) Scan(value any) error {
|
||||
func (ps *DocumentStatus) Scan(value any) error {
|
||||
val, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid scan source for PolicyStatus, expected string got %T", value)
|
||||
return fmt.Errorf("invalid scan source for DocumentStatus, expected string got %T", value)
|
||||
}
|
||||
|
||||
return ps.UnmarshalText([]byte(val))
|
||||
}
|
||||
|
||||
func (ps PolicyStatus) Value() (driver.Value, error) {
|
||||
func (ps DocumentStatus) Value() (driver.Value, error) {
|
||||
return ps.String(), nil
|
||||
}
|
||||
@@ -27,34 +27,34 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyVersion struct {
|
||||
ID gid.GID `db:"id"`
|
||||
PolicyID gid.GID `db:"policy_id"`
|
||||
VersionNumber int `db:"version_number"`
|
||||
Content string `db:"content"`
|
||||
Changelog string `db:"changelog"`
|
||||
CreatedBy gid.GID `db:"created_by"`
|
||||
Status PolicyStatus `db:"status"`
|
||||
PublishedBy *gid.GID `db:"published_by"`
|
||||
PublishedAt *time.Time `db:"published_at"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
DocumentVersion struct {
|
||||
ID gid.GID `db:"id"`
|
||||
DocumentID gid.GID `db:"document_id"`
|
||||
VersionNumber int `db:"version_number"`
|
||||
Content string `db:"content"`
|
||||
Changelog string `db:"changelog"`
|
||||
CreatedBy gid.GID `db:"created_by"`
|
||||
Status DocumentStatus `db:"status"`
|
||||
PublishedBy *gid.GID `db:"published_by"`
|
||||
PublishedAt *time.Time `db:"published_at"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
PolicyVersions []*PolicyVersion
|
||||
DocumentVersions []*DocumentVersion
|
||||
)
|
||||
|
||||
func (p *PolicyVersions) LoadByPolicyID(
|
||||
func (p *DocumentVersions) LoadByDocumentID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyID gid.GID,
|
||||
cursor *page.Cursor[PolicyVersionOrderField],
|
||||
documentID gid.GID,
|
||||
cursor *page.Cursor[DocumentVersionOrderField],
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
policy_id,
|
||||
document_id,
|
||||
version_number,
|
||||
content,
|
||||
changelog,
|
||||
@@ -65,53 +65,53 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policy_versions
|
||||
document_versions
|
||||
WHERE
|
||||
%s
|
||||
AND policy_id = @policy_id
|
||||
AND document_id = @document_id
|
||||
AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"policy_id": policyID}
|
||||
args := pgx.StrictNamedArgs{"document_id": documentID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
maps.Copy(args, cursor.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policy versions: %w", err)
|
||||
return fmt.Errorf("cannot query document versions: %w", err)
|
||||
}
|
||||
|
||||
policyVersions, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[PolicyVersion])
|
||||
documentVersions, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[DocumentVersion])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy versions: %w", err)
|
||||
return fmt.Errorf("cannot collect document versions: %w", err)
|
||||
}
|
||||
|
||||
*p = policyVersions
|
||||
*p = documentVersions
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p PolicyVersion) CursorKey(orderBy PolicyVersionOrderField) page.CursorKey {
|
||||
func (p DocumentVersion) CursorKey(orderBy DocumentVersionOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case PolicyVersionOrderFieldCreatedAt:
|
||||
case DocumentVersionOrderFieldCreatedAt:
|
||||
return page.NewCursorKey(p.ID, p.CreatedAt)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (p *PolicyVersion) LoadByID(
|
||||
func (p *DocumentVersion) LoadByID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyVersionID gid.GID,
|
||||
documentVersionID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
policy_id,
|
||||
document_id,
|
||||
version_number,
|
||||
content,
|
||||
changelog,
|
||||
@@ -122,43 +122,43 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policy_versions
|
||||
document_versions
|
||||
WHERE
|
||||
%s
|
||||
AND id = @policy_version_id
|
||||
AND id = @document_version_id
|
||||
LIMIT 1;
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"policy_version_id": policyVersionID}
|
||||
args := pgx.StrictNamedArgs{"document_version_id": documentVersionID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policy versions: %w", err)
|
||||
return fmt.Errorf("cannot query document versions: %w", err)
|
||||
}
|
||||
|
||||
policyVersion, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[PolicyVersion])
|
||||
documentVersion, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[DocumentVersion])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy version: %w", err)
|
||||
return fmt.Errorf("cannot collect document version: %w", err)
|
||||
}
|
||||
|
||||
*p = policyVersion
|
||||
*p = documentVersion
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p PolicyVersion) Insert(
|
||||
func (p DocumentVersion) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO policy_versions (
|
||||
INSERT INTO document_versions (
|
||||
tenant_id,
|
||||
id,
|
||||
policy_id,
|
||||
document_id,
|
||||
version_number,
|
||||
content,
|
||||
changelog,
|
||||
@@ -169,7 +169,7 @@ INSERT INTO policy_versions (
|
||||
) VALUES (
|
||||
@tenant_id,
|
||||
@id,
|
||||
@policy_id,
|
||||
@document_id,
|
||||
@version_number,
|
||||
@content,
|
||||
@changelog,
|
||||
@@ -184,7 +184,7 @@ INSERT INTO policy_versions (
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"id": p.ID,
|
||||
"policy_id": p.PolicyID,
|
||||
"document_id": p.DocumentID,
|
||||
"version_number": p.VersionNumber,
|
||||
"content": p.Content,
|
||||
"changelog": p.Changelog,
|
||||
@@ -196,23 +196,23 @@ INSERT INTO policy_versions (
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating/updating policy version: %w", err)
|
||||
return fmt.Errorf("error creating/updating document version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PolicyVersion) LoadByPolicyIDAndVersionNumber(
|
||||
func (p *DocumentVersion) LoadByDocumentIDAndVersionNumber(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyID gid.GID,
|
||||
documentID gid.GID,
|
||||
versionNumber int,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
policy_id,
|
||||
document_id,
|
||||
version_number,
|
||||
content,
|
||||
changelog,
|
||||
@@ -223,10 +223,10 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policy_versions
|
||||
document_versions
|
||||
WHERE
|
||||
%s
|
||||
AND policy_id = @policy_id
|
||||
AND document_id = @document_id
|
||||
AND version_number = @version_number
|
||||
LIMIT 1;
|
||||
`
|
||||
@@ -234,7 +234,7 @@ LIMIT 1;
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"policy_id": policyID,
|
||||
"document_id": documentID,
|
||||
"version_number": versionNumber,
|
||||
}
|
||||
|
||||
@@ -242,29 +242,29 @@ LIMIT 1;
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policy versions: %w", err)
|
||||
return fmt.Errorf("cannot query document versions: %w", err)
|
||||
}
|
||||
|
||||
policyVersion, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[PolicyVersion])
|
||||
documentVersion, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[DocumentVersion])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy version: %w", err)
|
||||
return fmt.Errorf("cannot collect document version: %w", err)
|
||||
}
|
||||
|
||||
*p = policyVersion
|
||||
*p = documentVersion
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PolicyVersion) LoadLatestVersion(
|
||||
func (p *DocumentVersion) LoadLatestVersion(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyID gid.GID,
|
||||
documentID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
policy_id,
|
||||
document_id,
|
||||
version_number,
|
||||
content,
|
||||
changelog,
|
||||
@@ -275,10 +275,10 @@ SELECT
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policy_versions
|
||||
document_versions
|
||||
WHERE
|
||||
%s
|
||||
AND policy_id = @policy_id
|
||||
AND document_id = @document_id
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 1;
|
||||
`
|
||||
@@ -286,58 +286,58 @@ LIMIT 1;
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"policy_id": policyID,
|
||||
"document_id": documentID,
|
||||
}
|
||||
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policy versions: %w", err)
|
||||
return fmt.Errorf("cannot query document versions: %w", err)
|
||||
}
|
||||
|
||||
policyVersion, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[PolicyVersion])
|
||||
documentVersion, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[DocumentVersion])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy version: %w", err)
|
||||
return fmt.Errorf("cannot collect document version: %w", err)
|
||||
}
|
||||
|
||||
*p = policyVersion
|
||||
*p = documentVersion
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p PolicyVersion) Update(
|
||||
func (p DocumentVersion) Update(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
UPDATE policy_versions SET
|
||||
UPDATE document_versions SET
|
||||
changelog = @changelog,
|
||||
status = @status,
|
||||
status = @status,
|
||||
content = @content,
|
||||
published_by = @published_by,
|
||||
published_at = @published_at,
|
||||
updated_at = @updated_at
|
||||
WHERE %s
|
||||
AND id = @policy_version_id;`
|
||||
AND id = @document_version_id;`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"policy_version_id": p.ID,
|
||||
"changelog": p.Changelog,
|
||||
"status": p.Status,
|
||||
"content": p.Content,
|
||||
"published_by": p.PublishedBy,
|
||||
"published_at": p.PublishedAt,
|
||||
"updated_at": p.UpdatedAt,
|
||||
"document_version_id": p.ID,
|
||||
"changelog": p.Changelog,
|
||||
"status": p.Status,
|
||||
"content": p.Content,
|
||||
"published_by": p.PublishedBy,
|
||||
"published_at": p.PublishedAt,
|
||||
"updated_at": p.UpdatedAt,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update policy version: %w", err)
|
||||
return fmt.Errorf("cannot update document version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -15,27 +15,27 @@
|
||||
package coredata
|
||||
|
||||
type (
|
||||
PolicyVersionOrderField string
|
||||
DocumentVersionOrderField string
|
||||
)
|
||||
|
||||
const (
|
||||
PolicyVersionOrderFieldCreatedAt PolicyVersionOrderField = "CREATED_AT"
|
||||
PolicyVersionOrderFieldVersion PolicyVersionOrderField = "VERSION"
|
||||
DocumentVersionOrderFieldCreatedAt DocumentVersionOrderField = "CREATED_AT"
|
||||
DocumentVersionOrderFieldVersion DocumentVersionOrderField = "VERSION"
|
||||
)
|
||||
|
||||
func (p PolicyVersionOrderField) Column() string {
|
||||
func (p DocumentVersionOrderField) Column() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (p PolicyVersionOrderField) String() string {
|
||||
func (p DocumentVersionOrderField) String() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (p PolicyVersionOrderField) MarshalText() ([]byte, error) {
|
||||
func (p DocumentVersionOrderField) MarshalText() ([]byte, error) {
|
||||
return []byte(p.String()), nil
|
||||
}
|
||||
|
||||
func (p *PolicyVersionOrderField) UnmarshalText(text []byte) error {
|
||||
*p = PolicyVersionOrderField(text)
|
||||
func (p *DocumentVersionOrderField) UnmarshalText(text []byte) error {
|
||||
*p = DocumentVersionOrderField(text)
|
||||
return nil
|
||||
}
|
||||
281
pkg/coredata/document_version_signature.go
Normal file
281
pkg/coredata/document_version_signature.go
Normal file
@@ -0,0 +1,281 @@
|
||||
// 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 (
|
||||
"context"
|
||||
"fmt"
|
||||
"maps"
|
||||
"time"
|
||||
|
||||
"github.com/getprobo/probo/pkg/gid"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"go.gearno.de/kit/pg"
|
||||
)
|
||||
|
||||
type (
|
||||
DocumentVersionSignature struct {
|
||||
ID gid.GID `json:"id"`
|
||||
DocumentVersionID gid.GID `json:"document_version_id"`
|
||||
State DocumentVersionSignatureState `json:"state"`
|
||||
SignedBy gid.GID `json:"signed_by"`
|
||||
SignedAt *time.Time `json:"signed_at"`
|
||||
RequestedAt time.Time `json:"requested_at"`
|
||||
RequestedBy gid.GID `json:"requested_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
DocumentVersionSignatures []*DocumentVersionSignature
|
||||
)
|
||||
|
||||
func (pvs DocumentVersionSignature) CursorKey(orderBy DocumentVersionSignatureOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case DocumentVersionSignatureOrderFieldCreatedAt:
|
||||
return page.NewCursorKey(pvs.ID, pvs.CreatedAt)
|
||||
case DocumentVersionSignatureOrderFieldSignedAt:
|
||||
return page.NewCursorKey(pvs.ID, pvs.SignedAt)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (pvs *DocumentVersionSignature) LoadByDocumentVersionIDAndSignatory(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
documentVersionID gid.GID,
|
||||
signatory gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
document_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
document_version_signatures
|
||||
WHERE
|
||||
%s
|
||||
AND document_version_id = @document_version_id
|
||||
AND signed_by = @signatory
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"document_version_id": documentVersionID, "signatory": signatory}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query document version signature: %w", err)
|
||||
}
|
||||
|
||||
documentVersionSignature, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[DocumentVersionSignature])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect document version signature: %w", err)
|
||||
}
|
||||
|
||||
*pvs = documentVersionSignature
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvs *DocumentVersionSignature) LoadByID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
signatureID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
document_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
document_version_signatures
|
||||
WHERE
|
||||
id = @document_version_signature_id
|
||||
AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"document_version_signature_id": signatureID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query document version signature: %w", err)
|
||||
}
|
||||
|
||||
documentVersionSignature, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[DocumentVersionSignature])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect document version signature: %w", err)
|
||||
}
|
||||
|
||||
*pvs = documentVersionSignature
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvs DocumentVersionSignature) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO document_version_signatures (
|
||||
id,
|
||||
tenant_id,
|
||||
document_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
) VALUES (
|
||||
@id,
|
||||
@tenant_id,
|
||||
@document_version_id,
|
||||
@state,
|
||||
@signed_by,
|
||||
@signed_at,
|
||||
@requested_at,
|
||||
@requested_by,
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": pvs.ID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"document_version_id": pvs.DocumentVersionID,
|
||||
"state": pvs.State,
|
||||
"signed_by": pvs.SignedBy,
|
||||
"signed_at": pvs.SignedAt,
|
||||
"requested_at": pvs.RequestedAt,
|
||||
"requested_by": pvs.RequestedBy,
|
||||
"created_at": pvs.CreatedAt,
|
||||
"updated_at": pvs.UpdatedAt,
|
||||
}
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert document version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvss *DocumentVersionSignatures) LoadByDocumentVersionID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
documentVersionID gid.GID,
|
||||
cursor *page.Cursor[DocumentVersionSignatureOrderField],
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
document_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
document_version_signatures
|
||||
WHERE
|
||||
%s
|
||||
AND document_version_id = @document_version_id
|
||||
AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"document_version_id": documentVersionID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
maps.Copy(args, cursor.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query document version signatures: %w", err)
|
||||
}
|
||||
|
||||
documentVersionSignatures, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[DocumentVersionSignature])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect document version signatures: %w", err)
|
||||
}
|
||||
|
||||
*pvss = documentVersionSignatures
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvs *DocumentVersionSignature) Update(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
UPDATE document_version_signatures
|
||||
SET
|
||||
state = @state,
|
||||
signed_by = @signed_by,
|
||||
signed_at = @signed_at,
|
||||
updated_at = @updated_at
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": pvs.ID,
|
||||
"state": pvs.State,
|
||||
"signed_by": pvs.SignedBy,
|
||||
"signed_at": pvs.SignedAt,
|
||||
"updated_at": pvs.UpdatedAt,
|
||||
}
|
||||
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update document version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -15,27 +15,27 @@
|
||||
package coredata
|
||||
|
||||
type (
|
||||
PolicyVersionSignatureOrderField string
|
||||
DocumentVersionSignatureOrderField string
|
||||
)
|
||||
|
||||
const (
|
||||
PolicyVersionSignatureOrderFieldCreatedAt PolicyVersionSignatureOrderField = "CREATED_AT"
|
||||
PolicyVersionSignatureOrderFieldSignedAt PolicyVersionSignatureOrderField = "SIGNED_AT"
|
||||
DocumentVersionSignatureOrderFieldCreatedAt DocumentVersionSignatureOrderField = "CREATED_AT"
|
||||
DocumentVersionSignatureOrderFieldSignedAt DocumentVersionSignatureOrderField = "SIGNED_AT"
|
||||
)
|
||||
|
||||
func (p PolicyVersionSignatureOrderField) Column() string {
|
||||
func (p DocumentVersionSignatureOrderField) Column() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (p PolicyVersionSignatureOrderField) String() string {
|
||||
func (p DocumentVersionSignatureOrderField) String() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (p PolicyVersionSignatureOrderField) MarshalText() ([]byte, error) {
|
||||
func (p DocumentVersionSignatureOrderField) MarshalText() ([]byte, error) {
|
||||
return []byte(p.String()), nil
|
||||
}
|
||||
|
||||
func (p *PolicyVersionSignatureOrderField) UnmarshalText(text []byte) error {
|
||||
*p = PolicyVersionSignatureOrderField(text)
|
||||
func (p *DocumentVersionSignatureOrderField) UnmarshalText(text []byte) error {
|
||||
*p = DocumentVersionSignatureOrderField(text)
|
||||
return nil
|
||||
}
|
||||
@@ -20,57 +20,57 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyVersionSignatureState string
|
||||
DocumentVersionSignatureState string
|
||||
)
|
||||
|
||||
const (
|
||||
PolicyVersionSignatureStateRequested PolicyVersionSignatureState = "REQUESTED"
|
||||
PolicyVersionSignatureStateSigned PolicyVersionSignatureState = "SIGNED"
|
||||
DocumentVersionSignatureStateRequested DocumentVersionSignatureState = "REQUESTED"
|
||||
DocumentVersionSignatureStateSigned DocumentVersionSignatureState = "SIGNED"
|
||||
)
|
||||
|
||||
func (pvs PolicyVersionSignatureState) MarshalText() ([]byte, error) {
|
||||
func (pvs DocumentVersionSignatureState) MarshalText() ([]byte, error) {
|
||||
return []byte(pvs.String()), nil
|
||||
}
|
||||
|
||||
func (pvs *PolicyVersionSignatureState) UnmarshalText(data []byte) error {
|
||||
func (pvs *DocumentVersionSignatureState) UnmarshalText(data []byte) error {
|
||||
val := string(data)
|
||||
|
||||
switch val {
|
||||
case PolicyVersionSignatureStateRequested.String():
|
||||
*pvs = PolicyVersionSignatureStateRequested
|
||||
case PolicyVersionSignatureStateSigned.String():
|
||||
*pvs = PolicyVersionSignatureStateSigned
|
||||
case DocumentVersionSignatureStateRequested.String():
|
||||
*pvs = DocumentVersionSignatureStateRequested
|
||||
case DocumentVersionSignatureStateSigned.String():
|
||||
*pvs = DocumentVersionSignatureStateSigned
|
||||
default:
|
||||
return fmt.Errorf("invalid PolicyVersionSignatureState value: %q", val)
|
||||
return fmt.Errorf("invalid DocumentVersionSignatureState value: %q", val)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvs PolicyVersionSignatureState) String() string {
|
||||
func (pvs DocumentVersionSignatureState) String() string {
|
||||
var val string
|
||||
|
||||
switch pvs {
|
||||
case PolicyVersionSignatureStateRequested:
|
||||
case DocumentVersionSignatureStateRequested:
|
||||
val = "REQUESTED"
|
||||
case PolicyVersionSignatureStateSigned:
|
||||
case DocumentVersionSignatureStateSigned:
|
||||
val = "SIGNED"
|
||||
default:
|
||||
panic(fmt.Errorf("invalid PolicyVersionSignatureState value: %q", string(pvs)))
|
||||
panic(fmt.Errorf("invalid DocumentVersionSignatureState value: %q", string(pvs)))
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
func (pvs *PolicyVersionSignatureState) Scan(value any) error {
|
||||
func (pvs *DocumentVersionSignatureState) Scan(value any) error {
|
||||
val, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid scan source for PolicyVersionSignatureState, expected string got %T", value)
|
||||
return fmt.Errorf("invalid scan source for DocumentVersionSignatureState, expected string got %T", value)
|
||||
}
|
||||
|
||||
return pvs.UnmarshalText([]byte(val))
|
||||
}
|
||||
|
||||
func (pvs PolicyVersionSignatureState) Value() (driver.Value, error) {
|
||||
func (pvs DocumentVersionSignatureState) Value() (driver.Value, error) {
|
||||
return pvs.String(), nil
|
||||
}
|
||||
@@ -25,12 +25,12 @@ const (
|
||||
VendorEntityType
|
||||
PeopleEntityType
|
||||
VendorComplianceReportEntityType
|
||||
PolicyEntityType
|
||||
DocumentEntityType
|
||||
UserEntityType
|
||||
SessionEntityType
|
||||
EmailEntityType
|
||||
ControlEntityType
|
||||
RiskEntityType
|
||||
PolicyVersionEntityType
|
||||
PolicyVersionSignatureEntityType
|
||||
DocumentVersionEntityType
|
||||
DocumentVersionSignatureEntityType
|
||||
)
|
||||
|
||||
36
pkg/coredata/migrations/20250530T033915Z.sql
Normal file
36
pkg/coredata/migrations/20250530T033915Z.sql
Normal file
@@ -0,0 +1,36 @@
|
||||
-- Rename policies table to documents
|
||||
ALTER TABLE policies RENAME TO documents;
|
||||
|
||||
-- Rename risks_policies table to risks_documents
|
||||
ALTER TABLE risks_policies RENAME TO risks_documents;
|
||||
|
||||
-- Update the foreign key reference in risks_documents
|
||||
ALTER TABLE risks_documents RENAME CONSTRAINT risks_policies_policy_id_fkey TO risks_documents_document_id_fkey;
|
||||
|
||||
-- Rename the policy_id column in risks_documents to document_id
|
||||
ALTER TABLE risks_documents RENAME COLUMN policy_id TO document_id;
|
||||
|
||||
-- Rename controls_policies table to controls_documents
|
||||
ALTER TABLE controls_policies RENAME TO controls_documents;
|
||||
|
||||
-- Update controls_documents foreign key and column
|
||||
ALTER TABLE controls_documents RENAME COLUMN policy_id TO document_id;
|
||||
ALTER TABLE controls_documents RENAME CONSTRAINT controls_policies_policy_id_fkey TO controls_documents_document_id_fkey;
|
||||
|
||||
-- Rename policy_versions table to document_versions
|
||||
ALTER TABLE policy_versions RENAME TO document_versions;
|
||||
|
||||
-- Update document_versions foreign key and column
|
||||
ALTER TABLE document_versions RENAME COLUMN policy_id TO document_id;
|
||||
ALTER TABLE document_versions RENAME CONSTRAINT policy_versions_policy_id_fkey TO document_versions_document_id_fkey;
|
||||
|
||||
-- Rename policy_version_signatures table to document_version_signatures
|
||||
ALTER TABLE policy_version_signatures RENAME TO document_version_signatures;
|
||||
|
||||
-- Update document_version_signatures foreign key and column
|
||||
ALTER TABLE document_version_signatures RENAME COLUMN policy_version_id TO document_version_id;
|
||||
ALTER TABLE document_version_signatures RENAME CONSTRAINT policy_version_signatures_policy_version_id_fkey TO document_version_signatures_document_version_id_fkey;
|
||||
|
||||
-- Rename the unique index, preserving the WHERE clause
|
||||
DROP INDEX policy_one_draft_version_idx;
|
||||
CREATE UNIQUE INDEX document_one_draft_version_idx ON document_versions (document_id, status) WHERE status = 'DRAFT';
|
||||
@@ -1,281 +0,0 @@
|
||||
// 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 (
|
||||
"context"
|
||||
"fmt"
|
||||
"maps"
|
||||
"time"
|
||||
|
||||
"github.com/getprobo/probo/pkg/gid"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"go.gearno.de/kit/pg"
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyVersionSignature struct {
|
||||
ID gid.GID `json:"id"`
|
||||
PolicyVersionID gid.GID `json:"policy_version_id"`
|
||||
State PolicyVersionSignatureState `json:"state"`
|
||||
SignedBy gid.GID `json:"signed_by"`
|
||||
SignedAt *time.Time `json:"signed_at"`
|
||||
RequestedAt time.Time `json:"requested_at"`
|
||||
RequestedBy gid.GID `json:"requested_by"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
PolicyVersionSignatures []*PolicyVersionSignature
|
||||
)
|
||||
|
||||
func (pvs PolicyVersionSignature) CursorKey(orderBy PolicyVersionSignatureOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case PolicyVersionSignatureOrderFieldCreatedAt:
|
||||
return page.NewCursorKey(pvs.ID, pvs.CreatedAt)
|
||||
case PolicyVersionSignatureOrderFieldSignedAt:
|
||||
return page.NewCursorKey(pvs.ID, pvs.SignedAt)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (pvs *PolicyVersionSignature) LoadByPolicyVersionIDAndSignatory(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyVersionID gid.GID,
|
||||
signatory gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
policy_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policy_version_signatures
|
||||
WHERE
|
||||
%s
|
||||
AND policy_version_id = @policy_version_id
|
||||
AND signed_by = @signatory
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"policy_version_id": policyVersionID, "signatory": signatory}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policy version signature: %w", err)
|
||||
}
|
||||
|
||||
policyVersionSignature, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[PolicyVersionSignature])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy version signature: %w", err)
|
||||
}
|
||||
|
||||
*pvs = policyVersionSignature
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvs *PolicyVersionSignature) LoadByID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
signatureID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
policy_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policy_version_signatures
|
||||
WHERE
|
||||
id = @policy_version_signature_id
|
||||
AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"policy_version_signature_id": signatureID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policy version signature: %w", err)
|
||||
}
|
||||
|
||||
policyVersionSignature, err := pgx.CollectOneRow(rows, pgx.RowToStructByName[PolicyVersionSignature])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy version signature: %w", err)
|
||||
}
|
||||
|
||||
*pvs = policyVersionSignature
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvs PolicyVersionSignature) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO policy_version_signatures (
|
||||
id,
|
||||
tenant_id,
|
||||
policy_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
) VALUES (
|
||||
@id,
|
||||
@tenant_id,
|
||||
@policy_version_id,
|
||||
@state,
|
||||
@signed_by,
|
||||
@signed_at,
|
||||
@requested_at,
|
||||
@requested_by,
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": pvs.ID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"policy_version_id": pvs.PolicyVersionID,
|
||||
"state": pvs.State,
|
||||
"signed_by": pvs.SignedBy,
|
||||
"signed_at": pvs.SignedAt,
|
||||
"requested_at": pvs.RequestedAt,
|
||||
"requested_by": pvs.RequestedBy,
|
||||
"created_at": pvs.CreatedAt,
|
||||
"updated_at": pvs.UpdatedAt,
|
||||
}
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert policy version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvss *PolicyVersionSignatures) LoadByPolicyVersionID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
policyVersionID gid.GID,
|
||||
cursor *page.Cursor[PolicyVersionSignatureOrderField],
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
policy_version_id,
|
||||
state,
|
||||
signed_by,
|
||||
signed_at,
|
||||
requested_at,
|
||||
requested_by,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
policy_version_signatures
|
||||
WHERE
|
||||
%s
|
||||
AND policy_version_id = @policy_version_id
|
||||
AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"policy_version_id": policyVersionID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
maps.Copy(args, cursor.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policy version signatures: %w", err)
|
||||
}
|
||||
|
||||
policyVersionSignatures, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[PolicyVersionSignature])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect policy version signatures: %w", err)
|
||||
}
|
||||
|
||||
*pvss = policyVersionSignatures
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvs *PolicyVersionSignature) Update(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
UPDATE policy_version_signatures
|
||||
SET
|
||||
state = @state,
|
||||
signed_by = @signed_by,
|
||||
signed_at = @signed_at,
|
||||
updated_at = @updated_at
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": pvs.ID,
|
||||
"state": pvs.State,
|
||||
"signed_by": pvs.SignedBy,
|
||||
"signed_at": pvs.SignedAt,
|
||||
"updated_at": pvs.UpdatedAt,
|
||||
}
|
||||
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update policy version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -26,69 +26,69 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
RiskPolicy struct {
|
||||
RiskID gid.GID `db:"risk_id"`
|
||||
PolicyID gid.GID `db:"policy_id"`
|
||||
TenantID gid.TenantID `db:"tenant_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
RiskDocument struct {
|
||||
RiskID gid.GID `db:"risk_id"`
|
||||
DocumentID gid.GID `db:"document_id"`
|
||||
TenantID gid.TenantID `db:"tenant_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
}
|
||||
|
||||
RiskPolicies []*RiskPolicy
|
||||
RiskDocuments []*RiskDocument
|
||||
)
|
||||
|
||||
func (rp RiskPolicy) Insert(
|
||||
func (rp RiskDocument) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO
|
||||
risks_policies (
|
||||
risks_documents (
|
||||
risk_id,
|
||||
policy_id,
|
||||
document_id,
|
||||
tenant_id,
|
||||
created_at
|
||||
)
|
||||
VALUES (
|
||||
@risk_id,
|
||||
@policy_id,
|
||||
@document_id,
|
||||
@tenant_id,
|
||||
@created_at
|
||||
);
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"risk_id": rp.RiskID,
|
||||
"policy_id": rp.PolicyID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"created_at": rp.CreatedAt,
|
||||
"risk_id": rp.RiskID,
|
||||
"document_id": rp.DocumentID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"created_at": rp.CreatedAt,
|
||||
}
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (rp RiskPolicy) Delete(
|
||||
func (rp RiskDocument) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
riskID gid.GID,
|
||||
policyID gid.GID,
|
||||
documentID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
DELETE
|
||||
FROM
|
||||
risks_policies
|
||||
risks_documents
|
||||
WHERE
|
||||
%s
|
||||
AND risk_id = @risk_id
|
||||
AND policy_id = @policy_id;
|
||||
AND document_id = @document_id;
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"risk_id": riskID,
|
||||
"policy_id": policyID,
|
||||
"risk_id": riskID,
|
||||
"document_id": documentID,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
@@ -55,22 +55,22 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func (s ControlService) ListForPolicyID(
|
||||
func (s ControlService) ListForDocumentID(
|
||||
ctx context.Context,
|
||||
policyID gid.GID,
|
||||
documentID gid.GID,
|
||||
cursor *page.Cursor[coredata.ControlOrderField],
|
||||
) (*page.Page[*coredata.Control, coredata.ControlOrderField], error) {
|
||||
var controls coredata.Controls
|
||||
policy := &coredata.Policy{}
|
||||
document := &coredata.Document{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := policy.LoadByID(ctx, conn, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load policy: %w", err)
|
||||
if err := document.LoadByID(ctx, conn, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load document: %w", err)
|
||||
}
|
||||
|
||||
return controls.LoadByPolicyID(ctx, conn, s.svc.scope, policyID, cursor)
|
||||
return controls.LoadByDocumentID(ctx, conn, s.svc.scope, documentID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -179,13 +179,13 @@ func (s ControlService) DeleteMeasureMapping(
|
||||
return control, measure, nil
|
||||
}
|
||||
|
||||
func (s ControlService) CreatePolicyMapping(
|
||||
func (s ControlService) CreateDocumentMapping(
|
||||
ctx context.Context,
|
||||
controlID gid.GID,
|
||||
policyID gid.GID,
|
||||
) (*coredata.Control, *coredata.Policy, error) {
|
||||
documentID gid.GID,
|
||||
) (*coredata.Control, *coredata.Document, error) {
|
||||
control := &coredata.Control{}
|
||||
policy := &coredata.Policy{}
|
||||
document := &coredata.Document{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
@@ -194,19 +194,19 @@ func (s ControlService) CreatePolicyMapping(
|
||||
return fmt.Errorf("cannot load control: %w", err)
|
||||
}
|
||||
|
||||
if err := policy.LoadByID(ctx, conn, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load policy: %w", err)
|
||||
if err := document.LoadByID(ctx, conn, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load document: %w", err)
|
||||
}
|
||||
|
||||
controlPolicy := &coredata.ControlPolicy{
|
||||
ControlID: control.ID,
|
||||
PolicyID: policy.ID,
|
||||
TenantID: s.svc.scope.GetTenantID(),
|
||||
CreatedAt: time.Now(),
|
||||
controlDocument := &coredata.ControlDocument{
|
||||
ControlID: control.ID,
|
||||
DocumentID: document.ID,
|
||||
TenantID: s.svc.scope.GetTenantID(),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
if err := controlPolicy.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot insert control policy: %w", err)
|
||||
if err := controlDocument.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot insert control document: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -214,19 +214,19 @@ func (s ControlService) CreatePolicyMapping(
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot create control policy mapping: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot create control document mapping: %w", err)
|
||||
}
|
||||
|
||||
return control, policy, nil
|
||||
return control, document, nil
|
||||
}
|
||||
|
||||
func (s ControlService) DeletePolicyMapping(
|
||||
func (s ControlService) DeleteDocumentMapping(
|
||||
ctx context.Context,
|
||||
controlID gid.GID,
|
||||
policyID gid.GID,
|
||||
) (*coredata.Control, *coredata.Policy, error) {
|
||||
documentID gid.GID,
|
||||
) (*coredata.Control, *coredata.Document, error) {
|
||||
control := &coredata.Control{}
|
||||
policy := &coredata.Policy{}
|
||||
document := &coredata.Document{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
@@ -235,13 +235,13 @@ func (s ControlService) DeletePolicyMapping(
|
||||
return fmt.Errorf("cannot load control: %w", err)
|
||||
}
|
||||
|
||||
if err := policy.LoadByID(ctx, conn, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load policy: %w", err)
|
||||
if err := document.LoadByID(ctx, conn, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load document: %w", err)
|
||||
}
|
||||
|
||||
controlPolicy := &coredata.ControlPolicy{}
|
||||
if err := controlPolicy.Delete(ctx, conn, s.svc.scope, control.ID, policy.ID); err != nil {
|
||||
return fmt.Errorf("cannot delete control policy mapping: %w", err)
|
||||
controlDocument := &coredata.ControlDocument{}
|
||||
if err := controlDocument.Delete(ctx, conn, s.svc.scope, control.ID, document.ID); err != nil {
|
||||
return fmt.Errorf("cannot delete control document mapping: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -249,10 +249,10 @@ func (s ControlService) DeletePolicyMapping(
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot delete control policy mapping: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot delete control document mapping: %w", err)
|
||||
}
|
||||
|
||||
return control, policy, nil
|
||||
return control, document, nil
|
||||
}
|
||||
|
||||
func (s ControlService) Create(
|
||||
|
||||
634
pkg/probo/document_service.go
Normal file
634
pkg/probo/document_service.go
Normal file
@@ -0,0 +1,634 @@
|
||||
package probo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/getprobo/probo/pkg/coredata"
|
||||
"github.com/getprobo/probo/pkg/gid"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
"github.com/getprobo/probo/pkg/statelesstoken"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"go.gearno.de/kit/pg"
|
||||
)
|
||||
|
||||
type (
|
||||
DocumentService struct {
|
||||
svc *TenantService
|
||||
}
|
||||
|
||||
CreateDocumentRequest struct {
|
||||
OrganizationID gid.GID
|
||||
Title string
|
||||
Content string
|
||||
OwnerID gid.GID
|
||||
CreatedBy gid.GID
|
||||
}
|
||||
|
||||
UpdateDocumentVersionRequest struct {
|
||||
ID gid.GID
|
||||
Content string
|
||||
}
|
||||
|
||||
RequestSignatureRequest struct {
|
||||
DocumentVersionID gid.GID
|
||||
RequestedBy gid.GID
|
||||
Signatory gid.GID
|
||||
}
|
||||
|
||||
SigningRequestData struct {
|
||||
OrganizationID gid.GID `json:"organization_id"`
|
||||
PeopleID gid.GID `json:"people_id"`
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
TokenTypeSigningRequest = "signing_request"
|
||||
)
|
||||
|
||||
func (s *DocumentService) Get(
|
||||
ctx context.Context,
|
||||
documentID gid.GID,
|
||||
) (*coredata.Document, error) {
|
||||
document := &coredata.Document{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return document.LoadByID(ctx, conn, s.svc.scope, documentID)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return document, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) PublishVersion(
|
||||
ctx context.Context,
|
||||
documentID gid.GID,
|
||||
publishedBy gid.GID,
|
||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||
document := &coredata.Document{}
|
||||
documentVersion := &coredata.DocumentVersion{}
|
||||
now := time.Now()
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(tx pg.Conn) error {
|
||||
if err := document.LoadByID(ctx, tx, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load document %q: %w", documentID, err)
|
||||
}
|
||||
|
||||
if err := documentVersion.LoadLatestVersion(ctx, tx, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load current draft: %w", err)
|
||||
}
|
||||
|
||||
if documentVersion.Status != coredata.DocumentStatusDraft {
|
||||
return fmt.Errorf("cannot publish version")
|
||||
}
|
||||
|
||||
document.CurrentPublishedVersion = &documentVersion.VersionNumber
|
||||
document.UpdatedAt = now
|
||||
|
||||
documentVersion.Status = coredata.DocumentStatusPublished
|
||||
documentVersion.PublishedAt = &now
|
||||
documentVersion.PublishedBy = &publishedBy
|
||||
documentVersion.UpdatedAt = now
|
||||
|
||||
if err := document.Update(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update document: %w", err)
|
||||
}
|
||||
|
||||
if err := documentVersion.Update(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update document version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return document, documentVersion, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) Create(
|
||||
ctx context.Context,
|
||||
req CreateDocumentRequest,
|
||||
) (*coredata.Document, *coredata.DocumentVersion, error) {
|
||||
now := time.Now()
|
||||
documentID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentEntityType)
|
||||
documentVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||
|
||||
organization := &coredata.Organization{}
|
||||
people := &coredata.People{}
|
||||
|
||||
document := &coredata.Document{
|
||||
ID: documentID,
|
||||
Title: req.Title,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
documentVersion := &coredata.DocumentVersion{
|
||||
ID: documentVersionID,
|
||||
DocumentID: documentID,
|
||||
VersionNumber: 1,
|
||||
Content: req.Content,
|
||||
Status: coredata.DocumentStatusDraft,
|
||||
CreatedBy: req.CreatedBy,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := organization.LoadByID(ctx, conn, s.svc.scope, req.OrganizationID); err != nil {
|
||||
return fmt.Errorf("cannot load organization: %w", err)
|
||||
}
|
||||
|
||||
if err := people.LoadByID(ctx, conn, s.svc.scope, req.OwnerID); err != nil {
|
||||
return fmt.Errorf("cannot load people: %w", err)
|
||||
}
|
||||
|
||||
document.OrganizationID = organization.ID
|
||||
document.OwnerID = people.ID
|
||||
|
||||
if err := document.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot insert document: %w", err)
|
||||
}
|
||||
|
||||
if err := documentVersion.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot create document version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return document, documentVersion, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) ListSigningRequests(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
peopleID gid.GID,
|
||||
) ([]map[string]any, error) {
|
||||
q := `
|
||||
SELECT
|
||||
p.title,
|
||||
pv.content,
|
||||
pv.id AS document_version_id
|
||||
FROM
|
||||
documents p
|
||||
INNER JOIN document_versions pv ON pv.document_id = p.id
|
||||
INNER JOIN document_version_signatures pvs ON pvs.document_version_id = pv.id
|
||||
WHERE
|
||||
p.tenant_id = $1
|
||||
AND pvs.signed_by = $2
|
||||
AND pvs.signed_at IS NULL
|
||||
`
|
||||
|
||||
var results []map[string]any
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
rows, err := conn.Query(ctx, q, s.svc.scope.GetTenantID(), peopleID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query documents: %w", err)
|
||||
}
|
||||
|
||||
results, err = pgx.CollectRows(rows, pgx.RowToMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) SendSigningNotifications(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
) error {
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(tx pg.Conn) error {
|
||||
var peoples coredata.Peoples
|
||||
if err := peoples.LoadAwaitingSigning(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot load people: %w", err)
|
||||
}
|
||||
|
||||
for _, people := range peoples {
|
||||
now := time.Now()
|
||||
|
||||
emailID := gid.New(s.svc.scope.GetTenantID(), coredata.EmailEntityType)
|
||||
|
||||
token, err := statelesstoken.NewToken(
|
||||
s.svc.tokenSecret,
|
||||
TokenTypeSigningRequest,
|
||||
time.Hour*24*7,
|
||||
SigningRequestData{
|
||||
OrganizationID: organizationID,
|
||||
PeopleID: people.ID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create signing request token: %w", err)
|
||||
}
|
||||
|
||||
signRequestURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: s.svc.hostname,
|
||||
Path: "/documents/signing-requests",
|
||||
RawQuery: url.Values{
|
||||
"token": []string{token},
|
||||
}.Encode(),
|
||||
}
|
||||
|
||||
email := &coredata.Email{
|
||||
ID: emailID,
|
||||
RecipientEmail: people.PrimaryEmailAddress,
|
||||
RecipientName: people.FullName,
|
||||
Subject: "Probo - Documents Signing Request",
|
||||
TextBody: fmt.Sprintf("Hi,\nYou have documents awaiting your signature. Please follow this link to sign them: %s", signRequestURL.String()),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
if err := email.Insert(ctx, tx); err != nil {
|
||||
return fmt.Errorf("cannot insert email: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot send signing notifications: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) SignDocumentVersion(
|
||||
ctx context.Context,
|
||||
documentVersionID gid.GID,
|
||||
signatory gid.GID,
|
||||
) error {
|
||||
documentVersion := &coredata.DocumentVersion{}
|
||||
documentVersionSignature := &coredata.DocumentVersionSignature{}
|
||||
now := time.Now()
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := documentVersion.LoadByID(ctx, conn, s.svc.scope, documentVersionID); err != nil {
|
||||
return fmt.Errorf("cannot load document version %q: %w", documentVersionID, err)
|
||||
}
|
||||
|
||||
if documentVersion.Status != coredata.DocumentStatusPublished {
|
||||
return fmt.Errorf("cannot sign unpublished version")
|
||||
}
|
||||
|
||||
if err := documentVersionSignature.LoadByDocumentVersionIDAndSignatory(ctx, conn, s.svc.scope, documentVersionID, signatory); err != nil {
|
||||
return fmt.Errorf("cannot load document version signature: %w", err)
|
||||
}
|
||||
|
||||
if documentVersionSignature.State == coredata.DocumentVersionSignatureStateSigned {
|
||||
return fmt.Errorf("document version already signed")
|
||||
}
|
||||
|
||||
documentVersionSignature.State = coredata.DocumentVersionSignatureStateSigned
|
||||
documentVersionSignature.SignedAt = &now
|
||||
documentVersionSignature.UpdatedAt = now
|
||||
|
||||
if err := documentVersion.Update(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update document version: %w", err)
|
||||
}
|
||||
|
||||
if err := documentVersionSignature.Update(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update document version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot sign document version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) UpdateVersion(
|
||||
ctx context.Context,
|
||||
req UpdateDocumentVersionRequest,
|
||||
) (*coredata.DocumentVersion, error) {
|
||||
documentVersion := &coredata.DocumentVersion{}
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := documentVersion.LoadByID(ctx, conn, s.svc.scope, req.ID); err != nil {
|
||||
return fmt.Errorf("cannot load document version %q: %w", req.ID, err)
|
||||
}
|
||||
|
||||
if documentVersion.Status != coredata.DocumentStatusDraft {
|
||||
return fmt.Errorf("cannot update published version")
|
||||
}
|
||||
|
||||
documentVersion.Content = req.Content
|
||||
documentVersion.UpdatedAt = time.Now()
|
||||
|
||||
if err := documentVersion.Update(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update document version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return documentVersion, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) GetVersionSignature(
|
||||
ctx context.Context,
|
||||
signatureID gid.GID,
|
||||
) (*coredata.DocumentVersionSignature, error) {
|
||||
documentVersionSignature := &coredata.DocumentVersionSignature{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return documentVersionSignature.LoadByID(ctx, conn, s.svc.scope, signatureID)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return documentVersionSignature, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) RequestSignature(
|
||||
ctx context.Context,
|
||||
req RequestSignatureRequest,
|
||||
) (*coredata.DocumentVersionSignature, error) {
|
||||
documentVersionSignatureID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionSignatureEntityType)
|
||||
|
||||
documentVersion, err := s.GetVersion(ctx, req.DocumentVersionID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get document version: %w", err)
|
||||
}
|
||||
|
||||
if documentVersion.Status != coredata.DocumentStatusPublished {
|
||||
return nil, fmt.Errorf("cannot request signature for unpublished version")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
documentVersionSignature := &coredata.DocumentVersionSignature{
|
||||
ID: documentVersionSignatureID,
|
||||
DocumentVersionID: req.DocumentVersionID,
|
||||
State: coredata.DocumentVersionSignatureStateRequested,
|
||||
RequestedBy: req.RequestedBy,
|
||||
RequestedAt: now,
|
||||
SignedBy: req.Signatory,
|
||||
SignedAt: nil,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
err = s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := documentVersionSignature.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot insert document version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return documentVersionSignature, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) ListSignatures(
|
||||
ctx context.Context,
|
||||
documentVersionID gid.GID,
|
||||
cursor *page.Cursor[coredata.DocumentVersionSignatureOrderField],
|
||||
) (*page.Page[*coredata.DocumentVersionSignature, coredata.DocumentVersionSignatureOrderField], error) {
|
||||
var documentVersionSignatures coredata.DocumentVersionSignatures
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return documentVersionSignatures.LoadByDocumentVersionID(ctx, conn, s.svc.scope, documentVersionID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(documentVersionSignatures, cursor), nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) CreateDraft(
|
||||
ctx context.Context,
|
||||
documentID gid.GID,
|
||||
createdBy gid.GID,
|
||||
) (*coredata.DocumentVersion, error) {
|
||||
draftVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
|
||||
|
||||
latestVersion := &coredata.DocumentVersion{}
|
||||
draftVersion := &coredata.DocumentVersion{}
|
||||
now := time.Now()
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := latestVersion.LoadLatestVersion(ctx, conn, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load latest version: %w", err)
|
||||
}
|
||||
|
||||
if latestVersion.Status != coredata.DocumentStatusPublished {
|
||||
return fmt.Errorf("cannot create draft from unpublished version")
|
||||
}
|
||||
|
||||
draftVersion.ID = draftVersionID
|
||||
draftVersion.DocumentID = documentID
|
||||
draftVersion.VersionNumber = latestVersion.VersionNumber + 1
|
||||
draftVersion.Content = latestVersion.Content
|
||||
draftVersion.Status = coredata.DocumentStatusDraft
|
||||
draftVersion.CreatedBy = createdBy
|
||||
draftVersion.CreatedAt = now
|
||||
draftVersion.UpdatedAt = now
|
||||
|
||||
if err := draftVersion.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot create draft: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return draftVersion, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) Delete(
|
||||
ctx context.Context,
|
||||
documentID gid.GID,
|
||||
) error {
|
||||
document := coredata.Document{ID: documentID}
|
||||
|
||||
return s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return document.Delete(ctx, conn, s.svc.scope)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (s *DocumentService) ListVersions(
|
||||
ctx context.Context,
|
||||
documentID gid.GID,
|
||||
cursor *page.Cursor[coredata.DocumentVersionOrderField],
|
||||
) (*page.Page[*coredata.DocumentVersion, coredata.DocumentVersionOrderField], error) {
|
||||
var documentVersions coredata.DocumentVersions
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return documentVersions.LoadByDocumentID(ctx, conn, s.svc.scope, documentID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(documentVersions, cursor), nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) GetVersion(
|
||||
ctx context.Context,
|
||||
documentVersionID gid.GID,
|
||||
) (*coredata.DocumentVersion, error) {
|
||||
documentVersion := &coredata.DocumentVersion{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return documentVersion.LoadByID(ctx, conn, s.svc.scope, documentVersionID)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return documentVersion, nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) ListByOrganizationID(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
cursor *page.Cursor[coredata.DocumentOrderField],
|
||||
) (*page.Page[*coredata.Document, coredata.DocumentOrderField], error) {
|
||||
var documents coredata.Documents
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return documents.LoadByOrganizationID(
|
||||
ctx,
|
||||
conn,
|
||||
s.svc.scope,
|
||||
organizationID,
|
||||
cursor,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(documents, cursor), nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) ListForControlID(
|
||||
ctx context.Context,
|
||||
controlID gid.GID,
|
||||
cursor *page.Cursor[coredata.DocumentOrderField],
|
||||
) (*page.Page[*coredata.Document, coredata.DocumentOrderField], error) {
|
||||
var documents coredata.Documents
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return documents.LoadByControlID(ctx, conn, s.svc.scope, controlID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(documents, cursor), nil
|
||||
}
|
||||
|
||||
func (s *DocumentService) ListForRiskID(
|
||||
ctx context.Context,
|
||||
riskID gid.GID,
|
||||
cursor *page.Cursor[coredata.DocumentOrderField],
|
||||
) (*page.Page[*coredata.Document, coredata.DocumentOrderField], error) {
|
||||
var documents coredata.Documents
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return documents.LoadByRiskID(ctx, conn, s.svc.scope, riskID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(documents, cursor), nil
|
||||
}
|
||||
@@ -327,36 +327,36 @@ func (s FrameworkService) ExportAudit(
|
||||
return fmt.Errorf("cannot load measures: %w", err)
|
||||
}
|
||||
|
||||
policies := coredata.Policies{}
|
||||
documents := coredata.Documents{}
|
||||
|
||||
cursor2 := page.NewCursor(
|
||||
0,
|
||||
nil,
|
||||
page.Head,
|
||||
page.OrderBy[coredata.PolicyOrderField]{
|
||||
Field: coredata.PolicyOrderFieldCreatedAt,
|
||||
page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
},
|
||||
)
|
||||
|
||||
if err := policies.LoadByControlID(ctx, conn, s.svc.scope, control.ID, cursor2); err != nil {
|
||||
return fmt.Errorf("cannot load policies: %w", err)
|
||||
if err := documents.LoadByControlID(ctx, conn, s.svc.scope, control.ID, cursor2); err != nil {
|
||||
return fmt.Errorf("cannot load documents: %w", err)
|
||||
}
|
||||
|
||||
for _, policy := range policies {
|
||||
policyDir := filepath.Join(controlDir, policy.Title)
|
||||
if err := os.MkdirAll(policyDir, 0755); err != nil {
|
||||
return fmt.Errorf("cannot create policy directory: %w", err)
|
||||
for _, document := range documents {
|
||||
documentDir := filepath.Join(controlDir, document.Title)
|
||||
if err := os.MkdirAll(documentDir, 0755); err != nil {
|
||||
return fmt.Errorf("cannot create document directory: %w", err)
|
||||
}
|
||||
|
||||
version := coredata.PolicyVersion{}
|
||||
if err := version.LoadLatestVersion(ctx, conn, s.svc.scope, policy.ID); err != nil {
|
||||
return fmt.Errorf("cannot load policy version: %w", err)
|
||||
version := coredata.DocumentVersion{}
|
||||
if err := version.LoadLatestVersion(ctx, conn, s.svc.scope, document.ID); err != nil {
|
||||
return fmt.Errorf("cannot load document version: %w", err)
|
||||
}
|
||||
|
||||
policyFile := filepath.Join(policyDir, "policy.md")
|
||||
if err := os.WriteFile(policyFile, []byte(version.Content), 0644); err != nil {
|
||||
return fmt.Errorf("cannot write policy file: %w", err)
|
||||
documentFile := filepath.Join(documentDir, "document.md")
|
||||
if err := os.WriteFile(documentFile, []byte(version.Content), 0644); err != nil {
|
||||
return fmt.Errorf("cannot write document file: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,634 +0,0 @@
|
||||
package probo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/getprobo/probo/pkg/coredata"
|
||||
"github.com/getprobo/probo/pkg/gid"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
"github.com/getprobo/probo/pkg/statelesstoken"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"go.gearno.de/kit/pg"
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyService struct {
|
||||
svc *TenantService
|
||||
}
|
||||
|
||||
CreatePolicyRequest struct {
|
||||
OrganizationID gid.GID
|
||||
Title string
|
||||
Content string
|
||||
OwnerID gid.GID
|
||||
CreatedBy gid.GID
|
||||
}
|
||||
|
||||
UpdatePolicyVersionRequest struct {
|
||||
ID gid.GID
|
||||
Content string
|
||||
}
|
||||
|
||||
RequestSignatureRequest struct {
|
||||
PolicyVersionID gid.GID
|
||||
RequestedBy gid.GID
|
||||
Signatory gid.GID
|
||||
}
|
||||
|
||||
SigningRequestData struct {
|
||||
OrganizationID gid.GID `json:"organization_id"`
|
||||
PeopleID gid.GID `json:"people_id"`
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
TokenTypeSigningRequest = "signing_request"
|
||||
)
|
||||
|
||||
func (s *PolicyService) Get(
|
||||
ctx context.Context,
|
||||
policyID gid.GID,
|
||||
) (*coredata.Policy, error) {
|
||||
policy := &coredata.Policy{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policy.LoadByID(ctx, conn, s.svc.scope, policyID)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) PublishVersion(
|
||||
ctx context.Context,
|
||||
policyID gid.GID,
|
||||
publishedBy gid.GID,
|
||||
) (*coredata.Policy, *coredata.PolicyVersion, error) {
|
||||
policy := &coredata.Policy{}
|
||||
policyVersion := &coredata.PolicyVersion{}
|
||||
now := time.Now()
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(tx pg.Conn) error {
|
||||
if err := policy.LoadByID(ctx, tx, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load policy %q: %w", policyID, err)
|
||||
}
|
||||
|
||||
if err := policyVersion.LoadLatestVersion(ctx, tx, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load current draft: %w", err)
|
||||
}
|
||||
|
||||
if policyVersion.Status != coredata.PolicyStatusDraft {
|
||||
return fmt.Errorf("cannot publish version")
|
||||
}
|
||||
|
||||
policy.CurrentPublishedVersion = &policyVersion.VersionNumber
|
||||
policy.UpdatedAt = now
|
||||
|
||||
policyVersion.Status = coredata.PolicyStatusPublished
|
||||
policyVersion.PublishedAt = &now
|
||||
policyVersion.PublishedBy = &publishedBy
|
||||
policyVersion.UpdatedAt = now
|
||||
|
||||
if err := policy.Update(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update policy: %w", err)
|
||||
}
|
||||
|
||||
if err := policyVersion.Update(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update policy version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return policy, policyVersion, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) Create(
|
||||
ctx context.Context,
|
||||
req CreatePolicyRequest,
|
||||
) (*coredata.Policy, *coredata.PolicyVersion, error) {
|
||||
now := time.Now()
|
||||
policyID := gid.New(s.svc.scope.GetTenantID(), coredata.PolicyEntityType)
|
||||
policyVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.PolicyVersionEntityType)
|
||||
|
||||
organization := &coredata.Organization{}
|
||||
people := &coredata.People{}
|
||||
|
||||
policy := &coredata.Policy{
|
||||
ID: policyID,
|
||||
Title: req.Title,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
policyVersion := &coredata.PolicyVersion{
|
||||
ID: policyVersionID,
|
||||
PolicyID: policyID,
|
||||
VersionNumber: 1,
|
||||
Content: req.Content,
|
||||
Status: coredata.PolicyStatusDraft,
|
||||
CreatedBy: req.CreatedBy,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := organization.LoadByID(ctx, conn, s.svc.scope, req.OrganizationID); err != nil {
|
||||
return fmt.Errorf("cannot load organization: %w", err)
|
||||
}
|
||||
|
||||
if err := people.LoadByID(ctx, conn, s.svc.scope, req.OwnerID); err != nil {
|
||||
return fmt.Errorf("cannot load people: %w", err)
|
||||
}
|
||||
|
||||
policy.OrganizationID = organization.ID
|
||||
policy.OwnerID = people.ID
|
||||
|
||||
if err := policy.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot insert policy: %w", err)
|
||||
}
|
||||
|
||||
if err := policyVersion.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot create policy version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return policy, policyVersion, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) ListSigningRequests(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
peopleID gid.GID,
|
||||
) ([]map[string]any, error) {
|
||||
q := `
|
||||
SELECT
|
||||
p.title,
|
||||
pv.content,
|
||||
pv.id AS policy_version_id
|
||||
FROM
|
||||
policies p
|
||||
INNER JOIN policy_versions pv ON pv.policy_id = p.id
|
||||
INNER JOIN policy_version_signatures pvs ON pvs.policy_version_id = pv.id
|
||||
WHERE
|
||||
p.tenant_id = $1
|
||||
AND pvs.signed_by = $2
|
||||
AND pvs.signed_at IS NULL
|
||||
`
|
||||
|
||||
var results []map[string]any
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
rows, err := conn.Query(ctx, q, s.svc.scope.GetTenantID(), peopleID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query policies: %w", err)
|
||||
}
|
||||
|
||||
results, err = pgx.CollectRows(rows, pgx.RowToMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) SendSigningNotifications(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
) error {
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(tx pg.Conn) error {
|
||||
var peoples coredata.Peoples
|
||||
if err := peoples.LoadAwaitingSigning(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot load people: %w", err)
|
||||
}
|
||||
|
||||
for _, people := range peoples {
|
||||
now := time.Now()
|
||||
|
||||
emailID := gid.New(s.svc.scope.GetTenantID(), coredata.EmailEntityType)
|
||||
|
||||
token, err := statelesstoken.NewToken(
|
||||
s.svc.tokenSecret,
|
||||
TokenTypeSigningRequest,
|
||||
time.Hour*24*7,
|
||||
SigningRequestData{
|
||||
OrganizationID: organizationID,
|
||||
PeopleID: people.ID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create signing request token: %w", err)
|
||||
}
|
||||
|
||||
signRequestURL := url.URL{
|
||||
Scheme: "https",
|
||||
Host: s.svc.hostname,
|
||||
Path: "/policies/signing-requests",
|
||||
RawQuery: url.Values{
|
||||
"token": []string{token},
|
||||
}.Encode(),
|
||||
}
|
||||
|
||||
email := &coredata.Email{
|
||||
ID: emailID,
|
||||
RecipientEmail: people.PrimaryEmailAddress,
|
||||
RecipientName: people.FullName,
|
||||
Subject: "Probo - Policies Signing Request",
|
||||
TextBody: fmt.Sprintf("Hi,\nYou have documents awaiting your signature. Please follow this link to sign them: %s", signRequestURL.String()),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
if err := email.Insert(ctx, tx); err != nil {
|
||||
return fmt.Errorf("cannot insert email: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot send signing notifications: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) SignPolicyVersion(
|
||||
ctx context.Context,
|
||||
policyVersionID gid.GID,
|
||||
signatory gid.GID,
|
||||
) error {
|
||||
policyVersion := &coredata.PolicyVersion{}
|
||||
policyVersionSignature := &coredata.PolicyVersionSignature{}
|
||||
now := time.Now()
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := policyVersion.LoadByID(ctx, conn, s.svc.scope, policyVersionID); err != nil {
|
||||
return fmt.Errorf("cannot load policy version %q: %w", policyVersionID, err)
|
||||
}
|
||||
|
||||
if policyVersion.Status != coredata.PolicyStatusPublished {
|
||||
return fmt.Errorf("cannot sign unpublished version")
|
||||
}
|
||||
|
||||
if err := policyVersionSignature.LoadByPolicyVersionIDAndSignatory(ctx, conn, s.svc.scope, policyVersionID, signatory); err != nil {
|
||||
return fmt.Errorf("cannot load policy version signature: %w", err)
|
||||
}
|
||||
|
||||
if policyVersionSignature.State == coredata.PolicyVersionSignatureStateSigned {
|
||||
return fmt.Errorf("policy version already signed")
|
||||
}
|
||||
|
||||
policyVersionSignature.State = coredata.PolicyVersionSignatureStateSigned
|
||||
policyVersionSignature.SignedAt = &now
|
||||
policyVersionSignature.UpdatedAt = now
|
||||
|
||||
if err := policyVersion.Update(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update policy version: %w", err)
|
||||
}
|
||||
|
||||
if err := policyVersionSignature.Update(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update policy version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot sign policy version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) UpdateVersion(
|
||||
ctx context.Context,
|
||||
req UpdatePolicyVersionRequest,
|
||||
) (*coredata.PolicyVersion, error) {
|
||||
policyVersion := &coredata.PolicyVersion{}
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := policyVersion.LoadByID(ctx, conn, s.svc.scope, req.ID); err != nil {
|
||||
return fmt.Errorf("cannot load policy version %q: %w", req.ID, err)
|
||||
}
|
||||
|
||||
if policyVersion.Status != coredata.PolicyStatusDraft {
|
||||
return fmt.Errorf("cannot update published version")
|
||||
}
|
||||
|
||||
policyVersion.Content = req.Content
|
||||
policyVersion.UpdatedAt = time.Now()
|
||||
|
||||
if err := policyVersion.Update(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update policy version: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return policyVersion, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) GetVersionSignature(
|
||||
ctx context.Context,
|
||||
signatureID gid.GID,
|
||||
) (*coredata.PolicyVersionSignature, error) {
|
||||
policyVersionSignature := &coredata.PolicyVersionSignature{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policyVersionSignature.LoadByID(ctx, conn, s.svc.scope, signatureID)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return policyVersionSignature, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) RequestSignature(
|
||||
ctx context.Context,
|
||||
req RequestSignatureRequest,
|
||||
) (*coredata.PolicyVersionSignature, error) {
|
||||
policyVersionSignatureID := gid.New(s.svc.scope.GetTenantID(), coredata.PolicyVersionSignatureEntityType)
|
||||
|
||||
policyVersion, err := s.GetVersion(ctx, req.PolicyVersionID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get policy version: %w", err)
|
||||
}
|
||||
|
||||
if policyVersion.Status != coredata.PolicyStatusPublished {
|
||||
return nil, fmt.Errorf("cannot request signature for unpublished version")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
policyVersionSignature := &coredata.PolicyVersionSignature{
|
||||
ID: policyVersionSignatureID,
|
||||
PolicyVersionID: req.PolicyVersionID,
|
||||
State: coredata.PolicyVersionSignatureStateRequested,
|
||||
RequestedBy: req.RequestedBy,
|
||||
RequestedAt: now,
|
||||
SignedBy: req.Signatory,
|
||||
SignedAt: nil,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
err = s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := policyVersionSignature.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot insert policy version signature: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return policyVersionSignature, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) ListSignatures(
|
||||
ctx context.Context,
|
||||
policyVersionID gid.GID,
|
||||
cursor *page.Cursor[coredata.PolicyVersionSignatureOrderField],
|
||||
) (*page.Page[*coredata.PolicyVersionSignature, coredata.PolicyVersionSignatureOrderField], error) {
|
||||
var policyVersionSignatures coredata.PolicyVersionSignatures
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policyVersionSignatures.LoadByPolicyVersionID(ctx, conn, s.svc.scope, policyVersionID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(policyVersionSignatures, cursor), nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) CreateDraft(
|
||||
ctx context.Context,
|
||||
policyID gid.GID,
|
||||
createdBy gid.GID,
|
||||
) (*coredata.PolicyVersion, error) {
|
||||
draftVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.PolicyVersionEntityType)
|
||||
|
||||
latestVersion := &coredata.PolicyVersion{}
|
||||
draftVersion := &coredata.PolicyVersion{}
|
||||
now := time.Now()
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := latestVersion.LoadLatestVersion(ctx, conn, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load latest version: %w", err)
|
||||
}
|
||||
|
||||
if latestVersion.Status != coredata.PolicyStatusPublished {
|
||||
return fmt.Errorf("cannot create draft from unpublished version")
|
||||
}
|
||||
|
||||
draftVersion.ID = draftVersionID
|
||||
draftVersion.PolicyID = policyID
|
||||
draftVersion.VersionNumber = latestVersion.VersionNumber + 1
|
||||
draftVersion.Content = latestVersion.Content
|
||||
draftVersion.Status = coredata.PolicyStatusDraft
|
||||
draftVersion.CreatedBy = createdBy
|
||||
draftVersion.CreatedAt = now
|
||||
draftVersion.UpdatedAt = now
|
||||
|
||||
if err := draftVersion.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot create draft: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return draftVersion, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) Delete(
|
||||
ctx context.Context,
|
||||
policyID gid.GID,
|
||||
) error {
|
||||
policy := coredata.Policy{ID: policyID}
|
||||
|
||||
return s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policy.Delete(ctx, conn, s.svc.scope)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (s *PolicyService) ListVersions(
|
||||
ctx context.Context,
|
||||
policyID gid.GID,
|
||||
cursor *page.Cursor[coredata.PolicyVersionOrderField],
|
||||
) (*page.Page[*coredata.PolicyVersion, coredata.PolicyVersionOrderField], error) {
|
||||
var policyVersions coredata.PolicyVersions
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policyVersions.LoadByPolicyID(ctx, conn, s.svc.scope, policyID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(policyVersions, cursor), nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) GetVersion(
|
||||
ctx context.Context,
|
||||
policyVersionID gid.GID,
|
||||
) (*coredata.PolicyVersion, error) {
|
||||
policyVersion := &coredata.PolicyVersion{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policyVersion.LoadByID(ctx, conn, s.svc.scope, policyVersionID)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return policyVersion, nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) ListByOrganizationID(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
cursor *page.Cursor[coredata.PolicyOrderField],
|
||||
) (*page.Page[*coredata.Policy, coredata.PolicyOrderField], error) {
|
||||
var policies coredata.Policies
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policies.LoadByOrganizationID(
|
||||
ctx,
|
||||
conn,
|
||||
s.svc.scope,
|
||||
organizationID,
|
||||
cursor,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(policies, cursor), nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) ListForControlID(
|
||||
ctx context.Context,
|
||||
controlID gid.GID,
|
||||
cursor *page.Cursor[coredata.PolicyOrderField],
|
||||
) (*page.Page[*coredata.Policy, coredata.PolicyOrderField], error) {
|
||||
var policies coredata.Policies
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policies.LoadByControlID(ctx, conn, s.svc.scope, controlID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(policies, cursor), nil
|
||||
}
|
||||
|
||||
func (s *PolicyService) ListForRiskID(
|
||||
ctx context.Context,
|
||||
riskID gid.GID,
|
||||
cursor *page.Cursor[coredata.PolicyOrderField],
|
||||
) (*page.Page[*coredata.Policy, coredata.PolicyOrderField], error) {
|
||||
var policies coredata.Policies
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
return policies.LoadByRiskID(ctx, conn, s.svc.scope, riskID, cursor)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(policies, cursor), nil
|
||||
}
|
||||
@@ -80,13 +80,13 @@ func (s RiskService) ListForMeasureID(
|
||||
return page.NewPage(risks, cursor), nil
|
||||
}
|
||||
|
||||
func (s RiskService) CreatePolicyMapping(
|
||||
func (s RiskService) CreateDocumentMapping(
|
||||
ctx context.Context,
|
||||
riskID gid.GID,
|
||||
policyID gid.GID,
|
||||
) (*coredata.Risk, *coredata.Policy, error) {
|
||||
documentID gid.GID,
|
||||
) (*coredata.Risk, *coredata.Document, error) {
|
||||
risk := &coredata.Risk{}
|
||||
policy := &coredata.Policy{}
|
||||
document := &coredata.Document{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
@@ -95,36 +95,36 @@ func (s RiskService) CreatePolicyMapping(
|
||||
return fmt.Errorf("cannot load risk: %w", err)
|
||||
}
|
||||
|
||||
if err := policy.LoadByID(ctx, conn, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load policy: %w", err)
|
||||
if err := document.LoadByID(ctx, conn, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load document: %w", err)
|
||||
}
|
||||
|
||||
riskPolicy := &coredata.RiskPolicy{
|
||||
RiskID: risk.ID,
|
||||
PolicyID: policy.ID,
|
||||
TenantID: s.svc.scope.GetTenantID(),
|
||||
CreatedAt: time.Now(),
|
||||
riskDocument := &coredata.RiskDocument{
|
||||
RiskID: risk.ID,
|
||||
DocumentID: document.ID,
|
||||
TenantID: s.svc.scope.GetTenantID(),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
return riskPolicy.Insert(ctx, conn, s.svc.scope)
|
||||
return riskDocument.Insert(ctx, conn, s.svc.scope)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot create risk policy mapping: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot create risk document mapping: %w", err)
|
||||
}
|
||||
|
||||
return risk, policy, nil
|
||||
return risk, document, nil
|
||||
}
|
||||
|
||||
func (s RiskService) DeletePolicyMapping(
|
||||
func (s RiskService) DeleteDocumentMapping(
|
||||
ctx context.Context,
|
||||
riskID gid.GID,
|
||||
policyID gid.GID,
|
||||
) (*coredata.Risk, *coredata.Policy, error) {
|
||||
riskPolicy := &coredata.RiskPolicy{}
|
||||
documentID gid.GID,
|
||||
) (*coredata.Risk, *coredata.Document, error) {
|
||||
riskDocument := &coredata.RiskDocument{}
|
||||
risk := &coredata.Risk{}
|
||||
policy := &coredata.Policy{}
|
||||
document := &coredata.Document{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
@@ -133,19 +133,19 @@ func (s RiskService) DeletePolicyMapping(
|
||||
return fmt.Errorf("cannot load risk: %w", err)
|
||||
}
|
||||
|
||||
if err := policy.LoadByID(ctx, conn, s.svc.scope, policyID); err != nil {
|
||||
return fmt.Errorf("cannot load policy: %w", err)
|
||||
if err := document.LoadByID(ctx, conn, s.svc.scope, documentID); err != nil {
|
||||
return fmt.Errorf("cannot load document: %w", err)
|
||||
}
|
||||
|
||||
return riskPolicy.Delete(ctx, conn, s.svc.scope, risk.ID, policy.ID)
|
||||
return riskDocument.Delete(ctx, conn, s.svc.scope, risk.ID, document.ID)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot delete risk policy mapping: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot delete risk document mapping: %w", err)
|
||||
}
|
||||
|
||||
return risk, policy, nil
|
||||
return risk, document, nil
|
||||
}
|
||||
|
||||
func (s RiskService) CreateMeasureMapping(
|
||||
|
||||
@@ -54,7 +54,7 @@ type (
|
||||
Organizations *OrganizationService
|
||||
Vendors *VendorService
|
||||
Peoples *PeopleService
|
||||
Policies *PolicyService
|
||||
Documents *DocumentService
|
||||
Controls *ControlService
|
||||
Risks *RiskService
|
||||
VendorComplianceReports *VendorComplianceReportService
|
||||
@@ -118,7 +118,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService {
|
||||
}
|
||||
tenantService.Peoples = &PeopleService{svc: tenantService}
|
||||
tenantService.Vendors = &VendorService{svc: tenantService}
|
||||
tenantService.Policies = &PolicyService{svc: tenantService}
|
||||
tenantService.Documents = &DocumentService{svc: tenantService}
|
||||
tenantService.Organizations = &OrganizationService{
|
||||
svc: tenantService,
|
||||
fileValidator: filevalidation.NewValidator(
|
||||
|
||||
@@ -89,7 +89,7 @@ func NewMux(
|
||||
r := chi.NewMux()
|
||||
|
||||
r.Get(
|
||||
"/policies/signing-requests",
|
||||
"/documents/signing-requests",
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
@@ -106,7 +106,7 @@ func NewMux(
|
||||
|
||||
svc := proboSvc.WithTenant(data.Data.OrganizationID.TenantID())
|
||||
|
||||
requests, err := svc.Policies.ListSigningRequests(r.Context(), data.Data.OrganizationID, data.Data.PeopleID)
|
||||
requests, err := svc.Documents.ListSigningRequests(r.Context(), data.Data.OrganizationID, data.Data.PeopleID)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -118,7 +118,7 @@ func NewMux(
|
||||
)
|
||||
|
||||
r.Post(
|
||||
"/policies/signing-requests/{policy_version_id}/sign",
|
||||
"/documents/signing-requests/{document_version_id}/sign",
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("Authorization")
|
||||
if token == "" {
|
||||
@@ -133,15 +133,15 @@ func NewMux(
|
||||
return
|
||||
}
|
||||
|
||||
policyVersionID, err := gid.ParseGID(chi.URLParam(r, "policy_version_id"))
|
||||
documentVersionID, err := gid.ParseGID(chi.URLParam(r, "document_version_id"))
|
||||
if err != nil {
|
||||
http.Error(w, "invalid policy version id", http.StatusBadRequest)
|
||||
http.Error(w, "invalid document version id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
svc := proboSvc.WithTenant(data.Data.OrganizationID.TenantID())
|
||||
|
||||
if err := svc.Policies.SignPolicyVersion(r.Context(), policyVersionID, data.Data.PeopleID); err != nil {
|
||||
if err := svc.Documents.SignDocumentVersion(r.Context(), documentVersionID, data.Data.PeopleID); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -91,13 +91,13 @@ enum PeopleKind
|
||||
)
|
||||
}
|
||||
|
||||
enum PolicyStatus
|
||||
@goModel(model: "github.com/getprobo/probo/pkg/coredata.PolicyStatus") {
|
||||
enum DocumentStatus
|
||||
@goModel(model: "github.com/getprobo/probo/pkg/coredata.DocumentStatus") {
|
||||
DRAFT
|
||||
@goEnum(value: "github.com/getprobo/probo/pkg/coredata.PolicyStatusDraft")
|
||||
@goEnum(value: "github.com/getprobo/probo/pkg/coredata.DocumentStatusDraft")
|
||||
PUBLISHED
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyStatusPublished"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentStatusPublished"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -184,15 +184,15 @@ enum TaskOrderField
|
||||
CREATED_AT
|
||||
}
|
||||
|
||||
enum PolicyOrderField
|
||||
@goModel(model: "github.com/getprobo/probo/pkg/coredata.PolicyOrderField") {
|
||||
enum DocumentOrderField
|
||||
@goModel(model: "github.com/getprobo/probo/pkg/coredata.DocumentOrderField") {
|
||||
TITLE
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyOrderFieldTitle"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentOrderFieldTitle"
|
||||
)
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyOrderFieldCreatedAt"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentOrderFieldCreatedAt"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -298,17 +298,17 @@ enum BusinessImpact
|
||||
)
|
||||
}
|
||||
|
||||
enum PolicyVersionOrderField
|
||||
enum DocumentVersionOrderField
|
||||
@goModel(
|
||||
model: "github.com/getprobo/probo/pkg/coredata.PolicyVersionOrderField"
|
||||
model: "github.com/getprobo/probo/pkg/coredata.DocumentVersionOrderField"
|
||||
) {
|
||||
VERSION
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyVersionOrderFieldVersion"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentVersionOrderFieldVersion"
|
||||
)
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyVersionOrderFieldCreatedAt"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentVersionOrderFieldCreatedAt"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -394,12 +394,12 @@ input TaskOrder
|
||||
field: TaskOrderField!
|
||||
}
|
||||
|
||||
input PolicyOrder
|
||||
input DocumentOrder
|
||||
@goModel(
|
||||
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.PolicyOrderBy"
|
||||
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.DocumentOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: PolicyOrderField!
|
||||
field: DocumentOrderField!
|
||||
}
|
||||
|
||||
input RiskOrder
|
||||
@@ -436,16 +436,16 @@ input ConnectorOrder {
|
||||
direction: OrderDirection!
|
||||
}
|
||||
|
||||
input PolicyVersionOrder
|
||||
input DocumentVersionOrder
|
||||
@goModel(
|
||||
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.PolicyVersionOrderBy"
|
||||
model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.DocumentVersionOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: PolicyVersionOrderField!
|
||||
field: DocumentVersionOrderField!
|
||||
}
|
||||
|
||||
input PolicyVersionFilter {
|
||||
status: PolicyStatus
|
||||
input DocumentVersionFilter {
|
||||
status: DocumentStatus
|
||||
}
|
||||
|
||||
# Core Types
|
||||
@@ -494,13 +494,13 @@ type Organization implements Node {
|
||||
orderBy: PeopleOrder
|
||||
): PeopleConnection! @goField(forceResolver: true)
|
||||
|
||||
policies(
|
||||
documents(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: PolicyOrder
|
||||
): PolicyConnection! @goField(forceResolver: true)
|
||||
orderBy: DocumentOrder
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
measures(
|
||||
first: Int
|
||||
@@ -652,13 +652,13 @@ type Control implements Node {
|
||||
orderBy: MeasureOrder
|
||||
): MeasureConnection! @goField(forceResolver: true)
|
||||
|
||||
policies(
|
||||
documents(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: PolicyOrder
|
||||
): PolicyConnection! @goField(forceResolver: true)
|
||||
orderBy: DocumentOrder
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
@@ -748,7 +748,7 @@ type Evidence implements Node {
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
|
||||
type Policy implements Node {
|
||||
type Document implements Node {
|
||||
id: ID!
|
||||
title: String!
|
||||
description: String!
|
||||
@@ -761,9 +761,9 @@ type Policy implements Node {
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: PolicyVersionOrder
|
||||
filter: PolicyVersionFilter
|
||||
): PolicyVersionConnection! @goField(forceResolver: true)
|
||||
orderBy: DocumentVersionOrder
|
||||
filter: DocumentVersionFilter
|
||||
): DocumentVersionConnection! @goField(forceResolver: true)
|
||||
|
||||
controls(
|
||||
first: Int
|
||||
@@ -802,13 +802,13 @@ type Risk implements Node {
|
||||
orderBy: MeasureOrder
|
||||
): MeasureConnection! @goField(forceResolver: true)
|
||||
|
||||
policies(
|
||||
documents(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: PolicyOrder
|
||||
): PolicyConnection! @goField(forceResolver: true)
|
||||
orderBy: DocumentOrder
|
||||
): DocumentConnection! @goField(forceResolver: true)
|
||||
|
||||
controls(
|
||||
first: Int
|
||||
@@ -931,14 +931,14 @@ type EvidenceEdge {
|
||||
node: Evidence!
|
||||
}
|
||||
|
||||
type PolicyConnection {
|
||||
edges: [PolicyEdge!]!
|
||||
type DocumentConnection {
|
||||
edges: [DocumentEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type PolicyEdge {
|
||||
type DocumentEdge {
|
||||
cursor: CursorKey!
|
||||
node: Policy!
|
||||
node: Document!
|
||||
}
|
||||
|
||||
type RiskConnection {
|
||||
@@ -981,14 +981,14 @@ type VendorRiskAssessmentEdge {
|
||||
node: VendorRiskAssessment!
|
||||
}
|
||||
|
||||
type PolicyVersionConnection {
|
||||
edges: [PolicyVersionEdge!]!
|
||||
type DocumentVersionConnection {
|
||||
edges: [DocumentVersionEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type PolicyVersionEdge {
|
||||
type DocumentVersionEdge {
|
||||
cursor: CursorKey!
|
||||
node: PolicyVersion!
|
||||
node: DocumentVersion!
|
||||
}
|
||||
|
||||
# Root Types
|
||||
@@ -1040,15 +1040,15 @@ type Mutation {
|
||||
createControlMeasureMapping(
|
||||
input: CreateControlMeasureMappingInput!
|
||||
): CreateControlMeasureMappingPayload!
|
||||
createControlPolicyMapping(
|
||||
input: CreateControlPolicyMappingInput!
|
||||
): CreateControlPolicyMappingPayload!
|
||||
createControlDocumentMapping(
|
||||
input: CreateControlDocumentMappingInput!
|
||||
): CreateControlDocumentMappingPayload!
|
||||
deleteControlMeasureMapping(
|
||||
input: DeleteControlMeasureMappingInput!
|
||||
): DeleteControlMeasureMappingPayload!
|
||||
deleteControlPolicyMapping(
|
||||
input: DeleteControlPolicyMappingInput!
|
||||
): DeleteControlPolicyMappingPayload!
|
||||
deleteControlDocumentMapping(
|
||||
input: DeleteControlDocumentMappingInput!
|
||||
): DeleteControlDocumentMappingPayload!
|
||||
|
||||
# Task mutations
|
||||
createTask(input: CreateTaskInput!): CreateTaskPayload!
|
||||
@@ -1068,12 +1068,12 @@ type Mutation {
|
||||
input: DeleteRiskMeasureMappingInput!
|
||||
): DeleteRiskMeasureMappingPayload!
|
||||
|
||||
createRiskPolicyMapping(
|
||||
input: CreateRiskPolicyMappingInput!
|
||||
): CreateRiskPolicyMappingPayload!
|
||||
deleteRiskPolicyMapping(
|
||||
input: DeleteRiskPolicyMappingInput!
|
||||
): DeleteRiskPolicyMappingPayload!
|
||||
createRiskDocumentMapping(
|
||||
input: CreateRiskDocumentMappingInput!
|
||||
): CreateRiskDocumentMappingPayload!
|
||||
deleteRiskDocumentMapping(
|
||||
input: DeleteRiskDocumentMappingInput!
|
||||
): DeleteRiskDocumentMappingPayload!
|
||||
|
||||
# Evidence mutations
|
||||
requestEvidence(input: RequestEvidenceInput!): RequestEvidencePayload!
|
||||
@@ -1094,18 +1094,18 @@ type Mutation {
|
||||
input: DeleteVendorComplianceReportInput!
|
||||
): DeleteVendorComplianceReportPayload!
|
||||
|
||||
# Policy mutations
|
||||
createPolicy(input: CreatePolicyInput!): CreatePolicyPayload!
|
||||
deletePolicy(input: DeletePolicyInput!): DeletePolicyPayload!
|
||||
publishPolicyVersion(
|
||||
input: PublishPolicyVersionInput!
|
||||
): PublishPolicyVersionPayload!
|
||||
createDraftPolicyVersion(
|
||||
input: CreateDraftPolicyVersionInput!
|
||||
): CreateDraftPolicyVersionPayload!
|
||||
updatePolicyVersion(
|
||||
input: UpdatePolicyVersionInput!
|
||||
): UpdatePolicyVersionPayload!
|
||||
# Document mutations
|
||||
createDocument(input: CreateDocumentInput!): CreateDocumentPayload!
|
||||
deleteDocument(input: DeleteDocumentInput!): DeleteDocumentPayload!
|
||||
publishDocumentVersion(
|
||||
input: PublishDocumentVersionInput!
|
||||
): PublishDocumentVersionPayload!
|
||||
createDraftDocumentVersion(
|
||||
input: CreateDraftDocumentVersionInput!
|
||||
): CreateDraftDocumentVersionPayload!
|
||||
updateDocumentVersion(
|
||||
input: UpdateDocumentVersionInput!
|
||||
): UpdateDocumentVersionPayload!
|
||||
requestSignature(input: RequestSignatureInput!): RequestSignaturePayload!
|
||||
sendSigningNotifications(
|
||||
input: SendSigningNotificationsInput!
|
||||
@@ -1285,9 +1285,9 @@ input CreateControlMeasureMappingInput {
|
||||
measureId: ID!
|
||||
}
|
||||
|
||||
input CreateControlPolicyMappingInput {
|
||||
input CreateControlDocumentMappingInput {
|
||||
controlId: ID!
|
||||
policyId: ID!
|
||||
documentId: ID!
|
||||
}
|
||||
|
||||
input DeleteControlMeasureMappingInput {
|
||||
@@ -1295,9 +1295,9 @@ input DeleteControlMeasureMappingInput {
|
||||
measureId: ID!
|
||||
}
|
||||
|
||||
input DeleteControlPolicyMappingInput {
|
||||
input DeleteControlDocumentMappingInput {
|
||||
controlId: ID!
|
||||
policyId: ID!
|
||||
documentId: ID!
|
||||
}
|
||||
|
||||
input CreateRiskInput {
|
||||
@@ -1342,14 +1342,14 @@ input DeleteRiskMeasureMappingInput {
|
||||
measureId: ID!
|
||||
}
|
||||
|
||||
input CreateRiskPolicyMappingInput {
|
||||
input CreateRiskDocumentMappingInput {
|
||||
riskId: ID!
|
||||
policyId: ID!
|
||||
documentId: ID!
|
||||
}
|
||||
|
||||
input DeleteRiskPolicyMappingInput {
|
||||
input DeleteRiskDocumentMappingInput {
|
||||
riskId: ID!
|
||||
policyId: ID!
|
||||
documentId: ID!
|
||||
}
|
||||
|
||||
input RequestEvidenceInput {
|
||||
@@ -1391,14 +1391,14 @@ input DeleteVendorComplianceReportInput {
|
||||
reportId: ID!
|
||||
}
|
||||
|
||||
input CreatePolicyInput {
|
||||
input CreateDocumentInput {
|
||||
organizationId: ID!
|
||||
title: String!
|
||||
content: String!
|
||||
ownerId: ID!
|
||||
}
|
||||
|
||||
input UpdatePolicyInput {
|
||||
input UpdateDocumentInput {
|
||||
id: ID!
|
||||
title: String
|
||||
content: String
|
||||
@@ -1406,8 +1406,8 @@ input UpdatePolicyInput {
|
||||
createdBy: ID
|
||||
}
|
||||
|
||||
input DeletePolicyInput {
|
||||
policyId: ID!
|
||||
input DeleteDocumentInput {
|
||||
documentId: ID!
|
||||
}
|
||||
|
||||
input ConfirmEmailInput {
|
||||
@@ -1515,9 +1515,9 @@ type CreateControlMeasureMappingPayload {
|
||||
measureEdge: MeasureEdge!
|
||||
}
|
||||
|
||||
type CreateControlPolicyMappingPayload {
|
||||
type CreateControlDocumentMappingPayload {
|
||||
controlEdge: ControlEdge!
|
||||
policyEdge: PolicyEdge!
|
||||
documentEdge: DocumentEdge!
|
||||
}
|
||||
|
||||
type DeleteControlMeasureMappingPayload {
|
||||
@@ -1525,9 +1525,9 @@ type DeleteControlMeasureMappingPayload {
|
||||
deletedMeasureId: ID!
|
||||
}
|
||||
|
||||
type DeleteControlPolicyMappingPayload {
|
||||
type DeleteControlDocumentMappingPayload {
|
||||
deletedControlId: ID!
|
||||
deletedPolicyId: ID!
|
||||
deletedDocumentId: ID!
|
||||
}
|
||||
|
||||
type CreateRiskPayload {
|
||||
@@ -1552,14 +1552,14 @@ type DeleteRiskMeasureMappingPayload {
|
||||
deletedRiskId: ID!
|
||||
}
|
||||
|
||||
type CreateRiskPolicyMappingPayload {
|
||||
type CreateRiskDocumentMappingPayload {
|
||||
riskEdge: RiskEdge!
|
||||
policyEdge: PolicyEdge!
|
||||
documentEdge: DocumentEdge!
|
||||
}
|
||||
|
||||
type DeleteRiskPolicyMappingPayload {
|
||||
type DeleteRiskDocumentMappingPayload {
|
||||
deletedRiskId: ID!
|
||||
deletedPolicyId: ID!
|
||||
deletedDocumentId: ID!
|
||||
}
|
||||
|
||||
type RequestEvidencePayload {
|
||||
@@ -1586,17 +1586,17 @@ type DeleteVendorComplianceReportPayload {
|
||||
deletedVendorComplianceReportId: ID!
|
||||
}
|
||||
|
||||
type CreatePolicyPayload {
|
||||
policyEdge: PolicyEdge!
|
||||
policyVersionEdge: PolicyVersionEdge!
|
||||
type CreateDocumentPayload {
|
||||
documentEdge: DocumentEdge!
|
||||
documentVersionEdge: DocumentVersionEdge!
|
||||
}
|
||||
|
||||
type UpdatePolicyPayload {
|
||||
policy: Policy!
|
||||
type UpdateDocumentPayload {
|
||||
document: Document!
|
||||
}
|
||||
|
||||
type DeletePolicyPayload {
|
||||
deletedPolicyId: ID!
|
||||
type DeleteDocumentPayload {
|
||||
deletedDocumentId: ID!
|
||||
}
|
||||
|
||||
type ConfirmEmailPayload {
|
||||
@@ -1668,10 +1668,10 @@ type DeleteMeasurePayload {
|
||||
deletedMeasureId: ID!
|
||||
}
|
||||
|
||||
type PolicyVersion implements Node {
|
||||
type DocumentVersion implements Node {
|
||||
id: ID!
|
||||
policy: Policy! @goField(forceResolver: true)
|
||||
status: PolicyStatus!
|
||||
document: Document! @goField(forceResolver: true)
|
||||
status: DocumentStatus!
|
||||
version: Int!
|
||||
content: String!
|
||||
changelog: String!
|
||||
@@ -1681,8 +1681,8 @@ type PolicyVersion implements Node {
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: PolicyVersionSignatureOrder
|
||||
): PolicyVersionSignatureConnection! @goField(forceResolver: true)
|
||||
orderBy: DocumentVersionSignatureOrder
|
||||
): DocumentVersionSignatureConnection! @goField(forceResolver: true)
|
||||
|
||||
publishedBy: People @goField(forceResolver: true)
|
||||
publishedAt: Datetime
|
||||
@@ -1690,53 +1690,53 @@ type PolicyVersion implements Node {
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
|
||||
type PolicyVersionSignatureConnection {
|
||||
edges: [PolicyVersionSignatureEdge!]!
|
||||
type DocumentVersionSignatureConnection {
|
||||
edges: [DocumentVersionSignatureEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type PolicyVersionSignatureEdge {
|
||||
type DocumentVersionSignatureEdge {
|
||||
cursor: CursorKey!
|
||||
node: PolicyVersionSignature!
|
||||
node: DocumentVersionSignature!
|
||||
}
|
||||
|
||||
input PolicyVersionSignatureOrder {
|
||||
field: PolicyVersionSignatureOrderField!
|
||||
input DocumentVersionSignatureOrder {
|
||||
field: DocumentVersionSignatureOrderField!
|
||||
direction: OrderDirection!
|
||||
}
|
||||
|
||||
enum PolicyVersionSignatureState
|
||||
enum DocumentVersionSignatureState
|
||||
@goModel(
|
||||
model: "github.com/getprobo/probo/pkg/coredata.PolicyVersionSignatureState"
|
||||
model: "github.com/getprobo/probo/pkg/coredata.DocumentVersionSignatureState"
|
||||
) {
|
||||
REQUESTED
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyVersionSignatureStateRequested"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentVersionSignatureStateRequested"
|
||||
)
|
||||
SIGNED
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyVersionSignatureStateSigned"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentVersionSignatureStateSigned"
|
||||
)
|
||||
}
|
||||
|
||||
enum PolicyVersionSignatureOrderField
|
||||
enum DocumentVersionSignatureOrderField
|
||||
@goModel(
|
||||
model: "github.com/getprobo/probo/pkg/coredata.PolicyVersionSignatureOrderField"
|
||||
model: "github.com/getprobo/probo/pkg/coredata.DocumentVersionSignatureOrderField"
|
||||
) {
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyVersionSignatureOrderFieldCreatedAt"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentVersionSignatureOrderFieldCreatedAt"
|
||||
)
|
||||
SIGNED_AT
|
||||
@goEnum(
|
||||
value: "github.com/getprobo/probo/pkg/coredata.PolicyVersionSignatureOrderFieldSignedAt"
|
||||
value: "github.com/getprobo/probo/pkg/coredata.DocumentVersionSignatureOrderFieldSignedAt"
|
||||
)
|
||||
}
|
||||
|
||||
type PolicyVersionSignature implements Node {
|
||||
type DocumentVersionSignature implements Node {
|
||||
id: ID!
|
||||
policyVersion: PolicyVersion! @goField(forceResolver: true)
|
||||
state: PolicyVersionSignatureState!
|
||||
documentVersion: DocumentVersion! @goField(forceResolver: true)
|
||||
state: DocumentVersionSignatureState!
|
||||
signedBy: People! @goField(forceResolver: true)
|
||||
signedAt: Datetime
|
||||
requestedAt: Datetime!
|
||||
@@ -1746,38 +1746,38 @@ type PolicyVersionSignature implements Node {
|
||||
}
|
||||
|
||||
input RequestSignatureInput {
|
||||
policyVersionId: ID!
|
||||
documentVersionId: ID!
|
||||
signatoryId: ID!
|
||||
}
|
||||
|
||||
type RequestSignaturePayload {
|
||||
policyVersionSignatureEdge: PolicyVersionSignatureEdge!
|
||||
documentVersionSignatureEdge: DocumentVersionSignatureEdge!
|
||||
}
|
||||
|
||||
input PublishPolicyVersionInput {
|
||||
policyId: ID!
|
||||
input PublishDocumentVersionInput {
|
||||
documentId: ID!
|
||||
}
|
||||
|
||||
type PublishPolicyVersionPayload {
|
||||
policyVersion: PolicyVersion!
|
||||
policy: Policy!
|
||||
type PublishDocumentVersionPayload {
|
||||
documentVersion: DocumentVersion!
|
||||
document: Document!
|
||||
}
|
||||
|
||||
type CreateDraftPolicyVersionPayload {
|
||||
policyVersionEdge: PolicyVersionEdge!
|
||||
type CreateDraftDocumentVersionPayload {
|
||||
documentVersionEdge: DocumentVersionEdge!
|
||||
}
|
||||
|
||||
input CreateDraftPolicyVersionInput {
|
||||
policyID: ID!
|
||||
input CreateDraftDocumentVersionInput {
|
||||
documentID: ID!
|
||||
}
|
||||
|
||||
input UpdatePolicyVersionInput {
|
||||
policyVersionId: ID!
|
||||
input UpdateDocumentVersionInput {
|
||||
documentVersionId: ID!
|
||||
content: String!
|
||||
}
|
||||
|
||||
type UpdatePolicyVersionPayload {
|
||||
policyVersion: PolicyVersion!
|
||||
type UpdateDocumentVersionPayload {
|
||||
documentVersion: DocumentVersion!
|
||||
}
|
||||
|
||||
input SendSigningNotificationsInput {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,34 +20,34 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyOrderBy OrderBy[coredata.PolicyOrderField]
|
||||
DocumentOrderBy OrderBy[coredata.DocumentOrderField]
|
||||
)
|
||||
|
||||
func NewPolicyConnection(page *page.Page[*coredata.Policy, coredata.PolicyOrderField]) *PolicyConnection {
|
||||
edges := make([]*PolicyEdge, len(page.Data))
|
||||
for i, policy := range page.Data {
|
||||
edges[i] = NewPolicyEdge(policy, page.Cursor.OrderBy.Field)
|
||||
func NewDocumentConnection(page *page.Page[*coredata.Document, coredata.DocumentOrderField]) *DocumentConnection {
|
||||
edges := make([]*DocumentEdge, len(page.Data))
|
||||
for i, document := range page.Data {
|
||||
edges[i] = NewDocumentEdge(document, page.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &PolicyConnection{
|
||||
return &DocumentConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(page),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPolicyEdge(policy *coredata.Policy, orderBy coredata.PolicyOrderField) *PolicyEdge {
|
||||
return &PolicyEdge{
|
||||
Cursor: policy.CursorKey(orderBy),
|
||||
Node: NewPolicy(policy),
|
||||
func NewDocumentEdge(document *coredata.Document, orderBy coredata.DocumentOrderField) *DocumentEdge {
|
||||
return &DocumentEdge{
|
||||
Cursor: document.CursorKey(orderBy),
|
||||
Node: NewDocument(document),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPolicy(policy *coredata.Policy) *Policy {
|
||||
return &Policy{
|
||||
ID: policy.ID,
|
||||
Title: policy.Title,
|
||||
CurrentPublishedVersion: policy.CurrentPublishedVersion,
|
||||
CreatedAt: policy.CreatedAt,
|
||||
UpdatedAt: policy.UpdatedAt,
|
||||
func NewDocument(document *coredata.Document) *Document {
|
||||
return &Document{
|
||||
ID: document.ID,
|
||||
Title: document.Title,
|
||||
CurrentPublishedVersion: document.CurrentPublishedVersion,
|
||||
CreatedAt: document.CreatedAt,
|
||||
UpdatedAt: document.UpdatedAt,
|
||||
}
|
||||
}
|
||||
56
pkg/server/api/console/v1/types/document_version.go
Normal file
56
pkg/server/api/console/v1/types/document_version.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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 types
|
||||
|
||||
import (
|
||||
"github.com/getprobo/probo/pkg/coredata"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
DocumentVersionOrderBy OrderBy[coredata.DocumentVersionOrderField]
|
||||
)
|
||||
|
||||
func NewDocumentVersionConnection(page *page.Page[*coredata.DocumentVersion, coredata.DocumentVersionOrderField]) *DocumentVersionConnection {
|
||||
edges := make([]*DocumentVersionEdge, len(page.Data))
|
||||
for i, documentVersion := range page.Data {
|
||||
edges[i] = NewDocumentVersionEdge(documentVersion, page.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &DocumentVersionConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(page),
|
||||
}
|
||||
}
|
||||
|
||||
func NewDocumentVersionEdge(documentVersion *coredata.DocumentVersion, orderBy coredata.DocumentVersionOrderField) *DocumentVersionEdge {
|
||||
return &DocumentVersionEdge{
|
||||
Cursor: documentVersion.CursorKey(orderBy),
|
||||
Node: NewDocumentVersion(documentVersion),
|
||||
}
|
||||
}
|
||||
|
||||
func NewDocumentVersion(documentVersion *coredata.DocumentVersion) *DocumentVersion {
|
||||
return &DocumentVersion{
|
||||
ID: documentVersion.ID,
|
||||
Version: documentVersion.VersionNumber,
|
||||
Content: documentVersion.Content,
|
||||
Status: documentVersion.Status,
|
||||
PublishedAt: documentVersion.PublishedAt,
|
||||
Changelog: documentVersion.Changelog,
|
||||
CreatedAt: documentVersion.CreatedAt,
|
||||
UpdatedAt: documentVersion.UpdatedAt,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// 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 types
|
||||
|
||||
import (
|
||||
"github.com/getprobo/probo/pkg/coredata"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
DocumentVersionSignatureOrderBy OrderBy[coredata.DocumentVersionSignatureOrderField]
|
||||
)
|
||||
|
||||
func NewDocumentVersionSignatureConnection(page *page.Page[*coredata.DocumentVersionSignature, coredata.DocumentVersionSignatureOrderField]) *DocumentVersionSignatureConnection {
|
||||
edges := make([]*DocumentVersionSignatureEdge, len(page.Data))
|
||||
for i, documentVersionSignature := range page.Data {
|
||||
edges[i] = NewDocumentVersionSignatureEdge(documentVersionSignature, page.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &DocumentVersionSignatureConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(page),
|
||||
}
|
||||
}
|
||||
|
||||
func NewDocumentVersionSignatureEdge(documentVersionSignature *coredata.DocumentVersionSignature, orderBy coredata.DocumentVersionSignatureOrderField) *DocumentVersionSignatureEdge {
|
||||
return &DocumentVersionSignatureEdge{
|
||||
Cursor: documentVersionSignature.CursorKey(orderBy),
|
||||
Node: NewDocumentVersionSignature(documentVersionSignature),
|
||||
}
|
||||
}
|
||||
|
||||
func NewDocumentVersionSignature(documentVersionSignature *coredata.DocumentVersionSignature) *DocumentVersionSignature {
|
||||
return &DocumentVersionSignature{
|
||||
ID: documentVersionSignature.ID,
|
||||
State: documentVersionSignature.State,
|
||||
SignedAt: documentVersionSignature.SignedAt,
|
||||
RequestedAt: documentVersionSignature.RequestedAt,
|
||||
CreatedAt: documentVersionSignature.CreatedAt,
|
||||
UpdatedAt: documentVersionSignature.UpdatedAt,
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// 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 types
|
||||
|
||||
import (
|
||||
"github.com/getprobo/probo/pkg/coredata"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyVersionOrderBy OrderBy[coredata.PolicyVersionOrderField]
|
||||
)
|
||||
|
||||
func NewPolicyVersionConnection(page *page.Page[*coredata.PolicyVersion, coredata.PolicyVersionOrderField]) *PolicyVersionConnection {
|
||||
edges := make([]*PolicyVersionEdge, len(page.Data))
|
||||
for i, policyVersion := range page.Data {
|
||||
edges[i] = NewPolicyVersionEdge(policyVersion, page.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &PolicyVersionConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(page),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPolicyVersionEdge(policyVersion *coredata.PolicyVersion, orderBy coredata.PolicyVersionOrderField) *PolicyVersionEdge {
|
||||
return &PolicyVersionEdge{
|
||||
Cursor: policyVersion.CursorKey(orderBy),
|
||||
Node: NewPolicyVersion(policyVersion),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPolicyVersion(policyVersion *coredata.PolicyVersion) *PolicyVersion {
|
||||
return &PolicyVersion{
|
||||
ID: policyVersion.ID,
|
||||
Version: policyVersion.VersionNumber,
|
||||
Content: policyVersion.Content,
|
||||
Status: policyVersion.Status,
|
||||
PublishedAt: policyVersion.PublishedAt,
|
||||
Changelog: policyVersion.Changelog,
|
||||
CreatedAt: policyVersion.CreatedAt,
|
||||
UpdatedAt: policyVersion.UpdatedAt,
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// 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 types
|
||||
|
||||
import (
|
||||
"github.com/getprobo/probo/pkg/coredata"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
PolicyVersionSignatureOrderBy OrderBy[coredata.PolicyVersionSignatureOrderField]
|
||||
)
|
||||
|
||||
func NewPolicyVersionSignatureConnection(page *page.Page[*coredata.PolicyVersionSignature, coredata.PolicyVersionSignatureOrderField]) *PolicyVersionSignatureConnection {
|
||||
edges := make([]*PolicyVersionSignatureEdge, len(page.Data))
|
||||
for i, policyVersionSignature := range page.Data {
|
||||
edges[i] = NewPolicyVersionSignatureEdge(policyVersionSignature, page.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &PolicyVersionSignatureConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(page),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPolicyVersionSignatureEdge(policyVersionSignature *coredata.PolicyVersionSignature, orderBy coredata.PolicyVersionSignatureOrderField) *PolicyVersionSignatureEdge {
|
||||
return &PolicyVersionSignatureEdge{
|
||||
Cursor: policyVersionSignature.CursorKey(orderBy),
|
||||
Node: NewPolicyVersionSignature(policyVersionSignature),
|
||||
}
|
||||
}
|
||||
|
||||
func NewPolicyVersionSignature(policyVersionSignature *coredata.PolicyVersionSignature) *PolicyVersionSignature {
|
||||
return &PolicyVersionSignature{
|
||||
ID: policyVersionSignature.ID,
|
||||
State: policyVersionSignature.State,
|
||||
SignedAt: policyVersionSignature.SignedAt,
|
||||
RequestedAt: policyVersionSignature.RequestedAt,
|
||||
CreatedAt: policyVersionSignature.CreatedAt,
|
||||
UpdatedAt: policyVersionSignature.UpdatedAt,
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ type Control struct {
|
||||
Description string `json:"description"`
|
||||
Framework *Framework `json:"framework"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Policies *PolicyConnection `json:"policies"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
@@ -107,22 +107,22 @@ type CreateControlMeasureMappingPayload struct {
|
||||
MeasureEdge *MeasureEdge `json:"measureEdge"`
|
||||
}
|
||||
|
||||
type CreateControlPolicyMappingInput struct {
|
||||
type CreateControlDocumentMappingInput struct {
|
||||
ControlID gid.GID `json:"controlId"`
|
||||
PolicyID gid.GID `json:"policyId"`
|
||||
DocumentID gid.GID `json:"documentId"`
|
||||
}
|
||||
|
||||
type CreateControlPolicyMappingPayload struct {
|
||||
type CreateControlDocumentMappingPayload struct {
|
||||
ControlEdge *ControlEdge `json:"controlEdge"`
|
||||
PolicyEdge *PolicyEdge `json:"policyEdge"`
|
||||
DocumentEdge *DocumentEdge `json:"documentEdge"`
|
||||
}
|
||||
|
||||
type CreateDraftPolicyVersionInput struct {
|
||||
PolicyID gid.GID `json:"policyID"`
|
||||
type CreateDraftDocumentVersionInput struct {
|
||||
DocumentID gid.GID `json:"documentID"`
|
||||
}
|
||||
|
||||
type CreateDraftPolicyVersionPayload struct {
|
||||
PolicyVersionEdge *PolicyVersionEdge `json:"policyVersionEdge"`
|
||||
type CreateDraftDocumentVersionPayload struct {
|
||||
DocumentVersionEdge *DocumentVersionEdge `json:"documentVersionEdge"`
|
||||
}
|
||||
|
||||
type CreateEvidenceInput struct {
|
||||
@@ -182,16 +182,16 @@ type CreatePeoplePayload struct {
|
||||
PeopleEdge *PeopleEdge `json:"peopleEdge"`
|
||||
}
|
||||
|
||||
type CreatePolicyInput struct {
|
||||
type CreateDocumentInput struct {
|
||||
OrganizationID gid.GID `json:"organizationId"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
OwnerID gid.GID `json:"ownerId"`
|
||||
}
|
||||
|
||||
type CreatePolicyPayload struct {
|
||||
PolicyEdge *PolicyEdge `json:"policyEdge"`
|
||||
PolicyVersionEdge *PolicyVersionEdge `json:"policyVersionEdge"`
|
||||
type CreateDocumentPayload struct {
|
||||
DocumentEdge *DocumentEdge `json:"documentEdge"`
|
||||
DocumentVersionEdge *DocumentVersionEdge `json:"documentVersionEdge"`
|
||||
}
|
||||
|
||||
type CreateRiskInput struct {
|
||||
@@ -222,14 +222,14 @@ type CreateRiskPayload struct {
|
||||
RiskEdge *RiskEdge `json:"riskEdge"`
|
||||
}
|
||||
|
||||
type CreateRiskPolicyMappingInput struct {
|
||||
type CreateRiskDocumentMappingInput struct {
|
||||
RiskID gid.GID `json:"riskId"`
|
||||
PolicyID gid.GID `json:"policyId"`
|
||||
DocumentID gid.GID `json:"documentId"`
|
||||
}
|
||||
|
||||
type CreateRiskPolicyMappingPayload struct {
|
||||
type CreateRiskDocumentMappingPayload struct {
|
||||
RiskEdge *RiskEdge `json:"riskEdge"`
|
||||
PolicyEdge *PolicyEdge `json:"policyEdge"`
|
||||
DocumentEdge *DocumentEdge `json:"documentEdge"`
|
||||
}
|
||||
|
||||
type CreateTaskInput struct {
|
||||
@@ -294,14 +294,14 @@ type DeleteControlMeasureMappingPayload struct {
|
||||
DeletedMeasureID gid.GID `json:"deletedMeasureId"`
|
||||
}
|
||||
|
||||
type DeleteControlPolicyMappingInput struct {
|
||||
type DeleteControlDocumentMappingInput struct {
|
||||
ControlID gid.GID `json:"controlId"`
|
||||
PolicyID gid.GID `json:"policyId"`
|
||||
DocumentID gid.GID `json:"documentId"`
|
||||
}
|
||||
|
||||
type DeleteControlPolicyMappingPayload struct {
|
||||
type DeleteControlDocumentMappingPayload struct {
|
||||
DeletedControlID gid.GID `json:"deletedControlId"`
|
||||
DeletedPolicyID gid.GID `json:"deletedPolicyId"`
|
||||
DeletedDocumentID gid.GID `json:"deletedDocumentId"`
|
||||
}
|
||||
|
||||
type DeleteEvidenceInput struct {
|
||||
@@ -344,12 +344,12 @@ type DeletePeoplePayload struct {
|
||||
DeletedPeopleID gid.GID `json:"deletedPeopleId"`
|
||||
}
|
||||
|
||||
type DeletePolicyInput struct {
|
||||
PolicyID gid.GID `json:"policyId"`
|
||||
type DeleteDocumentInput struct {
|
||||
DocumentID gid.GID `json:"documentId"`
|
||||
}
|
||||
|
||||
type DeletePolicyPayload struct {
|
||||
DeletedPolicyID gid.GID `json:"deletedPolicyId"`
|
||||
type DeleteDocumentPayload struct {
|
||||
DeletedDocumentID gid.GID `json:"deletedDocumentId"`
|
||||
}
|
||||
|
||||
type DeleteRiskInput struct {
|
||||
@@ -370,14 +370,14 @@ type DeleteRiskPayload struct {
|
||||
DeletedRiskID gid.GID `json:"deletedRiskId"`
|
||||
}
|
||||
|
||||
type DeleteRiskPolicyMappingInput struct {
|
||||
type DeleteRiskDocumentMappingInput struct {
|
||||
RiskID gid.GID `json:"riskId"`
|
||||
PolicyID gid.GID `json:"policyId"`
|
||||
DocumentID gid.GID `json:"documentId"`
|
||||
}
|
||||
|
||||
type DeleteRiskPolicyMappingPayload struct {
|
||||
type DeleteRiskDocumentMappingPayload struct {
|
||||
DeletedRiskID gid.GID `json:"deletedRiskId"`
|
||||
DeletedPolicyID gid.GID `json:"deletedPolicyId"`
|
||||
DeletedDocumentID gid.GID `json:"deletedDocumentId"`
|
||||
}
|
||||
|
||||
type DeleteTaskInput struct {
|
||||
@@ -542,7 +542,7 @@ type Organization struct {
|
||||
Frameworks *FrameworkConnection `json:"frameworks"`
|
||||
Vendors *VendorConnection `json:"vendors"`
|
||||
Peoples *PeopleConnection `json:"peoples"`
|
||||
Policies *PolicyConnection `json:"policies"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Risks *RiskConnection `json:"risks"`
|
||||
Tasks *TaskConnection `json:"tasks"`
|
||||
@@ -601,67 +601,67 @@ type PeopleEdge struct {
|
||||
Node *People `json:"node"`
|
||||
}
|
||||
|
||||
type Policy struct {
|
||||
type Document struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
CurrentPublishedVersion *int `json:"currentPublishedVersion,omitempty"`
|
||||
Owner *People `json:"owner"`
|
||||
Organization *Organization `json:"organization"`
|
||||
Versions *PolicyVersionConnection `json:"versions"`
|
||||
Versions *DocumentVersionConnection `json:"versions"`
|
||||
Controls *ControlConnection `json:"controls"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func (Policy) IsNode() {}
|
||||
func (this Policy) GetID() gid.GID { return this.ID }
|
||||
func (Document) IsNode() {}
|
||||
func (this Document) GetID() gid.GID { return this.ID }
|
||||
|
||||
type PolicyConnection struct {
|
||||
Edges []*PolicyEdge `json:"edges"`
|
||||
type DocumentConnection struct {
|
||||
Edges []*DocumentEdge `json:"edges"`
|
||||
PageInfo *PageInfo `json:"pageInfo"`
|
||||
}
|
||||
|
||||
type PolicyEdge struct {
|
||||
type DocumentEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
Node *Policy `json:"node"`
|
||||
Node *Document `json:"node"`
|
||||
}
|
||||
|
||||
type PolicyVersion struct {
|
||||
type DocumentVersion struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Policy *Policy `json:"policy"`
|
||||
Status coredata.PolicyStatus `json:"status"`
|
||||
Document *Document `json:"document"`
|
||||
Status coredata.DocumentStatus `json:"status"`
|
||||
Version int `json:"version"`
|
||||
Content string `json:"content"`
|
||||
Changelog string `json:"changelog"`
|
||||
Signatures *PolicyVersionSignatureConnection `json:"signatures"`
|
||||
Signatures *DocumentVersionSignatureConnection `json:"signatures"`
|
||||
PublishedBy *People `json:"publishedBy,omitempty"`
|
||||
PublishedAt *time.Time `json:"publishedAt,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func (PolicyVersion) IsNode() {}
|
||||
func (this PolicyVersion) GetID() gid.GID { return this.ID }
|
||||
func (DocumentVersion) IsNode() {}
|
||||
func (this DocumentVersion) GetID() gid.GID { return this.ID }
|
||||
|
||||
type PolicyVersionConnection struct {
|
||||
Edges []*PolicyVersionEdge `json:"edges"`
|
||||
type DocumentVersionConnection struct {
|
||||
Edges []*DocumentVersionEdge `json:"edges"`
|
||||
PageInfo *PageInfo `json:"pageInfo"`
|
||||
}
|
||||
|
||||
type PolicyVersionEdge struct {
|
||||
type DocumentVersionEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
Node *PolicyVersion `json:"node"`
|
||||
Node *DocumentVersion `json:"node"`
|
||||
}
|
||||
|
||||
type PolicyVersionFilter struct {
|
||||
Status *coredata.PolicyStatus `json:"status,omitempty"`
|
||||
type DocumentVersionFilter struct {
|
||||
Status *coredata.DocumentStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type PolicyVersionSignature struct {
|
||||
type DocumentVersionSignature struct {
|
||||
ID gid.GID `json:"id"`
|
||||
PolicyVersion *PolicyVersion `json:"policyVersion"`
|
||||
State coredata.PolicyVersionSignatureState `json:"state"`
|
||||
DocumentVersion *DocumentVersion `json:"documentVersion"`
|
||||
State coredata.DocumentVersionSignatureState `json:"state"`
|
||||
SignedBy *People `json:"signedBy"`
|
||||
SignedAt *time.Time `json:"signedAt,omitempty"`
|
||||
RequestedAt time.Time `json:"requestedAt"`
|
||||
@@ -670,31 +670,31 @@ type PolicyVersionSignature struct {
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func (PolicyVersionSignature) IsNode() {}
|
||||
func (this PolicyVersionSignature) GetID() gid.GID { return this.ID }
|
||||
func (DocumentVersionSignature) IsNode() {}
|
||||
func (this DocumentVersionSignature) GetID() gid.GID { return this.ID }
|
||||
|
||||
type PolicyVersionSignatureConnection struct {
|
||||
Edges []*PolicyVersionSignatureEdge `json:"edges"`
|
||||
type DocumentVersionSignatureConnection struct {
|
||||
Edges []*DocumentVersionSignatureEdge `json:"edges"`
|
||||
PageInfo *PageInfo `json:"pageInfo"`
|
||||
}
|
||||
|
||||
type PolicyVersionSignatureEdge struct {
|
||||
type DocumentVersionSignatureEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
Node *PolicyVersionSignature `json:"node"`
|
||||
Node *DocumentVersionSignature `json:"node"`
|
||||
}
|
||||
|
||||
type PolicyVersionSignatureOrder struct {
|
||||
Field coredata.PolicyVersionSignatureOrderField `json:"field"`
|
||||
type DocumentVersionSignatureOrder struct {
|
||||
Field coredata.DocumentVersionSignatureOrderField `json:"field"`
|
||||
Direction page.OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
type PublishPolicyVersionInput struct {
|
||||
PolicyID gid.GID `json:"policyId"`
|
||||
type PublishDocumentVersionInput struct {
|
||||
DocumentID gid.GID `json:"documentId"`
|
||||
}
|
||||
|
||||
type PublishPolicyVersionPayload struct {
|
||||
PolicyVersion *PolicyVersion `json:"policyVersion"`
|
||||
Policy *Policy `json:"policy"`
|
||||
type PublishDocumentVersionPayload struct {
|
||||
DocumentVersion *DocumentVersion `json:"documentVersion"`
|
||||
Document *Document `json:"document"`
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
@@ -721,12 +721,12 @@ type RequestEvidencePayload struct {
|
||||
}
|
||||
|
||||
type RequestSignatureInput struct {
|
||||
PolicyVersionID gid.GID `json:"policyVersionId"`
|
||||
DocumentVersionID gid.GID `json:"documentVersionId"`
|
||||
SignatoryID gid.GID `json:"signatoryId"`
|
||||
}
|
||||
|
||||
type RequestSignaturePayload struct {
|
||||
PolicyVersionSignatureEdge *PolicyVersionSignatureEdge `json:"policyVersionSignatureEdge"`
|
||||
DocumentVersionSignatureEdge *DocumentVersionSignatureEdge `json:"documentVersionSignatureEdge"`
|
||||
}
|
||||
|
||||
type Risk struct {
|
||||
@@ -745,7 +745,7 @@ type Risk struct {
|
||||
Owner *People `json:"owner,omitempty"`
|
||||
Organization *Organization `json:"organization"`
|
||||
Measures *MeasureConnection `json:"measures"`
|
||||
Policies *PolicyConnection `json:"policies"`
|
||||
Documents *DocumentConnection `json:"documents"`
|
||||
Controls *ControlConnection `json:"controls"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
@@ -859,7 +859,7 @@ type UpdatePeoplePayload struct {
|
||||
People *People `json:"people"`
|
||||
}
|
||||
|
||||
type UpdatePolicyInput struct {
|
||||
type UpdateDocumentInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
Content *string `json:"content,omitempty"`
|
||||
@@ -867,17 +867,17 @@ type UpdatePolicyInput struct {
|
||||
CreatedBy *gid.GID `json:"createdBy,omitempty"`
|
||||
}
|
||||
|
||||
type UpdatePolicyPayload struct {
|
||||
Policy *Policy `json:"policy"`
|
||||
type UpdateDocumentPayload struct {
|
||||
Document *Document `json:"document"`
|
||||
}
|
||||
|
||||
type UpdatePolicyVersionInput struct {
|
||||
PolicyVersionID gid.GID `json:"policyVersionId"`
|
||||
type UpdateDocumentVersionInput struct {
|
||||
DocumentVersionID gid.GID `json:"documentVersionId"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type UpdatePolicyVersionPayload struct {
|
||||
PolicyVersion *PolicyVersion `json:"policyVersion"`
|
||||
type UpdateDocumentVersionPayload struct {
|
||||
DocumentVersion *DocumentVersion `json:"documentVersion"`
|
||||
}
|
||||
|
||||
type UpdateRiskInput struct {
|
||||
|
||||
@@ -62,16 +62,16 @@ func (r *controlResolver) Measures(ctx context.Context, obj *types.Control, firs
|
||||
return types.NewMeasureConnection(page), nil
|
||||
}
|
||||
|
||||
// Policies is the resolver for the policies field.
|
||||
func (r *controlResolver) Policies(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PolicyOrderBy) (*types.PolicyConnection, error) {
|
||||
// Documents is the resolver for the documents field.
|
||||
func (r *controlResolver) Documents(ctx context.Context, obj *types.Control, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.DocumentConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.PolicyOrderField]{
|
||||
Field: coredata.PolicyOrderFieldCreatedAt,
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.PolicyOrderField]{
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
@@ -79,12 +79,12 @@ func (r *controlResolver) Policies(ctx context.Context, obj *types.Control, firs
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := svc.Policies.ListForControlID(ctx, obj.ID, cursor)
|
||||
page, err := svc.Documents.ListForControlID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot list policies: %w", err)
|
||||
return nil, fmt.Errorf("cannot list documents: %w", err)
|
||||
}
|
||||
|
||||
return types.NewPolicyConnection(page), nil
|
||||
return types.NewDocumentConnection(page), nil
|
||||
}
|
||||
|
||||
// FileURL is the resolver for the fileUrl field.
|
||||
@@ -730,18 +730,18 @@ func (r *mutationResolver) CreateControlMeasureMapping(ctx context.Context, inpu
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateControlPolicyMapping is the resolver for the createControlPolicyMapping field.
|
||||
func (r *mutationResolver) CreateControlPolicyMapping(ctx context.Context, input types.CreateControlPolicyMappingInput) (*types.CreateControlPolicyMappingPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.PolicyID.TenantID())
|
||||
// CreateControlDocumentMapping is the resolver for the createControlDocumentMapping field.
|
||||
func (r *mutationResolver) CreateControlDocumentMapping(ctx context.Context, input types.CreateControlDocumentMappingInput) (*types.CreateControlDocumentMappingPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.DocumentID.TenantID())
|
||||
|
||||
control, policy, err := svc.Controls.CreatePolicyMapping(ctx, input.ControlID, input.PolicyID)
|
||||
control, document, err := svc.Controls.CreateDocumentMapping(ctx, input.ControlID, input.DocumentID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot create control policy mapping: %w", err))
|
||||
panic(fmt.Errorf("cannot create control document mapping: %w", err))
|
||||
}
|
||||
|
||||
return &types.CreateControlPolicyMappingPayload{
|
||||
ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt),
|
||||
PolicyEdge: types.NewPolicyEdge(policy, coredata.PolicyOrderFieldTitle),
|
||||
return &types.CreateControlDocumentMappingPayload{
|
||||
ControlEdge: types.NewControlEdge(control, coredata.ControlOrderFieldCreatedAt),
|
||||
DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -760,18 +760,18 @@ func (r *mutationResolver) DeleteControlMeasureMapping(ctx context.Context, inpu
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteControlPolicyMapping is the resolver for the deleteControlPolicyMapping field.
|
||||
func (r *mutationResolver) DeleteControlPolicyMapping(ctx context.Context, input types.DeleteControlPolicyMappingInput) (*types.DeleteControlPolicyMappingPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.PolicyID.TenantID())
|
||||
// DeleteControlDocumentMapping is the resolver for the deleteControlDocumentMapping field.
|
||||
func (r *mutationResolver) DeleteControlDocumentMapping(ctx context.Context, input types.DeleteControlDocumentMappingInput) (*types.DeleteControlDocumentMappingPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.DocumentID.TenantID())
|
||||
|
||||
control, policy, err := svc.Controls.DeletePolicyMapping(ctx, input.ControlID, input.PolicyID)
|
||||
control, document, err := svc.Controls.DeleteDocumentMapping(ctx, input.ControlID, input.DocumentID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot delete control policy mapping: %w", err))
|
||||
panic(fmt.Errorf("cannot delete control document mapping: %w", err))
|
||||
}
|
||||
|
||||
return &types.DeleteControlPolicyMappingPayload{
|
||||
DeletedControlID: control.ID,
|
||||
DeletedPolicyID: policy.ID,
|
||||
return &types.DeleteControlDocumentMappingPayload{
|
||||
DeletedControlID: control.ID,
|
||||
DeletedDocumentID: document.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -959,33 +959,33 @@ func (r *mutationResolver) DeleteRiskMeasureMapping(ctx context.Context, input t
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateRiskPolicyMapping is the resolver for the createRiskPolicyMapping field.
|
||||
func (r *mutationResolver) CreateRiskPolicyMapping(ctx context.Context, input types.CreateRiskPolicyMappingInput) (*types.CreateRiskPolicyMappingPayload, error) {
|
||||
// CreateRiskDocumentMapping is the resolver for the createRiskDocumentMapping field.
|
||||
func (r *mutationResolver) CreateRiskDocumentMapping(ctx context.Context, input types.CreateRiskDocumentMappingInput) (*types.CreateRiskDocumentMappingPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.RiskID.TenantID())
|
||||
|
||||
risk, policy, err := svc.Risks.CreatePolicyMapping(ctx, input.RiskID, input.PolicyID)
|
||||
risk, document, err := svc.Risks.CreateDocumentMapping(ctx, input.RiskID, input.DocumentID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot create risk policy mapping: %w", err))
|
||||
panic(fmt.Errorf("cannot create risk document mapping: %w", err))
|
||||
}
|
||||
|
||||
return &types.CreateRiskPolicyMappingPayload{
|
||||
RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt),
|
||||
PolicyEdge: types.NewPolicyEdge(policy, coredata.PolicyOrderFieldTitle),
|
||||
return &types.CreateRiskDocumentMappingPayload{
|
||||
RiskEdge: types.NewRiskEdge(risk, coredata.RiskOrderFieldCreatedAt),
|
||||
DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteRiskPolicyMapping is the resolver for the deleteRiskPolicyMapping field.
|
||||
func (r *mutationResolver) DeleteRiskPolicyMapping(ctx context.Context, input types.DeleteRiskPolicyMappingInput) (*types.DeleteRiskPolicyMappingPayload, error) {
|
||||
// DeleteRiskDocumentMapping is the resolver for the deleteRiskDocumentMapping field.
|
||||
func (r *mutationResolver) DeleteRiskDocumentMapping(ctx context.Context, input types.DeleteRiskDocumentMappingInput) (*types.DeleteRiskDocumentMappingPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.RiskID.TenantID())
|
||||
|
||||
risk, policy, err := svc.Risks.DeletePolicyMapping(ctx, input.RiskID, input.PolicyID)
|
||||
risk, document, err := svc.Risks.DeleteDocumentMapping(ctx, input.RiskID, input.DocumentID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot delete risk policy mapping: %w", err))
|
||||
panic(fmt.Errorf("cannot delete risk document mapping: %w", err))
|
||||
}
|
||||
|
||||
return &types.DeleteRiskPolicyMappingPayload{
|
||||
DeletedRiskID: risk.ID,
|
||||
DeletedPolicyID: policy.ID,
|
||||
return &types.DeleteRiskDocumentMappingPayload{
|
||||
DeletedRiskID: risk.ID,
|
||||
DeletedDocumentID: document.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1139,8 +1139,8 @@ func (r *mutationResolver) DeleteVendorComplianceReport(ctx context.Context, inp
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreatePolicy is the resolver for the createPolicy field.
|
||||
func (r *mutationResolver) CreatePolicy(ctx context.Context, input types.CreatePolicyInput) (*types.CreatePolicyPayload, error) {
|
||||
// CreateDocument is the resolver for the createDocument field.
|
||||
func (r *mutationResolver) CreateDocument(ctx context.Context, input types.CreateDocumentInput) (*types.CreateDocumentPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.OrganizationID.TenantID())
|
||||
|
||||
user := UserFromContext(ctx)
|
||||
@@ -1149,9 +1149,9 @@ func (r *mutationResolver) CreatePolicy(ctx context.Context, input types.CreateP
|
||||
panic(fmt.Errorf("cannot get people: %w", err))
|
||||
}
|
||||
|
||||
policy, policyVersion, err := svc.Policies.Create(
|
||||
document, documentVersion, err := svc.Documents.Create(
|
||||
ctx,
|
||||
probo.CreatePolicyRequest{
|
||||
probo.CreateDocumentRequest{
|
||||
OrganizationID: input.OrganizationID,
|
||||
Title: input.Title,
|
||||
OwnerID: input.OwnerID,
|
||||
@@ -1160,32 +1160,32 @@ func (r *mutationResolver) CreatePolicy(ctx context.Context, input types.CreateP
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot create policy: %w", err))
|
||||
panic(fmt.Errorf("cannot create document: %w", err))
|
||||
}
|
||||
|
||||
return &types.CreatePolicyPayload{
|
||||
PolicyEdge: types.NewPolicyEdge(policy, coredata.PolicyOrderFieldTitle),
|
||||
PolicyVersionEdge: types.NewPolicyVersionEdge(policyVersion, coredata.PolicyVersionOrderFieldCreatedAt),
|
||||
return &types.CreateDocumentPayload{
|
||||
DocumentEdge: types.NewDocumentEdge(document, coredata.DocumentOrderFieldTitle),
|
||||
DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeletePolicy is the resolver for the deletePolicy field.
|
||||
func (r *mutationResolver) DeletePolicy(ctx context.Context, input types.DeletePolicyInput) (*types.DeletePolicyPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.PolicyID.TenantID())
|
||||
// DeleteDocument is the resolver for the deleteDocument field.
|
||||
func (r *mutationResolver) DeleteDocument(ctx context.Context, input types.DeleteDocumentInput) (*types.DeleteDocumentPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.DocumentID.TenantID())
|
||||
|
||||
err := svc.Policies.Delete(ctx, input.PolicyID)
|
||||
err := svc.Documents.Delete(ctx, input.DocumentID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot delete policy: %w", err))
|
||||
panic(fmt.Errorf("cannot delete document: %w", err))
|
||||
}
|
||||
|
||||
return &types.DeletePolicyPayload{
|
||||
DeletedPolicyID: input.PolicyID,
|
||||
return &types.DeleteDocumentPayload{
|
||||
DeletedDocumentID: input.DocumentID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublishPolicyVersion is the resolver for the publishPolicyVersion field.
|
||||
func (r *mutationResolver) PublishPolicyVersion(ctx context.Context, input types.PublishPolicyVersionInput) (*types.PublishPolicyVersionPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.PolicyID.TenantID())
|
||||
// PublishDocumentVersion is the resolver for the publishDocumentVersion field.
|
||||
func (r *mutationResolver) PublishDocumentVersion(ctx context.Context, input types.PublishDocumentVersionInput) (*types.PublishDocumentVersionPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.DocumentID.TenantID())
|
||||
user := UserFromContext(ctx)
|
||||
|
||||
people, err := svc.Peoples.GetByUserID(ctx, user.ID)
|
||||
@@ -1193,20 +1193,20 @@ func (r *mutationResolver) PublishPolicyVersion(ctx context.Context, input types
|
||||
panic(fmt.Errorf("cannot get people: %w", err))
|
||||
}
|
||||
|
||||
policy, policyVersion, err := svc.Policies.PublishVersion(ctx, input.PolicyID, people.ID)
|
||||
document, documentVersion, err := svc.Documents.PublishVersion(ctx, input.DocumentID, people.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot publish policy version: %w", err))
|
||||
panic(fmt.Errorf("cannot publish document version: %w", err))
|
||||
}
|
||||
|
||||
return &types.PublishPolicyVersionPayload{
|
||||
PolicyVersion: types.NewPolicyVersion(policyVersion),
|
||||
Policy: types.NewPolicy(policy),
|
||||
return &types.PublishDocumentVersionPayload{
|
||||
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
||||
Document: types.NewDocument(document),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateDraftPolicyVersion is the resolver for the createDraftPolicyVersion field.
|
||||
func (r *mutationResolver) CreateDraftPolicyVersion(ctx context.Context, input types.CreateDraftPolicyVersionInput) (*types.CreateDraftPolicyVersionPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.PolicyID.TenantID())
|
||||
// CreateDraftDocumentVersion is the resolver for the createDraftDocumentVersion field.
|
||||
func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.DocumentID.TenantID())
|
||||
|
||||
user := UserFromContext(ctx)
|
||||
people, err := svc.Peoples.GetByUserID(ctx, user.ID)
|
||||
@@ -1214,36 +1214,36 @@ func (r *mutationResolver) CreateDraftPolicyVersion(ctx context.Context, input t
|
||||
panic(fmt.Errorf("cannot get people: %w", err))
|
||||
}
|
||||
|
||||
policyVersion, err := svc.Policies.CreateDraft(ctx, input.PolicyID, people.ID)
|
||||
documentVersion, err := svc.Documents.CreateDraft(ctx, input.DocumentID, people.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot create draft policy version: %w", err))
|
||||
panic(fmt.Errorf("cannot create draft document version: %w", err))
|
||||
}
|
||||
|
||||
return &types.CreateDraftPolicyVersionPayload{
|
||||
PolicyVersionEdge: types.NewPolicyVersionEdge(policyVersion, coredata.PolicyVersionOrderFieldCreatedAt),
|
||||
return &types.CreateDraftDocumentVersionPayload{
|
||||
DocumentVersionEdge: types.NewDocumentVersionEdge(documentVersion, coredata.DocumentVersionOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdatePolicyVersion is the resolver for the updatePolicyVersion field.
|
||||
func (r *mutationResolver) UpdatePolicyVersion(ctx context.Context, input types.UpdatePolicyVersionInput) (*types.UpdatePolicyVersionPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.PolicyVersionID.TenantID())
|
||||
// UpdateDocumentVersion is the resolver for the updateDocumentVersion field.
|
||||
func (r *mutationResolver) UpdateDocumentVersion(ctx context.Context, input types.UpdateDocumentVersionInput) (*types.UpdateDocumentVersionPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.DocumentVersionID.TenantID())
|
||||
|
||||
policyVersion, err := svc.Policies.UpdateVersion(ctx, probo.UpdatePolicyVersionRequest{
|
||||
ID: input.PolicyVersionID,
|
||||
documentVersion, err := svc.Documents.UpdateVersion(ctx, probo.UpdateDocumentVersionRequest{
|
||||
ID: input.DocumentVersionID,
|
||||
Content: input.Content,
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot update policy version: %w", err))
|
||||
panic(fmt.Errorf("cannot update document version: %w", err))
|
||||
}
|
||||
|
||||
return &types.UpdatePolicyVersionPayload{
|
||||
PolicyVersion: types.NewPolicyVersion(policyVersion),
|
||||
return &types.UpdateDocumentVersionPayload{
|
||||
DocumentVersion: types.NewDocumentVersion(documentVersion),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RequestSignature is the resolver for the requestSignature field.
|
||||
func (r *mutationResolver) RequestSignature(ctx context.Context, input types.RequestSignatureInput) (*types.RequestSignaturePayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.PolicyVersionID.TenantID())
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.DocumentVersionID.TenantID())
|
||||
|
||||
user := UserFromContext(ctx)
|
||||
|
||||
@@ -1252,12 +1252,12 @@ func (r *mutationResolver) RequestSignature(ctx context.Context, input types.Req
|
||||
panic(fmt.Errorf("cannot get people: %w", err))
|
||||
}
|
||||
|
||||
policyVersionSignature, err := svc.Policies.RequestSignature(
|
||||
documentVersionSignature, err := svc.Documents.RequestSignature(
|
||||
ctx,
|
||||
probo.RequestSignatureRequest{
|
||||
PolicyVersionID: input.PolicyVersionID,
|
||||
RequestedBy: people.ID,
|
||||
Signatory: input.SignatoryID,
|
||||
DocumentVersionID: input.DocumentVersionID,
|
||||
RequestedBy: people.ID,
|
||||
Signatory: input.SignatoryID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -1265,7 +1265,7 @@ func (r *mutationResolver) RequestSignature(ctx context.Context, input types.Req
|
||||
}
|
||||
|
||||
return &types.RequestSignaturePayload{
|
||||
PolicyVersionSignatureEdge: types.NewPolicyVersionSignatureEdge(policyVersionSignature, coredata.PolicyVersionSignatureOrderFieldCreatedAt),
|
||||
DocumentVersionSignatureEdge: types.NewDocumentVersionSignatureEdge(documentVersionSignature, coredata.DocumentVersionSignatureOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1273,7 +1273,7 @@ func (r *mutationResolver) RequestSignature(ctx context.Context, input types.Req
|
||||
func (r *mutationResolver) SendSigningNotifications(ctx context.Context, input types.SendSigningNotificationsInput) (*types.SendSigningNotificationsPayload, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, input.OrganizationID.TenantID())
|
||||
|
||||
err := svc.Policies.SendSigningNotifications(ctx, input.OrganizationID)
|
||||
err := svc.Documents.SendSigningNotifications(ctx, input.OrganizationID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot send signing notifications: %w", err))
|
||||
}
|
||||
@@ -1467,16 +1467,16 @@ func (r *organizationResolver) Peoples(ctx context.Context, obj *types.Organizat
|
||||
return types.NewPeopleConnection(page), nil
|
||||
}
|
||||
|
||||
// Policies is the resolver for the policies field.
|
||||
func (r *organizationResolver) Policies(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PolicyOrderBy) (*types.PolicyConnection, error) {
|
||||
// Documents is the resolver for the documents field.
|
||||
func (r *organizationResolver) Documents(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.DocumentConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.PolicyOrderField]{
|
||||
Field: coredata.PolicyOrderFieldTitle,
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldTitle,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.PolicyOrderField]{
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
@@ -1484,12 +1484,12 @@ func (r *organizationResolver) Policies(ctx context.Context, obj *types.Organiza
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := svc.Policies.ListByOrganizationID(ctx, obj.ID, cursor)
|
||||
page, err := svc.Documents.ListByOrganizationID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list organization policies: %w", err))
|
||||
panic(fmt.Errorf("cannot list organization documents: %w", err))
|
||||
}
|
||||
|
||||
return types.NewPolicyConnection(page), nil
|
||||
return types.NewDocumentConnection(page), nil
|
||||
}
|
||||
|
||||
// Measures is the resolver for the measures field.
|
||||
@@ -1568,16 +1568,16 @@ func (r *organizationResolver) Tasks(ctx context.Context, obj *types.Organizatio
|
||||
}
|
||||
|
||||
// Owner is the resolver for the owner field.
|
||||
func (r *policyResolver) Owner(ctx context.Context, obj *types.Policy) (*types.People, error) {
|
||||
func (r *documentResolver) Owner(ctx context.Context, obj *types.Document) (*types.People, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policy, err := svc.Policies.Get(ctx, obj.ID)
|
||||
document, err := svc.Documents.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy: %w", err))
|
||||
panic(fmt.Errorf("cannot get document: %w", err))
|
||||
}
|
||||
|
||||
// Get the owner
|
||||
owner, err := svc.Peoples.Get(ctx, policy.OwnerID)
|
||||
owner, err := svc.Peoples.Get(ctx, document.OwnerID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get owner: %w", err))
|
||||
}
|
||||
@@ -1586,15 +1586,15 @@ func (r *policyResolver) Owner(ctx context.Context, obj *types.Policy) (*types.P
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *policyResolver) Organization(ctx context.Context, obj *types.Policy) (*types.Organization, error) {
|
||||
func (r *documentResolver) Organization(ctx context.Context, obj *types.Document) (*types.Organization, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policy, err := svc.Policies.Get(ctx, obj.ID)
|
||||
document, err := svc.Documents.Get(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy: %w", err))
|
||||
panic(fmt.Errorf("cannot get document: %w", err))
|
||||
}
|
||||
|
||||
organization, err := svc.Organizations.Get(ctx, policy.OrganizationID)
|
||||
organization, err := svc.Organizations.Get(ctx, document.OrganizationID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get organization: %w", err))
|
||||
}
|
||||
@@ -1603,15 +1603,15 @@ func (r *policyResolver) Organization(ctx context.Context, obj *types.Policy) (*
|
||||
}
|
||||
|
||||
// Versions is the resolver for the versions field.
|
||||
func (r *policyResolver) Versions(ctx context.Context, obj *types.Policy, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PolicyVersionOrderBy, filter *types.PolicyVersionFilter) (*types.PolicyVersionConnection, error) {
|
||||
func (r *documentResolver) Versions(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionOrderBy, filter *types.DocumentVersionFilter) (*types.DocumentVersionConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.PolicyVersionOrderField]{
|
||||
Field: coredata.PolicyVersionOrderFieldCreatedAt,
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentVersionOrderField]{
|
||||
Field: coredata.DocumentVersionOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.PolicyVersionOrderField]{
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentVersionOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
@@ -1619,16 +1619,16 @@ func (r *policyResolver) Versions(ctx context.Context, obj *types.Policy, first
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := svc.Policies.ListVersions(ctx, obj.ID, cursor)
|
||||
page, err := svc.Documents.ListVersions(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list policy versions: %w", err))
|
||||
panic(fmt.Errorf("cannot list document versions: %w", err))
|
||||
}
|
||||
|
||||
return types.NewPolicyVersionConnection(page), nil
|
||||
return types.NewDocumentVersionConnection(page), nil
|
||||
}
|
||||
|
||||
// Controls is the resolver for the controls field.
|
||||
func (r *policyResolver) Controls(ctx context.Context, obj *types.Policy, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy) (*types.ControlConnection, error) {
|
||||
func (r *documentResolver) Controls(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy) (*types.ControlConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.ControlOrderField]{
|
||||
@@ -1644,41 +1644,41 @@ func (r *policyResolver) Controls(ctx context.Context, obj *types.Policy, first
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := svc.Controls.ListForPolicyID(ctx, obj.ID, cursor)
|
||||
page, err := svc.Controls.ListForDocumentID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list policy controls: %w", err))
|
||||
panic(fmt.Errorf("cannot list document controls: %w", err))
|
||||
}
|
||||
|
||||
return types.NewControlConnection(page), nil
|
||||
}
|
||||
|
||||
// Policy is the resolver for the policy field.
|
||||
func (r *policyVersionResolver) Policy(ctx context.Context, obj *types.PolicyVersion) (*types.Policy, error) {
|
||||
// Document is the resolver for the document field.
|
||||
func (r *documentVersionResolver) Document(ctx context.Context, obj *types.DocumentVersion) (*types.Document, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policyVersion, err := svc.Policies.GetVersion(ctx, obj.ID)
|
||||
documentVersion, err := svc.Documents.GetVersion(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version: %w", err))
|
||||
}
|
||||
|
||||
policy, err := svc.Policies.Get(ctx, policyVersion.PolicyID)
|
||||
document, err := svc.Documents.Get(ctx, documentVersion.DocumentID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy: %w", err))
|
||||
panic(fmt.Errorf("cannot get document: %w", err))
|
||||
}
|
||||
|
||||
return types.NewPolicy(policy), nil
|
||||
return types.NewDocument(document), nil
|
||||
}
|
||||
|
||||
// Signatures is the resolver for the signatures field.
|
||||
func (r *policyVersionResolver) Signatures(ctx context.Context, obj *types.PolicyVersion, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PolicyVersionSignatureOrder) (*types.PolicyVersionSignatureConnection, error) {
|
||||
func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.DocumentVersion, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder) (*types.DocumentVersionSignatureConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.PolicyVersionSignatureOrderField]{
|
||||
Field: coredata.PolicyVersionSignatureOrderFieldCreatedAt,
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentVersionSignatureOrderField]{
|
||||
Field: coredata.DocumentVersionSignatureOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.PolicyVersionSignatureOrderField]{
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentVersionSignatureOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
@@ -1686,28 +1686,28 @@ func (r *policyVersionResolver) Signatures(ctx context.Context, obj *types.Polic
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := svc.Policies.ListSignatures(ctx, obj.ID, cursor)
|
||||
page, err := svc.Documents.ListSignatures(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list policy version signatures: %w", err))
|
||||
panic(fmt.Errorf("cannot list document version signatures: %w", err))
|
||||
}
|
||||
|
||||
return types.NewPolicyVersionSignatureConnection(page), nil
|
||||
return types.NewDocumentVersionSignatureConnection(page), nil
|
||||
}
|
||||
|
||||
// PublishedBy is the resolver for the publishedBy field.
|
||||
func (r *policyVersionResolver) PublishedBy(ctx context.Context, obj *types.PolicyVersion) (*types.People, error) {
|
||||
func (r *documentVersionResolver) PublishedBy(ctx context.Context, obj *types.DocumentVersion) (*types.People, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policyVersion, err := svc.Policies.GetVersion(ctx, obj.ID)
|
||||
documentVersion, err := svc.Documents.GetVersion(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version: %w", err))
|
||||
}
|
||||
|
||||
if policyVersion.PublishedBy == nil {
|
||||
if documentVersion.PublishedBy == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
people, err := svc.Peoples.Get(ctx, *policyVersion.PublishedBy)
|
||||
people, err := svc.Peoples.Get(ctx, *documentVersion.PublishedBy)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get people: %w", err))
|
||||
}
|
||||
@@ -1715,33 +1715,33 @@ func (r *policyVersionResolver) PublishedBy(ctx context.Context, obj *types.Poli
|
||||
return types.NewPeople(people), nil
|
||||
}
|
||||
|
||||
// PolicyVersion is the resolver for the policyVersion field.
|
||||
func (r *policyVersionSignatureResolver) PolicyVersion(ctx context.Context, obj *types.PolicyVersionSignature) (*types.PolicyVersion, error) {
|
||||
// DocumentVersion is the resolver for the documentVersion field.
|
||||
func (r *documentVersionSignatureResolver) DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policyVersionSignature, err := svc.Policies.GetVersionSignature(ctx, obj.ID)
|
||||
documentVersionSignature, err := svc.Documents.GetVersionSignature(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version signature: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version signature: %w", err))
|
||||
}
|
||||
|
||||
policyVersion, err := svc.Policies.GetVersion(ctx, policyVersionSignature.PolicyVersionID)
|
||||
documentVersion, err := svc.Documents.GetVersion(ctx, documentVersionSignature.DocumentVersionID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version: %w", err))
|
||||
}
|
||||
|
||||
return types.NewPolicyVersion(policyVersion), nil
|
||||
return types.NewDocumentVersion(documentVersion), nil
|
||||
}
|
||||
|
||||
// SignedBy is the resolver for the signedBy field.
|
||||
func (r *policyVersionSignatureResolver) SignedBy(ctx context.Context, obj *types.PolicyVersionSignature) (*types.People, error) {
|
||||
func (r *documentVersionSignatureResolver) SignedBy(ctx context.Context, obj *types.DocumentVersionSignature) (*types.People, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policyVersionSignature, err := svc.Policies.GetVersionSignature(ctx, obj.ID)
|
||||
documentVersionSignature, err := svc.Documents.GetVersionSignature(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version signature: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version signature: %w", err))
|
||||
}
|
||||
|
||||
people, err := svc.Peoples.Get(ctx, policyVersionSignature.SignedBy)
|
||||
people, err := svc.Peoples.Get(ctx, documentVersionSignature.SignedBy)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get people: %w", err))
|
||||
}
|
||||
@@ -1750,15 +1750,15 @@ func (r *policyVersionSignatureResolver) SignedBy(ctx context.Context, obj *type
|
||||
}
|
||||
|
||||
// RequestedBy is the resolver for the requestedBy field.
|
||||
func (r *policyVersionSignatureResolver) RequestedBy(ctx context.Context, obj *types.PolicyVersionSignature) (*types.People, error) {
|
||||
func (r *documentVersionSignatureResolver) RequestedBy(ctx context.Context, obj *types.DocumentVersionSignature) (*types.People, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
policyVersionSignature, err := svc.Policies.GetVersionSignature(ctx, obj.ID)
|
||||
documentVersionSignature, err := svc.Documents.GetVersionSignature(ctx, obj.ID)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version signature: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version signature: %w", err))
|
||||
}
|
||||
|
||||
people, err := svc.Peoples.Get(ctx, policyVersionSignature.RequestedBy)
|
||||
people, err := svc.Peoples.Get(ctx, documentVersionSignature.RequestedBy)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get people: %w", err))
|
||||
}
|
||||
@@ -1820,12 +1820,12 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
}
|
||||
|
||||
return types.NewEvidence(evidence), nil
|
||||
case coredata.PolicyEntityType:
|
||||
policy, err := svc.Policies.Get(ctx, id)
|
||||
case coredata.DocumentEntityType:
|
||||
document, err := svc.Documents.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy: %w", err))
|
||||
panic(fmt.Errorf("cannot get document: %w", err))
|
||||
}
|
||||
return types.NewPolicy(policy), nil
|
||||
return types.NewDocument(document), nil
|
||||
case coredata.ControlEntityType:
|
||||
control, err := svc.Controls.Get(ctx, id)
|
||||
if err != nil {
|
||||
@@ -1845,18 +1845,18 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
panic(fmt.Errorf("cannot get vendor compliance report: %w", err))
|
||||
}
|
||||
return types.NewVendorComplianceReport(vendorComplianceReport), nil
|
||||
case coredata.PolicyVersionEntityType:
|
||||
policyVersion, err := svc.Policies.GetVersion(ctx, id)
|
||||
case coredata.DocumentVersionEntityType:
|
||||
documentVersion, err := svc.Documents.GetVersion(ctx, id)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version: %w", err))
|
||||
}
|
||||
return types.NewPolicyVersion(policyVersion), nil
|
||||
case coredata.PolicyVersionSignatureEntityType:
|
||||
policyVersionSignature, err := svc.Policies.GetVersionSignature(ctx, id)
|
||||
return types.NewDocumentVersion(documentVersion), nil
|
||||
case coredata.DocumentVersionSignatureEntityType:
|
||||
documentVersionSignature, err := svc.Documents.GetVersionSignature(ctx, id)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot get policy version signature: %w", err))
|
||||
panic(fmt.Errorf("cannot get document version signature: %w", err))
|
||||
}
|
||||
return types.NewPolicyVersionSignature(policyVersionSignature), nil
|
||||
return types.NewDocumentVersionSignature(documentVersionSignature), nil
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -1937,16 +1937,16 @@ func (r *riskResolver) Measures(ctx context.Context, obj *types.Risk, first *int
|
||||
return types.NewMeasureConnection(page), nil
|
||||
}
|
||||
|
||||
// Policies is the resolver for the policies field.
|
||||
func (r *riskResolver) Policies(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PolicyOrderBy) (*types.PolicyConnection, error) {
|
||||
// Documents is the resolver for the documents field.
|
||||
func (r *riskResolver) Documents(ctx context.Context, obj *types.Risk, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy) (*types.DocumentConnection, error) {
|
||||
svc := GetTenantService(ctx, r.proboSvc, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.PolicyOrderField]{
|
||||
Field: coredata.PolicyOrderFieldCreatedAt,
|
||||
pageOrderBy := page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: coredata.DocumentOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.PolicyOrderField]{
|
||||
pageOrderBy = page.OrderBy[coredata.DocumentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
@@ -1954,12 +1954,12 @@ func (r *riskResolver) Policies(ctx context.Context, obj *types.Risk, first *int
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := svc.Policies.ListForRiskID(ctx, obj.ID, cursor)
|
||||
page, err := svc.Documents.ListForRiskID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot list risk policies: %w", err))
|
||||
panic(fmt.Errorf("cannot list risk documents: %w", err))
|
||||
}
|
||||
|
||||
return types.NewPolicyConnection(page), nil
|
||||
return types.NewDocumentConnection(page), nil
|
||||
}
|
||||
|
||||
// Controls is the resolver for the controls field.
|
||||
@@ -2283,15 +2283,17 @@ func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver
|
||||
// Organization returns schema.OrganizationResolver implementation.
|
||||
func (r *Resolver) Organization() schema.OrganizationResolver { return &organizationResolver{r} }
|
||||
|
||||
// Policy returns schema.PolicyResolver implementation.
|
||||
func (r *Resolver) Policy() schema.PolicyResolver { return &policyResolver{r} }
|
||||
// Document returns schema.DocumentResolver implementation.
|
||||
func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} }
|
||||
|
||||
// PolicyVersion returns schema.PolicyVersionResolver implementation.
|
||||
func (r *Resolver) PolicyVersion() schema.PolicyVersionResolver { return &policyVersionResolver{r} }
|
||||
// DocumentVersion returns schema.DocumentVersionResolver implementation.
|
||||
func (r *Resolver) DocumentVersion() schema.DocumentVersionResolver {
|
||||
return &documentVersionResolver{r}
|
||||
}
|
||||
|
||||
// PolicyVersionSignature returns schema.PolicyVersionSignatureResolver implementation.
|
||||
func (r *Resolver) PolicyVersionSignature() schema.PolicyVersionSignatureResolver {
|
||||
return &policyVersionSignatureResolver{r}
|
||||
// DocumentVersionSignature returns schema.DocumentVersionSignatureResolver implementation.
|
||||
func (r *Resolver) DocumentVersionSignature() schema.DocumentVersionSignatureResolver {
|
||||
return &documentVersionSignatureResolver{r}
|
||||
}
|
||||
|
||||
// Query returns schema.QueryResolver implementation.
|
||||
@@ -2328,9 +2330,9 @@ type frameworkResolver struct{ *Resolver }
|
||||
type measureResolver struct{ *Resolver }
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type organizationResolver struct{ *Resolver }
|
||||
type policyResolver struct{ *Resolver }
|
||||
type policyVersionResolver struct{ *Resolver }
|
||||
type policyVersionSignatureResolver struct{ *Resolver }
|
||||
type documentResolver struct{ *Resolver }
|
||||
type documentVersionResolver struct{ *Resolver }
|
||||
type documentVersionSignatureResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
type riskResolver struct{ *Resolver }
|
||||
type taskResolver struct{ *Resolver }
|
||||
|
||||
Reference in New Issue
Block a user