Add configurable compliance portal commitment cards
The compliance portal home page rendered security-commitment cards from a hardcoded placeholder POJO. Back them with real, per-organization data that admins configure in the console and the portal loads over the trust center GraphQL API. Model two entities under the trust center: a commitment group (title, description, rank) and a commitment card (icon, eyebrow, title, description, rank). The card icon is a curated enum mapped to a Phosphor icon in the portal. New entities adopt the compliance_portal_ prefix as the start of the broader rename away from trust_center_ naming. Expose the groups and cards read-only on the public trust API and with full CRUD on the console API, add a Commitments tab to the compliance page, and replace the placeholder section with a Relay-driven one. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
416
pkg/coredata/compliance_portal_commitment.go
Normal file
416
pkg/coredata/compliance_portal_commitment.go
Normal file
@@ -0,0 +1,416 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/iam/policy"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
CompliancePortalCommitment struct {
|
||||
ID gid.GID `db:"id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
TrustCenterID gid.GID `db:"trust_center_id"`
|
||||
GroupID gid.GID `db:"group_id"`
|
||||
Icon CompliancePortalCommitmentIcon `db:"icon"`
|
||||
Eyebrow string `db:"eyebrow"`
|
||||
Title string `db:"title"`
|
||||
Description string `db:"description"`
|
||||
Rank int `db:"rank"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
CompliancePortalCommitments []*CompliancePortalCommitment
|
||||
)
|
||||
|
||||
func (t CompliancePortalCommitment) CursorKey(orderBy CompliancePortalCommitmentOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case CompliancePortalCommitmentOrderFieldRank:
|
||||
return page.NewCursorKey(t.ID, t.Rank)
|
||||
case CompliancePortalCommitmentOrderFieldCreatedAt:
|
||||
return page.NewCursorKey(t.ID, t.CreatedAt)
|
||||
case CompliancePortalCommitmentOrderFieldUpdatedAt:
|
||||
return page.NewCursorKey(t.ID, t.UpdatedAt)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitment) AuthorizationAttributes(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
resourceIDs []gid.GID,
|
||||
) (policy.AttributesByID, error) {
|
||||
q := `SELECT id, organization_id FROM compliance_portal_commitments WHERE id = ANY(@resource_ids::text[])`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"resource_ids": resourceIDs,
|
||||
}
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot query authorization attributes: %w", err)
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
attrsByID := make(policy.AttributesByID)
|
||||
|
||||
for rows.Next() {
|
||||
var id, organizationID gid.GID
|
||||
|
||||
if err := rows.Scan(&id, &organizationID); err != nil {
|
||||
return nil, fmt.Errorf("cannot scan authorization attributes: %w", err)
|
||||
}
|
||||
|
||||
attrsByID[id] = policy.Attributes{
|
||||
"organization_id": organizationID.String(),
|
||||
}
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("cannot iterate authorization attributes: %w", err)
|
||||
}
|
||||
|
||||
return attrsByID, nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitment) LoadByID(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
scope Scoper,
|
||||
commitmentID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
group_id,
|
||||
icon,
|
||||
eyebrow,
|
||||
title,
|
||||
description,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
compliance_portal_commitments
|
||||
WHERE
|
||||
%s
|
||||
AND id = @commitment_id
|
||||
LIMIT 1;
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"commitment_id": commitmentID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query compliance_portal_commitments: %w", err)
|
||||
}
|
||||
|
||||
commitment, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CompliancePortalCommitment])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
*t = commitment
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitment) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO
|
||||
compliance_portal_commitments (
|
||||
tenant_id,
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
group_id,
|
||||
icon,
|
||||
eyebrow,
|
||||
title,
|
||||
description,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
@tenant_id,
|
||||
@id,
|
||||
@organization_id,
|
||||
@trust_center_id,
|
||||
@group_id,
|
||||
@icon,
|
||||
@eyebrow,
|
||||
@title,
|
||||
@description,
|
||||
(SELECT COALESCE(MAX(rank), 0) + 1 FROM compliance_portal_commitments WHERE group_id = @group_id),
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
RETURNING rank;
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"id": t.ID,
|
||||
"organization_id": t.OrganizationID,
|
||||
"trust_center_id": t.TrustCenterID,
|
||||
"group_id": t.GroupID,
|
||||
"icon": t.Icon,
|
||||
"eyebrow": t.Eyebrow,
|
||||
"title": t.Title,
|
||||
"description": t.Description,
|
||||
"created_at": t.CreatedAt,
|
||||
"updated_at": t.UpdatedAt,
|
||||
}
|
||||
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&t.Rank)
|
||||
if err != nil {
|
||||
if pgErr, ok := errors.AsType[*pgconn.PgError](err); ok {
|
||||
if pgErr.Code == "23505" && pgErr.ConstraintName == "compliance_portal_commitments_group_id_rank_key" {
|
||||
return ErrResourceAlreadyExists
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot insert compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitment) Update(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
UPDATE compliance_portal_commitments
|
||||
SET
|
||||
icon = @icon,
|
||||
eyebrow = @eyebrow,
|
||||
title = @title,
|
||||
description = @description,
|
||||
updated_at = @updated_at
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id;
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": t.ID,
|
||||
"icon": t.Icon,
|
||||
"eyebrow": t.Eyebrow,
|
||||
"title": t.Title,
|
||||
"description": t.Description,
|
||||
"updated_at": t.UpdatedAt,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
result, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
if result.RowsAffected() == 0 {
|
||||
return ErrResourceNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitment) UpdateRank(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
WITH old AS (
|
||||
SELECT
|
||||
rank AS old_rank
|
||||
FROM compliance_portal_commitments
|
||||
WHERE %s AND id = @id AND group_id = @group_id
|
||||
)
|
||||
UPDATE compliance_portal_commitments
|
||||
SET
|
||||
rank = CASE
|
||||
WHEN id = @id THEN @new_rank
|
||||
ELSE rank + CASE
|
||||
WHEN @new_rank < old.old_rank THEN 1
|
||||
WHEN @new_rank > old.old_rank THEN -1
|
||||
END
|
||||
END,
|
||||
updated_at = @updated_at
|
||||
FROM old
|
||||
WHERE %s
|
||||
AND group_id = @group_id
|
||||
AND (
|
||||
id = @id
|
||||
OR (rank BETWEEN LEAST(old.old_rank, @new_rank) AND GREATEST(old.old_rank, @new_rank))
|
||||
);
|
||||
`
|
||||
|
||||
scopeFragment := scope.SQLFragment()
|
||||
q = fmt.Sprintf(q, scopeFragment, scopeFragment)
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": t.ID,
|
||||
"new_rank": t.Rank,
|
||||
"group_id": t.GroupID,
|
||||
"updated_at": t.UpdatedAt,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update compliance portal commitment rank: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitment) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
DELETE FROM
|
||||
compliance_portal_commitments
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"id": t.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot delete compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitments) LoadByGroupID(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
scope Scoper,
|
||||
groupID gid.GID,
|
||||
cursor *page.Cursor[CompliancePortalCommitmentOrderField],
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
group_id,
|
||||
icon,
|
||||
eyebrow,
|
||||
title,
|
||||
description,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
compliance_portal_commitments
|
||||
WHERE
|
||||
%s
|
||||
AND group_id = @group_id
|
||||
AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"group_id": groupID}
|
||||
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 compliance_portal_commitments: %w", err)
|
||||
}
|
||||
|
||||
commitments, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[CompliancePortalCommitment])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect compliance portal commitments: %w", err)
|
||||
}
|
||||
|
||||
*t = commitments
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitments) CountByGroupID(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
scope Scoper,
|
||||
groupID gid.GID,
|
||||
) (int, error) {
|
||||
q := `
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
compliance_portal_commitments
|
||||
WHERE
|
||||
%s
|
||||
AND group_id = @group_id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"group_id": groupID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
var count int
|
||||
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("cannot count compliance portal commitments: %w", err)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
393
pkg/coredata/compliance_portal_commitment_group.go
Normal file
393
pkg/coredata/compliance_portal_commitment_group.go
Normal file
@@ -0,0 +1,393 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/iam/policy"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
CompliancePortalCommitmentGroup struct {
|
||||
ID gid.GID `db:"id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
TrustCenterID gid.GID `db:"trust_center_id"`
|
||||
Title string `db:"title"`
|
||||
Description string `db:"description"`
|
||||
Rank int `db:"rank"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
CompliancePortalCommitmentGroups []*CompliancePortalCommitmentGroup
|
||||
)
|
||||
|
||||
func (t CompliancePortalCommitmentGroup) CursorKey(orderBy CompliancePortalCommitmentGroupOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case CompliancePortalCommitmentGroupOrderFieldRank:
|
||||
return page.NewCursorKey(t.ID, t.Rank)
|
||||
case CompliancePortalCommitmentGroupOrderFieldCreatedAt:
|
||||
return page.NewCursorKey(t.ID, t.CreatedAt)
|
||||
case CompliancePortalCommitmentGroupOrderFieldUpdatedAt:
|
||||
return page.NewCursorKey(t.ID, t.UpdatedAt)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroup) AuthorizationAttributes(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
resourceIDs []gid.GID,
|
||||
) (policy.AttributesByID, error) {
|
||||
q := `SELECT id, organization_id FROM compliance_portal_commitment_groups WHERE id = ANY(@resource_ids::text[])`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"resource_ids": resourceIDs,
|
||||
}
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot query authorization attributes: %w", err)
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
attrsByID := make(policy.AttributesByID)
|
||||
|
||||
for rows.Next() {
|
||||
var id, organizationID gid.GID
|
||||
|
||||
if err := rows.Scan(&id, &organizationID); err != nil {
|
||||
return nil, fmt.Errorf("cannot scan authorization attributes: %w", err)
|
||||
}
|
||||
|
||||
attrsByID[id] = policy.Attributes{
|
||||
"organization_id": organizationID.String(),
|
||||
}
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("cannot iterate authorization attributes: %w", err)
|
||||
}
|
||||
|
||||
return attrsByID, nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroup) LoadByID(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
scope Scoper,
|
||||
groupID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
title,
|
||||
description,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
compliance_portal_commitment_groups
|
||||
WHERE
|
||||
%s
|
||||
AND id = @group_id
|
||||
LIMIT 1;
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"group_id": groupID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query compliance_portal_commitment_groups: %w", err)
|
||||
}
|
||||
|
||||
group, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CompliancePortalCommitmentGroup])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
*t = group
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroup) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO
|
||||
compliance_portal_commitment_groups (
|
||||
tenant_id,
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
title,
|
||||
description,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
@tenant_id,
|
||||
@id,
|
||||
@organization_id,
|
||||
@trust_center_id,
|
||||
@title,
|
||||
@description,
|
||||
(SELECT COALESCE(MAX(rank), 0) + 1 FROM compliance_portal_commitment_groups WHERE trust_center_id = @trust_center_id),
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
RETURNING rank;
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"id": t.ID,
|
||||
"organization_id": t.OrganizationID,
|
||||
"trust_center_id": t.TrustCenterID,
|
||||
"title": t.Title,
|
||||
"description": t.Description,
|
||||
"created_at": t.CreatedAt,
|
||||
"updated_at": t.UpdatedAt,
|
||||
}
|
||||
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&t.Rank)
|
||||
if err != nil {
|
||||
if pgErr, ok := errors.AsType[*pgconn.PgError](err); ok {
|
||||
if pgErr.Code == "23505" && pgErr.ConstraintName == "compliance_portal_commitment_groups_trust_center_id_rank_key" {
|
||||
return ErrResourceAlreadyExists
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot insert compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroup) Update(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
UPDATE compliance_portal_commitment_groups
|
||||
SET
|
||||
title = @title,
|
||||
description = @description,
|
||||
updated_at = @updated_at
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id;
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": t.ID,
|
||||
"title": t.Title,
|
||||
"description": t.Description,
|
||||
"updated_at": t.UpdatedAt,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
result, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
if result.RowsAffected() == 0 {
|
||||
return ErrResourceNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroup) UpdateRank(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
WITH old AS (
|
||||
SELECT
|
||||
rank AS old_rank
|
||||
FROM compliance_portal_commitment_groups
|
||||
WHERE %s AND id = @id AND trust_center_id = @trust_center_id
|
||||
)
|
||||
UPDATE compliance_portal_commitment_groups
|
||||
SET
|
||||
rank = CASE
|
||||
WHEN id = @id THEN @new_rank
|
||||
ELSE rank + CASE
|
||||
WHEN @new_rank < old.old_rank THEN 1
|
||||
WHEN @new_rank > old.old_rank THEN -1
|
||||
END
|
||||
END,
|
||||
updated_at = @updated_at
|
||||
FROM old
|
||||
WHERE %s
|
||||
AND (
|
||||
id = @id
|
||||
OR (rank BETWEEN LEAST(old.old_rank, @new_rank) AND GREATEST(old.old_rank, @new_rank))
|
||||
);
|
||||
`
|
||||
|
||||
scopeFragment := scope.SQLFragment()
|
||||
q = fmt.Sprintf(q, scopeFragment, scopeFragment)
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"id": t.ID,
|
||||
"new_rank": t.Rank,
|
||||
"trust_center_id": t.TrustCenterID,
|
||||
"updated_at": t.UpdatedAt,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot update compliance portal commitment group rank: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroup) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Tx,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
DELETE FROM
|
||||
compliance_portal_commitment_groups
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"id": t.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot delete compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroups) LoadByTrustCenterID(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
scope Scoper,
|
||||
trustCenterID gid.GID,
|
||||
cursor *page.Cursor[CompliancePortalCommitmentGroupOrderField],
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
title,
|
||||
description,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
compliance_portal_commitment_groups
|
||||
WHERE
|
||||
%s
|
||||
AND trust_center_id = @trust_center_id
|
||||
AND %s
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"trust_center_id": trustCenterID}
|
||||
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 compliance_portal_commitment_groups: %w", err)
|
||||
}
|
||||
|
||||
groups, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[CompliancePortalCommitmentGroup])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect compliance portal commitment groups: %w", err)
|
||||
}
|
||||
|
||||
*t = groups
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *CompliancePortalCommitmentGroups) CountByTrustCenterID(
|
||||
ctx context.Context,
|
||||
conn pg.Querier,
|
||||
scope Scoper,
|
||||
trustCenterID gid.GID,
|
||||
) (int, error) {
|
||||
q := `
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
compliance_portal_commitment_groups
|
||||
WHERE
|
||||
%s
|
||||
AND trust_center_id = @trust_center_id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"trust_center_id": trustCenterID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
var count int
|
||||
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("cannot count compliance portal commitment groups: %w", err)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
CompliancePortalCommitmentGroupOrderField string
|
||||
)
|
||||
|
||||
const (
|
||||
CompliancePortalCommitmentGroupOrderFieldRank CompliancePortalCommitmentGroupOrderField = "RANK"
|
||||
CompliancePortalCommitmentGroupOrderFieldCreatedAt CompliancePortalCommitmentGroupOrderField = "CREATED_AT"
|
||||
CompliancePortalCommitmentGroupOrderFieldUpdatedAt CompliancePortalCommitmentGroupOrderField = "UPDATED_AT"
|
||||
)
|
||||
|
||||
var (
|
||||
_ page.OrderField = CompliancePortalCommitmentGroupOrderField("")
|
||||
_ fmt.Stringer = CompliancePortalCommitmentGroupOrderField("")
|
||||
_ encoding.TextMarshaler = CompliancePortalCommitmentGroupOrderField("")
|
||||
_ encoding.TextUnmarshaler = (*CompliancePortalCommitmentGroupOrderField)(nil)
|
||||
)
|
||||
|
||||
func CompliancePortalCommitmentGroupOrderFields() []CompliancePortalCommitmentGroupOrderField {
|
||||
return []CompliancePortalCommitmentGroupOrderField{
|
||||
CompliancePortalCommitmentGroupOrderFieldRank,
|
||||
CompliancePortalCommitmentGroupOrderFieldCreatedAt,
|
||||
CompliancePortalCommitmentGroupOrderFieldUpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentGroupOrderField) IsValid() bool {
|
||||
switch v {
|
||||
case
|
||||
CompliancePortalCommitmentGroupOrderFieldRank,
|
||||
CompliancePortalCommitmentGroupOrderFieldCreatedAt,
|
||||
CompliancePortalCommitmentGroupOrderFieldUpdatedAt:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentGroupOrderField) String() string {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentGroupOrderField) MarshalText() ([]byte, error) {
|
||||
return []byte(v.String()), nil
|
||||
}
|
||||
|
||||
func (v *CompliancePortalCommitmentGroupOrderField) UnmarshalText(text []byte) error {
|
||||
val := CompliancePortalCommitmentGroupOrderField(text)
|
||||
if !val.IsValid() {
|
||||
return fmt.Errorf("invalid CompliancePortalCommitmentGroupOrderField value: %q", string(text))
|
||||
}
|
||||
|
||||
*v = val
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p CompliancePortalCommitmentGroupOrderField) Column() string {
|
||||
switch p {
|
||||
case CompliancePortalCommitmentGroupOrderFieldRank:
|
||||
return "rank"
|
||||
case CompliancePortalCommitmentGroupOrderFieldCreatedAt:
|
||||
return "created_at"
|
||||
case CompliancePortalCommitmentGroupOrderFieldUpdatedAt:
|
||||
return "updated_at"
|
||||
default:
|
||||
return string(p)
|
||||
}
|
||||
}
|
||||
130
pkg/coredata/compliance_portal_commitment_icon.go
Normal file
130
pkg/coredata/compliance_portal_commitment_icon.go
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type CompliancePortalCommitmentIcon string
|
||||
|
||||
const (
|
||||
CompliancePortalCommitmentIconLockKey CompliancePortalCommitmentIcon = "LOCK_KEY"
|
||||
CompliancePortalCommitmentIconEyeSlash CompliancePortalCommitmentIcon = "EYE_SLASH"
|
||||
CompliancePortalCommitmentIconFingerprint CompliancePortalCommitmentIcon = "FINGERPRINT"
|
||||
CompliancePortalCommitmentIconShieldWarning CompliancePortalCommitmentIcon = "SHIELD_WARNING"
|
||||
CompliancePortalCommitmentIconShieldCheck CompliancePortalCommitmentIcon = "SHIELD_CHECK"
|
||||
CompliancePortalCommitmentIconSiren CompliancePortalCommitmentIcon = "SIREN"
|
||||
CompliancePortalCommitmentIconKey CompliancePortalCommitmentIcon = "KEY"
|
||||
CompliancePortalCommitmentIconLock CompliancePortalCommitmentIcon = "LOCK"
|
||||
CompliancePortalCommitmentIconCloud CompliancePortalCommitmentIcon = "CLOUD"
|
||||
CompliancePortalCommitmentIconDatabase CompliancePortalCommitmentIcon = "DATABASE"
|
||||
CompliancePortalCommitmentIconGlobe CompliancePortalCommitmentIcon = "GLOBE"
|
||||
CompliancePortalCommitmentIconEye CompliancePortalCommitmentIcon = "EYE"
|
||||
CompliancePortalCommitmentIconUsers CompliancePortalCommitmentIcon = "USERS"
|
||||
CompliancePortalCommitmentIconCertificate CompliancePortalCommitmentIcon = "CERTIFICATE"
|
||||
CompliancePortalCommitmentIconGavel CompliancePortalCommitmentIcon = "GAVEL"
|
||||
CompliancePortalCommitmentIconHeartbeat CompliancePortalCommitmentIcon = "HEARTBEAT"
|
||||
CompliancePortalCommitmentIconBell CompliancePortalCommitmentIcon = "BELL"
|
||||
CompliancePortalCommitmentIconBug CompliancePortalCommitmentIcon = "BUG"
|
||||
CompliancePortalCommitmentIconCode CompliancePortalCommitmentIcon = "CODE"
|
||||
CompliancePortalCommitmentIconServer CompliancePortalCommitmentIcon = "SERVER"
|
||||
)
|
||||
|
||||
var (
|
||||
_ fmt.Stringer = CompliancePortalCommitmentIcon("")
|
||||
_ encoding.TextMarshaler = CompliancePortalCommitmentIcon("")
|
||||
_ encoding.TextUnmarshaler = (*CompliancePortalCommitmentIcon)(nil)
|
||||
)
|
||||
|
||||
func CompliancePortalCommitmentIcons() []CompliancePortalCommitmentIcon {
|
||||
return []CompliancePortalCommitmentIcon{
|
||||
CompliancePortalCommitmentIconLockKey,
|
||||
CompliancePortalCommitmentIconEyeSlash,
|
||||
CompliancePortalCommitmentIconFingerprint,
|
||||
CompliancePortalCommitmentIconShieldWarning,
|
||||
CompliancePortalCommitmentIconShieldCheck,
|
||||
CompliancePortalCommitmentIconSiren,
|
||||
CompliancePortalCommitmentIconKey,
|
||||
CompliancePortalCommitmentIconLock,
|
||||
CompliancePortalCommitmentIconCloud,
|
||||
CompliancePortalCommitmentIconDatabase,
|
||||
CompliancePortalCommitmentIconGlobe,
|
||||
CompliancePortalCommitmentIconEye,
|
||||
CompliancePortalCommitmentIconUsers,
|
||||
CompliancePortalCommitmentIconCertificate,
|
||||
CompliancePortalCommitmentIconGavel,
|
||||
CompliancePortalCommitmentIconHeartbeat,
|
||||
CompliancePortalCommitmentIconBell,
|
||||
CompliancePortalCommitmentIconBug,
|
||||
CompliancePortalCommitmentIconCode,
|
||||
CompliancePortalCommitmentIconServer,
|
||||
}
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentIcon) IsValid() bool {
|
||||
switch v {
|
||||
case
|
||||
CompliancePortalCommitmentIconLockKey,
|
||||
CompliancePortalCommitmentIconEyeSlash,
|
||||
CompliancePortalCommitmentIconFingerprint,
|
||||
CompliancePortalCommitmentIconShieldWarning,
|
||||
CompliancePortalCommitmentIconShieldCheck,
|
||||
CompliancePortalCommitmentIconSiren,
|
||||
CompliancePortalCommitmentIconKey,
|
||||
CompliancePortalCommitmentIconLock,
|
||||
CompliancePortalCommitmentIconCloud,
|
||||
CompliancePortalCommitmentIconDatabase,
|
||||
CompliancePortalCommitmentIconGlobe,
|
||||
CompliancePortalCommitmentIconEye,
|
||||
CompliancePortalCommitmentIconUsers,
|
||||
CompliancePortalCommitmentIconCertificate,
|
||||
CompliancePortalCommitmentIconGavel,
|
||||
CompliancePortalCommitmentIconHeartbeat,
|
||||
CompliancePortalCommitmentIconBell,
|
||||
CompliancePortalCommitmentIconBug,
|
||||
CompliancePortalCommitmentIconCode,
|
||||
CompliancePortalCommitmentIconServer:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentIcon) String() string {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentIcon) MarshalText() ([]byte, error) {
|
||||
return []byte(v.String()), nil
|
||||
}
|
||||
|
||||
func (v *CompliancePortalCommitmentIcon) UnmarshalText(text []byte) error {
|
||||
val := CompliancePortalCommitmentIcon(text)
|
||||
if !val.IsValid() {
|
||||
return fmt.Errorf("invalid CompliancePortalCommitmentIcon value: %q", string(text))
|
||||
}
|
||||
|
||||
*v = val
|
||||
|
||||
return nil
|
||||
}
|
||||
97
pkg/coredata/compliance_portal_commitment_order_field.go
Normal file
97
pkg/coredata/compliance_portal_commitment_order_field.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"fmt"
|
||||
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
CompliancePortalCommitmentOrderField string
|
||||
)
|
||||
|
||||
const (
|
||||
CompliancePortalCommitmentOrderFieldRank CompliancePortalCommitmentOrderField = "RANK"
|
||||
CompliancePortalCommitmentOrderFieldCreatedAt CompliancePortalCommitmentOrderField = "CREATED_AT"
|
||||
CompliancePortalCommitmentOrderFieldUpdatedAt CompliancePortalCommitmentOrderField = "UPDATED_AT"
|
||||
)
|
||||
|
||||
var (
|
||||
_ page.OrderField = CompliancePortalCommitmentOrderField("")
|
||||
_ fmt.Stringer = CompliancePortalCommitmentOrderField("")
|
||||
_ encoding.TextMarshaler = CompliancePortalCommitmentOrderField("")
|
||||
_ encoding.TextUnmarshaler = (*CompliancePortalCommitmentOrderField)(nil)
|
||||
)
|
||||
|
||||
func CompliancePortalCommitmentOrderFields() []CompliancePortalCommitmentOrderField {
|
||||
return []CompliancePortalCommitmentOrderField{
|
||||
CompliancePortalCommitmentOrderFieldRank,
|
||||
CompliancePortalCommitmentOrderFieldCreatedAt,
|
||||
CompliancePortalCommitmentOrderFieldUpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentOrderField) IsValid() bool {
|
||||
switch v {
|
||||
case
|
||||
CompliancePortalCommitmentOrderFieldRank,
|
||||
CompliancePortalCommitmentOrderFieldCreatedAt,
|
||||
CompliancePortalCommitmentOrderFieldUpdatedAt:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentOrderField) String() string {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
func (v CompliancePortalCommitmentOrderField) MarshalText() ([]byte, error) {
|
||||
return []byte(v.String()), nil
|
||||
}
|
||||
|
||||
func (v *CompliancePortalCommitmentOrderField) UnmarshalText(text []byte) error {
|
||||
val := CompliancePortalCommitmentOrderField(text)
|
||||
if !val.IsValid() {
|
||||
return fmt.Errorf("invalid CompliancePortalCommitmentOrderField value: %q", string(text))
|
||||
}
|
||||
|
||||
*v = val
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p CompliancePortalCommitmentOrderField) Column() string {
|
||||
switch p {
|
||||
case CompliancePortalCommitmentOrderFieldRank:
|
||||
return "rank"
|
||||
case CompliancePortalCommitmentOrderFieldCreatedAt:
|
||||
return "created_at"
|
||||
case CompliancePortalCommitmentOrderFieldUpdatedAt:
|
||||
return "updated_at"
|
||||
default:
|
||||
return string(p)
|
||||
}
|
||||
}
|
||||
@@ -133,6 +133,8 @@ const (
|
||||
RiskAssessmentBoundaryEntityType uint16 = 101
|
||||
AccessReviewCampaignSourceEntityType uint16 = 102
|
||||
AccessReviewCampaignSourceFetchAttemptEntityType uint16 = 103
|
||||
CompliancePortalCommitmentGroupEntityType uint16 = 104
|
||||
CompliancePortalCommitmentEntityType uint16 = 105
|
||||
)
|
||||
|
||||
func NewEntityFromID(id gid.GID) (any, bool) {
|
||||
@@ -327,6 +329,10 @@ func NewEntityFromID(id gid.GID) (any, bool) {
|
||||
return &AccessReviewCampaignSource{ID: id}, true
|
||||
case AccessReviewCampaignSourceFetchAttemptEntityType:
|
||||
return &AccessReviewCampaignSourceFetchAttempt{ID: id}, true
|
||||
case CompliancePortalCommitmentGroupEntityType:
|
||||
return &CompliancePortalCommitmentGroup{ID: id}, true
|
||||
case CompliancePortalCommitmentEntityType:
|
||||
return &CompliancePortalCommitment{ID: id}, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
|
||||
53
pkg/coredata/migrations/20260716T084447Z.sql
Normal file
53
pkg/coredata/migrations/20260716T084447Z.sql
Normal file
@@ -0,0 +1,53 @@
|
||||
-- Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
--
|
||||
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
-- of this software and associated documentation files (the "Software"), to deal
|
||||
-- in the Software without restriction, including without limitation the rights
|
||||
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
-- copies of the Software, and to permit persons to whom the Software is
|
||||
-- furnished to do so, subject to the following conditions:
|
||||
--
|
||||
-- The above copyright notice and this permission notice shall be included in
|
||||
-- all copies or substantial portions of the Software.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
-- SOFTWARE.
|
||||
|
||||
CREATE TABLE compliance_portal_commitment_groups (
|
||||
id TEXT PRIMARY KEY,
|
||||
tenant_id TEXT NOT NULL,
|
||||
organization_id TEXT NOT NULL REFERENCES organizations(id)
|
||||
ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
trust_center_id TEXT NOT NULL REFERENCES trust_centers(id)
|
||||
ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
rank INTEGER NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
UNIQUE (trust_center_id, rank)
|
||||
);
|
||||
|
||||
CREATE TABLE compliance_portal_commitments (
|
||||
id TEXT PRIMARY KEY,
|
||||
tenant_id TEXT NOT NULL,
|
||||
organization_id TEXT NOT NULL REFERENCES organizations(id)
|
||||
ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
trust_center_id TEXT NOT NULL REFERENCES trust_centers(id)
|
||||
ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
group_id TEXT NOT NULL REFERENCES compliance_portal_commitment_groups(id)
|
||||
ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
icon TEXT NOT NULL,
|
||||
eyebrow TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
rank INTEGER NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
UNIQUE (group_id, rank)
|
||||
);
|
||||
@@ -69,6 +69,20 @@ const (
|
||||
ActionTrustCenterReferenceUpdate = "core:trust-center-reference:update"
|
||||
ActionTrustCenterReferenceDelete = "core:trust-center-reference:delete"
|
||||
|
||||
// CompliancePortalCommitmentGroup actions
|
||||
ActionCompliancePortalCommitmentGroupList = "core:compliance-portal-commitment-group:list"
|
||||
ActionCompliancePortalCommitmentGroupCreate = "core:compliance-portal-commitment-group:create"
|
||||
ActionCompliancePortalCommitmentGroupUpdate = "core:compliance-portal-commitment-group:update"
|
||||
ActionCompliancePortalCommitmentGroupUpdateRank = "core:compliance-portal-commitment-group:update-rank"
|
||||
ActionCompliancePortalCommitmentGroupDelete = "core:compliance-portal-commitment-group:delete"
|
||||
|
||||
// CompliancePortalCommitment actions
|
||||
ActionCompliancePortalCommitmentList = "core:compliance-portal-commitment:list"
|
||||
ActionCompliancePortalCommitmentCreate = "core:compliance-portal-commitment:create"
|
||||
ActionCompliancePortalCommitmentUpdate = "core:compliance-portal-commitment:update"
|
||||
ActionCompliancePortalCommitmentUpdateRank = "core:compliance-portal-commitment:update-rank"
|
||||
ActionCompliancePortalCommitmentDelete = "core:compliance-portal-commitment:delete"
|
||||
|
||||
// ComplianceFramework actions
|
||||
ActionComplianceFrameworkList = "core:compliance-framework:list"
|
||||
ActionComplianceFrameworkCreate = "core:compliance-framework:create"
|
||||
|
||||
257
pkg/probo/compliance_portal_commitment_group_service.go
Normal file
257
pkg/probo/compliance_portal_commitment_group_service.go
Normal file
@@ -0,0 +1,257 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package probo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/validator"
|
||||
)
|
||||
|
||||
type (
|
||||
CompliancePortalCommitmentGroupService struct {
|
||||
svc *Service
|
||||
}
|
||||
|
||||
CreateCompliancePortalCommitmentGroupRequest struct {
|
||||
TrustCenterID gid.GID
|
||||
Title string
|
||||
Description string
|
||||
}
|
||||
|
||||
UpdateCompliancePortalCommitmentGroupRequest struct {
|
||||
ID gid.GID
|
||||
Title *string
|
||||
Description *string
|
||||
Rank *int
|
||||
}
|
||||
)
|
||||
|
||||
func (r *CreateCompliancePortalCommitmentGroupRequest) Validate() error {
|
||||
v := validator.New()
|
||||
|
||||
v.Check(r.TrustCenterID, "trust_center_id", validator.Required(), validator.GID(coredata.TrustCenterEntityType))
|
||||
v.Check(r.Title, "title", validator.Required(), validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(r.Description, "description", validator.SafeText(ContentMaxLength))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
|
||||
func (r *UpdateCompliancePortalCommitmentGroupRequest) Validate() error {
|
||||
v := validator.New()
|
||||
|
||||
v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.CompliancePortalCommitmentGroupEntityType))
|
||||
v.Check(r.Title, "title", validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(r.Description, "description", validator.SafeText(ContentMaxLength))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) ListForTrustCenterID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
cursor *page.Cursor[coredata.CompliancePortalCommitmentGroupOrderField],
|
||||
) (*page.Page[*coredata.CompliancePortalCommitmentGroup, coredata.CompliancePortalCommitmentGroupOrderField], error) {
|
||||
var groups coredata.CompliancePortalCommitmentGroups
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error {
|
||||
err := groups.LoadByTrustCenterID(ctx, conn, scope, trustCenterID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment groups: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(groups, cursor), nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) CountForTrustCenterID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
) (int, error) {
|
||||
var count int
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) (err error) {
|
||||
groups := coredata.CompliancePortalCommitmentGroups{}
|
||||
|
||||
count, err = groups.CountByTrustCenterID(ctx, conn, scope, trustCenterID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot count compliance portal commitment groups: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) Get(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
groupID gid.GID,
|
||||
) (*coredata.CompliancePortalCommitmentGroup, error) {
|
||||
var group coredata.CompliancePortalCommitmentGroup
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error {
|
||||
err := group.LoadByID(ctx, conn, scope, groupID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &group, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) Create(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
req *CreateCompliancePortalCommitmentGroupRequest,
|
||||
) (*coredata.CompliancePortalCommitmentGroup, error) {
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
groupID := gid.New(scope.GetTenantID(), coredata.CompliancePortalCommitmentGroupEntityType)
|
||||
|
||||
var group *coredata.CompliancePortalCommitmentGroup
|
||||
|
||||
err := s.svc.pg.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, tx, scope, req.TrustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
}
|
||||
|
||||
group = &coredata.CompliancePortalCommitmentGroup{
|
||||
ID: groupID,
|
||||
OrganizationID: trustCenter.OrganizationID,
|
||||
TrustCenterID: req.TrustCenterID,
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
if err := group.Insert(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot insert compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) Update(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
req *UpdateCompliancePortalCommitmentGroupRequest,
|
||||
) (*coredata.CompliancePortalCommitmentGroup, error) {
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
var group *coredata.CompliancePortalCommitmentGroup
|
||||
|
||||
err := s.svc.pg.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error {
|
||||
group = &coredata.CompliancePortalCommitmentGroup{}
|
||||
|
||||
if err := group.LoadByID(ctx, tx, scope, req.ID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
if req.Title != nil {
|
||||
group.Title = *req.Title
|
||||
}
|
||||
|
||||
if req.Description != nil {
|
||||
group.Description = *req.Description
|
||||
}
|
||||
|
||||
group.UpdatedAt = now
|
||||
|
||||
if req.Rank != nil {
|
||||
group.Rank = *req.Rank
|
||||
if err := group.UpdateRank(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot update rank: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := group.Update(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot update compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) Delete(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
groupID gid.GID,
|
||||
) error {
|
||||
err := s.svc.pg.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error {
|
||||
group := &coredata.CompliancePortalCommitmentGroup{}
|
||||
|
||||
if err := group.LoadByID(ctx, tx, scope, groupID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
if err := group.Delete(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot delete compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
278
pkg/probo/compliance_portal_commitment_service.go
Normal file
278
pkg/probo/compliance_portal_commitment_service.go
Normal file
@@ -0,0 +1,278 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package probo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/validator"
|
||||
)
|
||||
|
||||
type (
|
||||
CompliancePortalCommitmentService struct {
|
||||
svc *Service
|
||||
}
|
||||
|
||||
CreateCompliancePortalCommitmentRequest struct {
|
||||
GroupID gid.GID
|
||||
Icon coredata.CompliancePortalCommitmentIcon
|
||||
Eyebrow string
|
||||
Title string
|
||||
Description string
|
||||
}
|
||||
|
||||
UpdateCompliancePortalCommitmentRequest struct {
|
||||
ID gid.GID
|
||||
Icon *coredata.CompliancePortalCommitmentIcon
|
||||
Eyebrow *string
|
||||
Title *string
|
||||
Description *string
|
||||
Rank *int
|
||||
}
|
||||
)
|
||||
|
||||
func (r *CreateCompliancePortalCommitmentRequest) Validate() error {
|
||||
v := validator.New()
|
||||
|
||||
v.Check(r.GroupID, "group_id", validator.Required(), validator.GID(coredata.CompliancePortalCommitmentGroupEntityType))
|
||||
v.Check(r.Icon, "icon", validator.Required(), validator.OneOfSlice(coredata.CompliancePortalCommitmentIcons()))
|
||||
v.Check(r.Eyebrow, "eyebrow", validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(r.Title, "title", validator.Required(), validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(r.Description, "description", validator.SafeText(ContentMaxLength))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
|
||||
func (r *UpdateCompliancePortalCommitmentRequest) Validate() error {
|
||||
v := validator.New()
|
||||
|
||||
v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.CompliancePortalCommitmentEntityType))
|
||||
if r.Icon != nil {
|
||||
v.Check(*r.Icon, "icon", validator.OneOfSlice(coredata.CompliancePortalCommitmentIcons()))
|
||||
}
|
||||
v.Check(r.Eyebrow, "eyebrow", validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(r.Title, "title", validator.SafeTextNoNewLine(TitleMaxLength))
|
||||
v.Check(r.Description, "description", validator.SafeText(ContentMaxLength))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) ListForGroupID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
groupID gid.GID,
|
||||
cursor *page.Cursor[coredata.CompliancePortalCommitmentOrderField],
|
||||
) (*page.Page[*coredata.CompliancePortalCommitment, coredata.CompliancePortalCommitmentOrderField], error) {
|
||||
var commitments coredata.CompliancePortalCommitments
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error {
|
||||
err := commitments.LoadByGroupID(ctx, conn, scope, groupID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitments: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(commitments, cursor), nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) CountForGroupID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
groupID gid.GID,
|
||||
) (int, error) {
|
||||
var count int
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) (err error) {
|
||||
commitments := coredata.CompliancePortalCommitments{}
|
||||
|
||||
count, err = commitments.CountByGroupID(ctx, conn, scope, groupID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot count compliance portal commitments: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) Get(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
commitmentID gid.GID,
|
||||
) (*coredata.CompliancePortalCommitment, error) {
|
||||
var commitment coredata.CompliancePortalCommitment
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error {
|
||||
err := commitment.LoadByID(ctx, conn, scope, commitmentID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &commitment, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) Create(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
req *CreateCompliancePortalCommitmentRequest,
|
||||
) (*coredata.CompliancePortalCommitment, error) {
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
commitmentID := gid.New(scope.GetTenantID(), coredata.CompliancePortalCommitmentEntityType)
|
||||
|
||||
var commitment *coredata.CompliancePortalCommitment
|
||||
|
||||
err := s.svc.pg.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error {
|
||||
group := &coredata.CompliancePortalCommitmentGroup{}
|
||||
if err := group.LoadByID(ctx, tx, scope, req.GroupID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
commitment = &coredata.CompliancePortalCommitment{
|
||||
ID: commitmentID,
|
||||
OrganizationID: group.OrganizationID,
|
||||
TrustCenterID: group.TrustCenterID,
|
||||
GroupID: req.GroupID,
|
||||
Icon: req.Icon,
|
||||
Eyebrow: req.Eyebrow,
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
if err := commitment.Insert(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot insert compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return commitment, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) Update(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
req *UpdateCompliancePortalCommitmentRequest,
|
||||
) (*coredata.CompliancePortalCommitment, error) {
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
var commitment *coredata.CompliancePortalCommitment
|
||||
|
||||
err := s.svc.pg.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error {
|
||||
commitment = &coredata.CompliancePortalCommitment{}
|
||||
|
||||
if err := commitment.LoadByID(ctx, tx, scope, req.ID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
if req.Icon != nil {
|
||||
commitment.Icon = *req.Icon
|
||||
}
|
||||
|
||||
if req.Eyebrow != nil {
|
||||
commitment.Eyebrow = *req.Eyebrow
|
||||
}
|
||||
|
||||
if req.Title != nil {
|
||||
commitment.Title = *req.Title
|
||||
}
|
||||
|
||||
if req.Description != nil {
|
||||
commitment.Description = *req.Description
|
||||
}
|
||||
|
||||
commitment.UpdatedAt = now
|
||||
|
||||
if req.Rank != nil {
|
||||
commitment.Rank = *req.Rank
|
||||
if err := commitment.UpdateRank(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot update rank: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := commitment.Update(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot update compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return commitment, nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) Delete(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
commitmentID gid.GID,
|
||||
) error {
|
||||
err := s.svc.pg.WithTx(ctx, func(ctx context.Context, tx pg.Tx) error {
|
||||
commitment := &coredata.CompliancePortalCommitment{}
|
||||
|
||||
if err := commitment.LoadByID(ctx, tx, scope, commitmentID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
if err := commitment.Delete(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot delete compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -108,6 +108,7 @@ var ViewerPolicy = policy.NewPolicy(
|
||||
ActionTrustCenterDocumentAccessList,
|
||||
ActionTrustCenterFileGet, ActionTrustCenterFileList, ActionTrustCenterFileGetFileUrl,
|
||||
ActionTrustCenterReferenceList, ActionTrustCenterReferenceGetLogoUrl,
|
||||
ActionCompliancePortalCommitmentGroupList, ActionCompliancePortalCommitmentList,
|
||||
ActionComplianceFrameworkList,
|
||||
).WithSID("trust-center-read-access").When(organizationCondition),
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ type (
|
||||
TrustCenters *TrustCenterService
|
||||
TrustCenterAccesses *TrustCenterAccessService
|
||||
TrustCenterReferences *TrustCenterReferenceService
|
||||
CompliancePortalCommitmentGroups *CompliancePortalCommitmentGroupService
|
||||
CompliancePortalCommitments *CompliancePortalCommitmentService
|
||||
TrustCenterFiles *TrustCenterFileService
|
||||
ComplianceFrameworks *ComplianceFrameworkService
|
||||
ComplianceExternalURLs *ComplianceExternalURLService
|
||||
@@ -235,6 +237,8 @@ func NewService(
|
||||
svc.TrustCenters = &TrustCenterService{svc: svc}
|
||||
svc.TrustCenterAccesses = &TrustCenterAccessService{svc: svc}
|
||||
svc.TrustCenterReferences = &TrustCenterReferenceService{svc: svc}
|
||||
svc.CompliancePortalCommitmentGroups = &CompliancePortalCommitmentGroupService{svc: svc}
|
||||
svc.CompliancePortalCommitments = &CompliancePortalCommitmentService{svc: svc}
|
||||
svc.ComplianceFrameworks = &ComplianceFrameworkService{svc: svc}
|
||||
svc.ComplianceExternalURLs = &ComplianceExternalURLService{svc: svc}
|
||||
svc.TrustCenterFiles = &TrustCenterFileService{
|
||||
|
||||
@@ -106,6 +106,88 @@ enum TrustCenterReferenceOrderField
|
||||
)
|
||||
}
|
||||
|
||||
enum CompliancePortalCommitmentGroupOrderField
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderField"
|
||||
) {
|
||||
RANK
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldRank"
|
||||
)
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldCreatedAt"
|
||||
)
|
||||
UPDATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentGroupOrderFieldUpdatedAt"
|
||||
)
|
||||
}
|
||||
|
||||
enum CompliancePortalCommitmentOrderField
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderField"
|
||||
) {
|
||||
RANK
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldRank"
|
||||
)
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldCreatedAt"
|
||||
)
|
||||
UPDATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentOrderFieldUpdatedAt"
|
||||
)
|
||||
}
|
||||
|
||||
enum CompliancePortalCommitmentIcon
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIcon"
|
||||
) {
|
||||
LOCK_KEY
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLockKey")
|
||||
EYE_SLASH
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEyeSlash")
|
||||
FINGERPRINT
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconFingerprint")
|
||||
SHIELD_WARNING
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldWarning")
|
||||
SHIELD_CHECK
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldCheck")
|
||||
SIREN
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconSiren")
|
||||
KEY
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconKey")
|
||||
LOCK
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLock")
|
||||
CLOUD
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCloud")
|
||||
DATABASE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconDatabase")
|
||||
GLOBE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGlobe")
|
||||
EYE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEye")
|
||||
USERS
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconUsers")
|
||||
CERTIFICATE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCertificate")
|
||||
GAVEL
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGavel")
|
||||
HEARTBEAT
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconHeartbeat")
|
||||
BELL
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBell")
|
||||
BUG
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBug")
|
||||
CODE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCode")
|
||||
SERVER
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconServer")
|
||||
}
|
||||
|
||||
enum ComplianceExternalURLOrderField
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderField"
|
||||
@@ -218,6 +300,22 @@ input TrustCenterReferenceOrder
|
||||
field: TrustCenterReferenceOrderField!
|
||||
}
|
||||
|
||||
input CompliancePortalCommitmentGroupOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentGroupOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: CompliancePortalCommitmentGroupOrderField!
|
||||
}
|
||||
|
||||
input CompliancePortalCommitmentOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: CompliancePortalCommitmentOrderField!
|
||||
}
|
||||
|
||||
input TrustCenterFileOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.TrustCenterFileOrderBy"
|
||||
@@ -272,6 +370,14 @@ type TrustCenter implements Node
|
||||
orderBy: TrustCenterReferenceOrder
|
||||
): TrustCenterReferenceConnection! @goField(forceResolver: true)
|
||||
|
||||
commitmentGroups(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: CompliancePortalCommitmentGroupOrder
|
||||
): CompliancePortalCommitmentGroupConnection! @goField(forceResolver: true)
|
||||
|
||||
complianceFrameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
@@ -389,6 +495,66 @@ type TrustCenterReferenceEdge {
|
||||
node: TrustCenterReference!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentGroup implements Node {
|
||||
id: ID!
|
||||
title: String!
|
||||
description: String!
|
||||
rank: Int!
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
commitments(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: CompliancePortalCommitmentOrder
|
||||
): CompliancePortalCommitmentConnection! @goField(forceResolver: true)
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentGroupConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentGroupConnection"
|
||||
) {
|
||||
totalCount: Int! @goField(forceResolver: true)
|
||||
edges: [CompliancePortalCommitmentGroupEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentGroupEdge {
|
||||
cursor: CursorKey!
|
||||
node: CompliancePortalCommitmentGroup!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitment implements Node {
|
||||
id: ID!
|
||||
icon: CompliancePortalCommitmentIcon!
|
||||
eyebrow: String!
|
||||
title: String!
|
||||
description: String!
|
||||
rank: Int!
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CompliancePortalCommitmentConnection"
|
||||
) {
|
||||
totalCount: Int! @goField(forceResolver: true)
|
||||
edges: [CompliancePortalCommitmentEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentEdge {
|
||||
cursor: CursorKey!
|
||||
node: CompliancePortalCommitment!
|
||||
}
|
||||
|
||||
type ComplianceFramework implements Node
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFramework"
|
||||
@@ -514,6 +680,24 @@ extend type Mutation {
|
||||
deleteTrustCenterReference(
|
||||
input: DeleteTrustCenterReferenceInput!
|
||||
): DeleteTrustCenterReferencePayload!
|
||||
createCompliancePortalCommitmentGroup(
|
||||
input: CreateCompliancePortalCommitmentGroupInput!
|
||||
): CreateCompliancePortalCommitmentGroupPayload!
|
||||
updateCompliancePortalCommitmentGroup(
|
||||
input: UpdateCompliancePortalCommitmentGroupInput!
|
||||
): UpdateCompliancePortalCommitmentGroupPayload!
|
||||
deleteCompliancePortalCommitmentGroup(
|
||||
input: DeleteCompliancePortalCommitmentGroupInput!
|
||||
): DeleteCompliancePortalCommitmentGroupPayload!
|
||||
createCompliancePortalCommitment(
|
||||
input: CreateCompliancePortalCommitmentInput!
|
||||
): CreateCompliancePortalCommitmentPayload!
|
||||
updateCompliancePortalCommitment(
|
||||
input: UpdateCompliancePortalCommitmentInput!
|
||||
): UpdateCompliancePortalCommitmentPayload!
|
||||
deleteCompliancePortalCommitment(
|
||||
input: DeleteCompliancePortalCommitmentInput!
|
||||
): DeleteCompliancePortalCommitmentPayload!
|
||||
createComplianceFramework(
|
||||
input: CreateComplianceFrameworkInput!
|
||||
): CreateComplianceFrameworkPayload!
|
||||
@@ -613,6 +797,44 @@ input DeleteTrustCenterReferenceInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input CreateCompliancePortalCommitmentGroupInput {
|
||||
trustCenterId: ID!
|
||||
title: String!
|
||||
description: String!
|
||||
}
|
||||
|
||||
input UpdateCompliancePortalCommitmentGroupInput {
|
||||
id: ID!
|
||||
title: String
|
||||
description: String
|
||||
rank: Int
|
||||
}
|
||||
|
||||
input DeleteCompliancePortalCommitmentGroupInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input CreateCompliancePortalCommitmentInput {
|
||||
groupId: ID!
|
||||
icon: CompliancePortalCommitmentIcon!
|
||||
eyebrow: String!
|
||||
title: String!
|
||||
description: String!
|
||||
}
|
||||
|
||||
input UpdateCompliancePortalCommitmentInput {
|
||||
id: ID!
|
||||
icon: CompliancePortalCommitmentIcon
|
||||
eyebrow: String
|
||||
title: String
|
||||
description: String
|
||||
rank: Int
|
||||
}
|
||||
|
||||
input DeleteCompliancePortalCommitmentInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input CreateComplianceFrameworkInput {
|
||||
trustCenterId: ID!
|
||||
frameworkId: ID!
|
||||
@@ -712,6 +934,30 @@ type DeleteTrustCenterReferencePayload {
|
||||
deletedTrustCenterReferenceId: ID!
|
||||
}
|
||||
|
||||
type CreateCompliancePortalCommitmentGroupPayload {
|
||||
compliancePortalCommitmentGroupEdge: CompliancePortalCommitmentGroupEdge!
|
||||
}
|
||||
|
||||
type UpdateCompliancePortalCommitmentGroupPayload {
|
||||
compliancePortalCommitmentGroup: CompliancePortalCommitmentGroup!
|
||||
}
|
||||
|
||||
type DeleteCompliancePortalCommitmentGroupPayload {
|
||||
deletedCompliancePortalCommitmentGroupId: ID!
|
||||
}
|
||||
|
||||
type CreateCompliancePortalCommitmentPayload {
|
||||
compliancePortalCommitmentEdge: CompliancePortalCommitmentEdge!
|
||||
}
|
||||
|
||||
type UpdateCompliancePortalCommitmentPayload {
|
||||
compliancePortalCommitment: CompliancePortalCommitment!
|
||||
}
|
||||
|
||||
type DeleteCompliancePortalCommitmentPayload {
|
||||
deletedCompliancePortalCommitmentId: ID!
|
||||
}
|
||||
|
||||
type CreateComplianceFrameworkPayload {
|
||||
complianceFrameworkEdge: ComplianceFrameworkEdge!
|
||||
}
|
||||
|
||||
@@ -51,6 +51,78 @@ func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.
|
||||
return types.NewFramework(framework), nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *compliancePortalCommitmentResolver) Permission(ctx context.Context, obj *types.CompliancePortalCommitment, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *compliancePortalCommitmentConnectionResolver) TotalCount(ctx context.Context, obj *types.CompliancePortalCommitmentConnection) (int, error) {
|
||||
scope, err := r.authorize(ctx, obj.ParentID, probo.ActionCompliancePortalCommitmentList)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count, err := r.probo.CompliancePortalCommitments.CountForGroupID(ctx, scope, obj.ParentID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count compliance portal commitments", log.Error(err))
|
||||
return 0, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Commitments is the resolver for the commitments field.
|
||||
func (r *compliancePortalCommitmentGroupResolver) Commitments(ctx context.Context, obj *types.CompliancePortalCommitmentGroup, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.CompliancePortalCommitmentOrderField]) (*types.CompliancePortalCommitmentConnection, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionCompliancePortalCommitmentList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentOrderField]{
|
||||
Field: coredata.CompliancePortalCommitmentOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.CompliancePortalCommitmentOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
result, err := r.probo.CompliancePortalCommitments.ListForGroupID(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list compliance portal commitments", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewCompliancePortalCommitmentConnection(result, obj.ID), nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *compliancePortalCommitmentGroupResolver) Permission(ctx context.Context, obj *types.CompliancePortalCommitmentGroup, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *compliancePortalCommitmentGroupConnectionResolver) TotalCount(ctx context.Context, obj *types.CompliancePortalCommitmentGroupConnection) (int, error) {
|
||||
scope, err := r.authorize(ctx, obj.ParentID, probo.ActionCompliancePortalCommitmentGroupList)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
count, err := r.probo.CompliancePortalCommitmentGroups.CountForTrustCenterID(ctx, scope, obj.ParentID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count compliance portal commitment groups", log.Error(err))
|
||||
return 0, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *customDomainResolver) Permission(ctx context.Context, obj *types.CustomDomain, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
@@ -364,6 +436,166 @@ func (r *mutationResolver) DeleteTrustCenterReference(ctx context.Context, input
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateCompliancePortalCommitmentGroup is the resolver for the createCompliancePortalCommitmentGroup field.
|
||||
func (r *mutationResolver) CreateCompliancePortalCommitmentGroup(ctx context.Context, input types.CreateCompliancePortalCommitmentGroupInput) (*types.CreateCompliancePortalCommitmentGroupPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionCompliancePortalCommitmentGroupCreate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
group, err := r.probo.CompliancePortalCommitmentGroups.Create(
|
||||
ctx, scope,
|
||||
&probo.CreateCompliancePortalCommitmentGroupRequest{
|
||||
TrustCenterID: input.TrustCenterID,
|
||||
Title: input.Title,
|
||||
Description: input.Description,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot create compliance portal commitment group", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.CreateCompliancePortalCommitmentGroupPayload{
|
||||
CompliancePortalCommitmentGroupEdge: types.NewCompliancePortalCommitmentGroupEdge(group, coredata.CompliancePortalCommitmentGroupOrderFieldRank),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateCompliancePortalCommitmentGroup is the resolver for the updateCompliancePortalCommitmentGroup field.
|
||||
func (r *mutationResolver) UpdateCompliancePortalCommitmentGroup(ctx context.Context, input types.UpdateCompliancePortalCommitmentGroupInput) (*types.UpdateCompliancePortalCommitmentGroupPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentGroupUpdate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
group, err := r.probo.CompliancePortalCommitmentGroups.Update(
|
||||
ctx, scope,
|
||||
&probo.UpdateCompliancePortalCommitmentGroupRequest{
|
||||
ID: input.ID,
|
||||
Title: input.Title,
|
||||
Description: input.Description,
|
||||
Rank: input.Rank,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot update compliance portal commitment group", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateCompliancePortalCommitmentGroupPayload{
|
||||
CompliancePortalCommitmentGroup: types.NewCompliancePortalCommitmentGroup(group),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteCompliancePortalCommitmentGroup is the resolver for the deleteCompliancePortalCommitmentGroup field.
|
||||
func (r *mutationResolver) DeleteCompliancePortalCommitmentGroup(ctx context.Context, input types.DeleteCompliancePortalCommitmentGroupInput) (*types.DeleteCompliancePortalCommitmentGroupPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentGroupDelete)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := r.probo.CompliancePortalCommitmentGroups.Delete(ctx, scope, input.ID); err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot delete compliance portal commitment group", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeleteCompliancePortalCommitmentGroupPayload{
|
||||
DeletedCompliancePortalCommitmentGroupID: input.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateCompliancePortalCommitment is the resolver for the createCompliancePortalCommitment field.
|
||||
func (r *mutationResolver) CreateCompliancePortalCommitment(ctx context.Context, input types.CreateCompliancePortalCommitmentInput) (*types.CreateCompliancePortalCommitmentPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.GroupID, probo.ActionCompliancePortalCommitmentCreate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commitment, err := r.probo.CompliancePortalCommitments.Create(
|
||||
ctx, scope,
|
||||
&probo.CreateCompliancePortalCommitmentRequest{
|
||||
GroupID: input.GroupID,
|
||||
Icon: input.Icon,
|
||||
Eyebrow: input.Eyebrow,
|
||||
Title: input.Title,
|
||||
Description: input.Description,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot create compliance portal commitment", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.CreateCompliancePortalCommitmentPayload{
|
||||
CompliancePortalCommitmentEdge: types.NewCompliancePortalCommitmentEdge(commitment, coredata.CompliancePortalCommitmentOrderFieldRank),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateCompliancePortalCommitment is the resolver for the updateCompliancePortalCommitment field.
|
||||
func (r *mutationResolver) UpdateCompliancePortalCommitment(ctx context.Context, input types.UpdateCompliancePortalCommitmentInput) (*types.UpdateCompliancePortalCommitmentPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentUpdate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commitment, err := r.probo.CompliancePortalCommitments.Update(
|
||||
ctx, scope,
|
||||
&probo.UpdateCompliancePortalCommitmentRequest{
|
||||
ID: input.ID,
|
||||
Icon: input.Icon,
|
||||
Eyebrow: input.Eyebrow,
|
||||
Title: input.Title,
|
||||
Description: input.Description,
|
||||
Rank: input.Rank,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot update compliance portal commitment", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateCompliancePortalCommitmentPayload{
|
||||
CompliancePortalCommitment: types.NewCompliancePortalCommitment(commitment),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteCompliancePortalCommitment is the resolver for the deleteCompliancePortalCommitment field.
|
||||
func (r *mutationResolver) DeleteCompliancePortalCommitment(ctx context.Context, input types.DeleteCompliancePortalCommitmentInput) (*types.DeleteCompliancePortalCommitmentPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.ID, probo.ActionCompliancePortalCommitmentDelete)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := r.probo.CompliancePortalCommitments.Delete(ctx, scope, input.ID); err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot delete compliance portal commitment", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeleteCompliancePortalCommitmentPayload{
|
||||
DeletedCompliancePortalCommitmentID: input.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateComplianceFramework is the resolver for the createComplianceFramework field.
|
||||
func (r *mutationResolver) CreateComplianceFramework(ctx context.Context, input types.CreateComplianceFrameworkInput) (*types.CreateComplianceFrameworkPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.TrustCenterID, probo.ActionComplianceFrameworkCreate)
|
||||
@@ -817,6 +1049,36 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe
|
||||
return types.NewTrustCenterReferenceConnection(result, obj.ID), nil
|
||||
}
|
||||
|
||||
// CommitmentGroups is the resolver for the commitmentGroups field.
|
||||
func (r *trustCenterResolver) CommitmentGroups(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]) (*types.CompliancePortalCommitmentGroupConnection, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionCompliancePortalCommitmentGroupList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]{
|
||||
Field: coredata.CompliancePortalCommitmentGroupOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
result, err := r.probo.CompliancePortalCommitmentGroups.ListForTrustCenterID(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list compliance portal commitment groups", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewCompliancePortalCommitmentGroupConnection(result, obj.ID), nil
|
||||
}
|
||||
|
||||
// ComplianceFrameworks is the resolver for the complianceFrameworks field.
|
||||
func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceFrameworkOrderField]) (*types.ComplianceFrameworkConnection, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionComplianceFrameworkList)
|
||||
@@ -1236,6 +1498,26 @@ func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver {
|
||||
return &complianceFrameworkResolver{r}
|
||||
}
|
||||
|
||||
// CompliancePortalCommitment returns schema.CompliancePortalCommitmentResolver implementation.
|
||||
func (r *Resolver) CompliancePortalCommitment() schema.CompliancePortalCommitmentResolver {
|
||||
return &compliancePortalCommitmentResolver{r}
|
||||
}
|
||||
|
||||
// CompliancePortalCommitmentConnection returns schema.CompliancePortalCommitmentConnectionResolver implementation.
|
||||
func (r *Resolver) CompliancePortalCommitmentConnection() schema.CompliancePortalCommitmentConnectionResolver {
|
||||
return &compliancePortalCommitmentConnectionResolver{r}
|
||||
}
|
||||
|
||||
// CompliancePortalCommitmentGroup returns schema.CompliancePortalCommitmentGroupResolver implementation.
|
||||
func (r *Resolver) CompliancePortalCommitmentGroup() schema.CompliancePortalCommitmentGroupResolver {
|
||||
return &compliancePortalCommitmentGroupResolver{r}
|
||||
}
|
||||
|
||||
// CompliancePortalCommitmentGroupConnection returns schema.CompliancePortalCommitmentGroupConnectionResolver implementation.
|
||||
func (r *Resolver) CompliancePortalCommitmentGroupConnection() schema.CompliancePortalCommitmentGroupConnectionResolver {
|
||||
return &compliancePortalCommitmentGroupConnectionResolver{r}
|
||||
}
|
||||
|
||||
// CustomDomain returns schema.CustomDomainResolver implementation.
|
||||
func (r *Resolver) CustomDomain() schema.CustomDomainResolver { return &customDomainResolver{r} }
|
||||
|
||||
@@ -1278,15 +1560,19 @@ func (r *Resolver) TrustCenterReferenceConnection() schema.TrustCenterReferenceC
|
||||
}
|
||||
|
||||
type (
|
||||
complianceExternalURLResolver struct{ *Resolver }
|
||||
complianceFrameworkResolver struct{ *Resolver }
|
||||
customDomainResolver struct{ *Resolver }
|
||||
trustCenterResolver struct{ *Resolver }
|
||||
trustCenterAccessResolver struct{ *Resolver }
|
||||
trustCenterDocumentAccessResolver struct{ *Resolver }
|
||||
trustCenterDocumentAccessConnectionResolver struct{ *Resolver }
|
||||
trustCenterFileResolver struct{ *Resolver }
|
||||
trustCenterFileConnectionResolver struct{ *Resolver }
|
||||
trustCenterReferenceResolver struct{ *Resolver }
|
||||
trustCenterReferenceConnectionResolver struct{ *Resolver }
|
||||
complianceExternalURLResolver struct{ *Resolver }
|
||||
complianceFrameworkResolver struct{ *Resolver }
|
||||
compliancePortalCommitmentResolver struct{ *Resolver }
|
||||
compliancePortalCommitmentConnectionResolver struct{ *Resolver }
|
||||
compliancePortalCommitmentGroupResolver struct{ *Resolver }
|
||||
compliancePortalCommitmentGroupConnectionResolver struct{ *Resolver }
|
||||
customDomainResolver struct{ *Resolver }
|
||||
trustCenterResolver struct{ *Resolver }
|
||||
trustCenterAccessResolver struct{ *Resolver }
|
||||
trustCenterDocumentAccessResolver struct{ *Resolver }
|
||||
trustCenterDocumentAccessConnectionResolver struct{ *Resolver }
|
||||
trustCenterFileResolver struct{ *Resolver }
|
||||
trustCenterFileConnectionResolver struct{ *Resolver }
|
||||
trustCenterReferenceResolver struct{ *Resolver }
|
||||
trustCenterReferenceConnectionResolver struct{ *Resolver }
|
||||
)
|
||||
|
||||
125
pkg/server/api/console/v1/types/compliance_portal_commitment.go
Normal file
125
pkg/server/api/console/v1/types/compliance_portal_commitment.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
CompliancePortalCommitmentGroupOrderBy = OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]
|
||||
|
||||
CompliancePortalCommitmentGroupConnection struct {
|
||||
TotalCount int `json:"totalCount"`
|
||||
Edges []*CompliancePortalCommitmentGroupEdge `json:"edges"`
|
||||
PageInfo *PageInfo `json:"pageInfo"`
|
||||
ParentID gid.GID `json:"-"`
|
||||
}
|
||||
|
||||
CompliancePortalCommitmentOrderBy = OrderBy[coredata.CompliancePortalCommitmentOrderField]
|
||||
|
||||
CompliancePortalCommitmentConnection struct {
|
||||
TotalCount int `json:"totalCount"`
|
||||
Edges []*CompliancePortalCommitmentEdge `json:"edges"`
|
||||
PageInfo *PageInfo `json:"pageInfo"`
|
||||
ParentID gid.GID `json:"-"`
|
||||
}
|
||||
)
|
||||
|
||||
func NewCompliancePortalCommitmentGroup(g *coredata.CompliancePortalCommitmentGroup) *CompliancePortalCommitmentGroup {
|
||||
return &CompliancePortalCommitmentGroup{
|
||||
ID: g.ID,
|
||||
Title: g.Title,
|
||||
Description: g.Description,
|
||||
Rank: g.Rank,
|
||||
CreatedAt: g.CreatedAt,
|
||||
UpdatedAt: g.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentGroupEdge(
|
||||
g *coredata.CompliancePortalCommitmentGroup,
|
||||
orderBy coredata.CompliancePortalCommitmentGroupOrderField,
|
||||
) *CompliancePortalCommitmentGroupEdge {
|
||||
return &CompliancePortalCommitmentGroupEdge{
|
||||
Cursor: g.CursorKey(orderBy),
|
||||
Node: NewCompliancePortalCommitmentGroup(g),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentGroupConnection(
|
||||
p *page.Page[*coredata.CompliancePortalCommitmentGroup, coredata.CompliancePortalCommitmentGroupOrderField],
|
||||
parentID gid.GID,
|
||||
) *CompliancePortalCommitmentGroupConnection {
|
||||
edges := make([]*CompliancePortalCommitmentGroupEdge, len(p.Data))
|
||||
|
||||
for i := range edges {
|
||||
edges[i] = NewCompliancePortalCommitmentGroupEdge(p.Data[i], p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &CompliancePortalCommitmentGroupConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(p),
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitment(c *coredata.CompliancePortalCommitment) *CompliancePortalCommitment {
|
||||
return &CompliancePortalCommitment{
|
||||
ID: c.ID,
|
||||
Icon: c.Icon,
|
||||
Eyebrow: c.Eyebrow,
|
||||
Title: c.Title,
|
||||
Description: c.Description,
|
||||
Rank: c.Rank,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentEdge(
|
||||
c *coredata.CompliancePortalCommitment,
|
||||
orderBy coredata.CompliancePortalCommitmentOrderField,
|
||||
) *CompliancePortalCommitmentEdge {
|
||||
return &CompliancePortalCommitmentEdge{
|
||||
Cursor: c.CursorKey(orderBy),
|
||||
Node: NewCompliancePortalCommitment(c),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentConnection(
|
||||
p *page.Page[*coredata.CompliancePortalCommitment, coredata.CompliancePortalCommitmentOrderField],
|
||||
parentID gid.GID,
|
||||
) *CompliancePortalCommitmentConnection {
|
||||
edges := make([]*CompliancePortalCommitmentEdge, len(p.Data))
|
||||
|
||||
for i := range edges {
|
||||
edges[i] = NewCompliancePortalCommitmentEdge(p.Data[i], p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &CompliancePortalCommitmentConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(p),
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,13 @@ type TrustCenter implements Node {
|
||||
before: CursorKey
|
||||
): TrustCenterReferenceConnection! @goField(forceResolver: true)
|
||||
|
||||
commitmentGroups(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): CompliancePortalCommitmentGroupConnection! @goField(forceResolver: true)
|
||||
|
||||
trustCenterFiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
@@ -304,6 +311,91 @@ type TrustCenterReferenceEdge @nda {
|
||||
node: TrustCenterReference!
|
||||
}
|
||||
|
||||
enum CompliancePortalCommitmentIcon
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIcon") {
|
||||
LOCK_KEY
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLockKey")
|
||||
EYE_SLASH
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEyeSlash")
|
||||
FINGERPRINT
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconFingerprint")
|
||||
SHIELD_WARNING
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldWarning")
|
||||
SHIELD_CHECK
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconShieldCheck")
|
||||
SIREN
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconSiren")
|
||||
KEY
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconKey")
|
||||
LOCK
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconLock")
|
||||
CLOUD
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCloud")
|
||||
DATABASE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconDatabase")
|
||||
GLOBE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGlobe")
|
||||
EYE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconEye")
|
||||
USERS
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconUsers")
|
||||
CERTIFICATE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCertificate")
|
||||
GAVEL
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconGavel")
|
||||
HEARTBEAT
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconHeartbeat")
|
||||
BELL
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBell")
|
||||
BUG
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconBug")
|
||||
CODE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconCode")
|
||||
SERVER
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.CompliancePortalCommitmentIconServer")
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentGroup implements Node {
|
||||
id: ID!
|
||||
title: String!
|
||||
description: String!
|
||||
|
||||
commitments(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): CompliancePortalCommitmentConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentGroupConnection {
|
||||
edges: [CompliancePortalCommitmentGroupEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentGroupEdge {
|
||||
cursor: CursorKey!
|
||||
node: CompliancePortalCommitmentGroup!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitment implements Node {
|
||||
id: ID!
|
||||
icon: CompliancePortalCommitmentIcon!
|
||||
eyebrow: String!
|
||||
title: String!
|
||||
description: String!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentConnection {
|
||||
edges: [CompliancePortalCommitmentEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type CompliancePortalCommitmentEdge {
|
||||
cursor: CursorKey!
|
||||
node: CompliancePortalCommitment!
|
||||
}
|
||||
|
||||
type TrustCenterFile implements Node @nda {
|
||||
id: ID!
|
||||
name: String!
|
||||
|
||||
@@ -175,6 +175,25 @@ func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.
|
||||
return types.NewFramework(framework), nil
|
||||
}
|
||||
|
||||
// Commitments is the resolver for the commitments field.
|
||||
func (r *compliancePortalCommitmentGroupResolver) Commitments(ctx context.Context, obj *types.CompliancePortalCommitmentGroup, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.CompliancePortalCommitmentConnection, error) {
|
||||
compliancePage := compliancepage.CompliancePageFromContext(ctx)
|
||||
scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID)
|
||||
pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentOrderField]{
|
||||
Field: coredata.CompliancePortalCommitmentOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
commitmentPage, err := r.trust.CompliancePortalCommitments.ListForGroupID(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list public compliance portal commitments", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewCompliancePortalCommitmentConnection(commitmentPage), nil
|
||||
}
|
||||
|
||||
// Alias is the resolver for the alias field.
|
||||
func (r *documentResolver) Alias(ctx context.Context, obj *types.Document) (*string, error) {
|
||||
return r.ResourceAliasResolver(ctx, obj.ID)
|
||||
@@ -897,6 +916,25 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe
|
||||
return types.NewTrustCenterReferenceConnection(referencePage), nil
|
||||
}
|
||||
|
||||
// CommitmentGroups is the resolver for the commitmentGroups field.
|
||||
func (r *trustCenterResolver) CommitmentGroups(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.CompliancePortalCommitmentGroupConnection, error) {
|
||||
compliancePage := compliancepage.CompliancePageFromContext(ctx)
|
||||
scope := coredata.NewScopeFromObjectID(compliancePage.OrganizationID)
|
||||
pageOrderBy := page.OrderBy[coredata.CompliancePortalCommitmentGroupOrderField]{
|
||||
Field: coredata.CompliancePortalCommitmentGroupOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
groupPage, err := r.trust.CompliancePortalCommitmentGroups.ListForTrustCenterID(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list public compliance portal commitment groups", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewCompliancePortalCommitmentGroupConnection(groupPage), nil
|
||||
}
|
||||
|
||||
// TrustCenterFiles is the resolver for the trustCenterFiles field.
|
||||
func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, filter *types.TrustCenterVisibilityFilter) (*types.TrustCenterFileConnection, error) {
|
||||
compliancePage := compliancepage.CompliancePageFromContext(ctx)
|
||||
@@ -1115,6 +1153,11 @@ func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver {
|
||||
return &complianceFrameworkResolver{r}
|
||||
}
|
||||
|
||||
// CompliancePortalCommitmentGroup returns schema.CompliancePortalCommitmentGroupResolver implementation.
|
||||
func (r *Resolver) CompliancePortalCommitmentGroup() schema.CompliancePortalCommitmentGroupResolver {
|
||||
return &compliancePortalCommitmentGroupResolver{r}
|
||||
}
|
||||
|
||||
// Document returns schema.DocumentResolver implementation.
|
||||
func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} }
|
||||
|
||||
@@ -1140,13 +1183,14 @@ func (r *Resolver) TrustCenterReference() schema.TrustCenterReferenceResolver {
|
||||
}
|
||||
|
||||
type (
|
||||
auditResolver struct{ *Resolver }
|
||||
auditReportResolver struct{ *Resolver }
|
||||
complianceFrameworkResolver struct{ *Resolver }
|
||||
documentResolver struct{ *Resolver }
|
||||
frameworkResolver struct{ *Resolver }
|
||||
subprocessorConnectionResolver struct{ *Resolver }
|
||||
trustCenterResolver struct{ *Resolver }
|
||||
trustCenterFileResolver struct{ *Resolver }
|
||||
trustCenterReferenceResolver struct{ *Resolver }
|
||||
auditResolver struct{ *Resolver }
|
||||
auditReportResolver struct{ *Resolver }
|
||||
complianceFrameworkResolver struct{ *Resolver }
|
||||
compliancePortalCommitmentGroupResolver struct{ *Resolver }
|
||||
documentResolver struct{ *Resolver }
|
||||
frameworkResolver struct{ *Resolver }
|
||||
subprocessorConnectionResolver struct{ *Resolver }
|
||||
trustCenterResolver struct{ *Resolver }
|
||||
trustCenterFileResolver struct{ *Resolver }
|
||||
trustCenterReferenceResolver struct{ *Resolver }
|
||||
)
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
func NewCompliancePortalCommitmentGroup(g *coredata.CompliancePortalCommitmentGroup) *CompliancePortalCommitmentGroup {
|
||||
return &CompliancePortalCommitmentGroup{
|
||||
ID: g.ID,
|
||||
Title: g.Title,
|
||||
Description: g.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentGroupConnection(
|
||||
p *page.Page[*coredata.CompliancePortalCommitmentGroup, coredata.CompliancePortalCommitmentGroupOrderField],
|
||||
) *CompliancePortalCommitmentGroupConnection {
|
||||
edges := make([]*CompliancePortalCommitmentGroupEdge, len(p.Data))
|
||||
|
||||
for i, item := range p.Data {
|
||||
edges[i] = NewCompliancePortalCommitmentGroupEdge(item, p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &CompliancePortalCommitmentGroupConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(p),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentGroupEdge(
|
||||
g *coredata.CompliancePortalCommitmentGroup,
|
||||
orderBy coredata.CompliancePortalCommitmentGroupOrderField,
|
||||
) *CompliancePortalCommitmentGroupEdge {
|
||||
return &CompliancePortalCommitmentGroupEdge{
|
||||
Cursor: g.CursorKey(orderBy),
|
||||
Node: NewCompliancePortalCommitmentGroup(g),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitment(c *coredata.CompliancePortalCommitment) *CompliancePortalCommitment {
|
||||
return &CompliancePortalCommitment{
|
||||
ID: c.ID,
|
||||
Icon: c.Icon,
|
||||
Eyebrow: c.Eyebrow,
|
||||
Title: c.Title,
|
||||
Description: c.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentConnection(
|
||||
p *page.Page[*coredata.CompliancePortalCommitment, coredata.CompliancePortalCommitmentOrderField],
|
||||
) *CompliancePortalCommitmentConnection {
|
||||
edges := make([]*CompliancePortalCommitmentEdge, len(p.Data))
|
||||
|
||||
for i, item := range p.Data {
|
||||
edges[i] = NewCompliancePortalCommitmentEdge(item, p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &CompliancePortalCommitmentConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(p),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCompliancePortalCommitmentEdge(
|
||||
c *coredata.CompliancePortalCommitment,
|
||||
orderBy coredata.CompliancePortalCommitmentOrderField,
|
||||
) *CompliancePortalCommitmentEdge {
|
||||
return &CompliancePortalCommitmentEdge{
|
||||
Cursor: c.CursorKey(orderBy),
|
||||
Node: NewCompliancePortalCommitment(c),
|
||||
}
|
||||
}
|
||||
83
pkg/trust/compliance_portal_commitment_group_service.go
Normal file
83
pkg/trust/compliance_portal_commitment_group_service.go
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package trust
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type CompliancePortalCommitmentGroupService struct {
|
||||
svc *Service
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) ListForTrustCenterID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
cursor *page.Cursor[coredata.CompliancePortalCommitmentGroupOrderField],
|
||||
) (*page.Page[*coredata.CompliancePortalCommitmentGroup, coredata.CompliancePortalCommitmentGroupOrderField], error) {
|
||||
var groups coredata.CompliancePortalCommitmentGroups
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error {
|
||||
err := groups.LoadByTrustCenterID(ctx, conn, scope, trustCenterID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment groups: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(groups, cursor), nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentGroupService) Get(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
groupID gid.GID,
|
||||
) (*coredata.CompliancePortalCommitmentGroup, error) {
|
||||
group := &coredata.CompliancePortalCommitmentGroup{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := group.LoadByID(ctx, conn, scope, groupID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment group: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return group, nil
|
||||
}
|
||||
83
pkg/trust/compliance_portal_commitment_service.go
Normal file
83
pkg/trust/compliance_portal_commitment_service.go
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
package trust
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type CompliancePortalCommitmentService struct {
|
||||
svc *Service
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) ListForGroupID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
groupID gid.GID,
|
||||
cursor *page.Cursor[coredata.CompliancePortalCommitmentOrderField],
|
||||
) (*page.Page[*coredata.CompliancePortalCommitment, coredata.CompliancePortalCommitmentOrderField], error) {
|
||||
var commitments coredata.CompliancePortalCommitments
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(ctx context.Context, conn pg.Querier) error {
|
||||
err := commitments.LoadByGroupID(ctx, conn, scope, groupID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitments: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(commitments, cursor), nil
|
||||
}
|
||||
|
||||
func (s CompliancePortalCommitmentService) Get(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
commitmentID gid.GID,
|
||||
) (*coredata.CompliancePortalCommitment, error) {
|
||||
commitment := &coredata.CompliancePortalCommitment{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := commitment.LoadByID(ctx, conn, scope, commitmentID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance portal commitment: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return commitment, nil
|
||||
}
|
||||
@@ -45,26 +45,30 @@ const NDAConsentText = "By clicking \"Review and sign\", I consent to sign this
|
||||
|
||||
type (
|
||||
Service struct {
|
||||
pg *pg.Client
|
||||
s3 *s3.Client
|
||||
bucket string
|
||||
proboSvc *probo.Service
|
||||
slackSigningSecret string
|
||||
baseURL string
|
||||
iam *iam.Service
|
||||
esign *esign.Service
|
||||
html2pdfConverter *html2pdf.Converter
|
||||
fileManager *filemanager.Service
|
||||
logger *log.Logger
|
||||
slack *slack.Service
|
||||
TrustCenters *TrustCenterService
|
||||
Documents *DocumentService
|
||||
Audits *AuditService
|
||||
ThirdParties *ThirdPartyService
|
||||
Frameworks *FrameworkService
|
||||
ComplianceFrameworks *ComplianceFrameworkService
|
||||
TrustCenterAccesses *TrustCenterAccessService
|
||||
TrustCenterReferences *TrustCenterReferenceService
|
||||
pg *pg.Client
|
||||
s3 *s3.Client
|
||||
bucket string
|
||||
proboSvc *probo.Service
|
||||
slackSigningSecret string
|
||||
baseURL string
|
||||
iam *iam.Service
|
||||
esign *esign.Service
|
||||
html2pdfConverter *html2pdf.Converter
|
||||
fileManager *filemanager.Service
|
||||
logger *log.Logger
|
||||
slack *slack.Service
|
||||
TrustCenters *TrustCenterService
|
||||
Documents *DocumentService
|
||||
Audits *AuditService
|
||||
ThirdParties *ThirdPartyService
|
||||
Frameworks *FrameworkService
|
||||
ComplianceFrameworks *ComplianceFrameworkService
|
||||
TrustCenterAccesses *TrustCenterAccessService
|
||||
TrustCenterReferences *TrustCenterReferenceService
|
||||
|
||||
CompliancePortalCommitmentGroups *CompliancePortalCommitmentGroupService
|
||||
CompliancePortalCommitments *CompliancePortalCommitmentService
|
||||
|
||||
TrustCenterFiles *TrustCenterFileService
|
||||
Reports *ReportService
|
||||
Organizations *OrganizationService
|
||||
@@ -109,6 +113,8 @@ func NewService(
|
||||
svc.ComplianceFrameworks = &ComplianceFrameworkService{svc: svc}
|
||||
svc.TrustCenterAccesses = &TrustCenterAccessService{svc: svc, iamSvc: iam, logger: logger}
|
||||
svc.TrustCenterReferences = &TrustCenterReferenceService{svc: svc}
|
||||
svc.CompliancePortalCommitmentGroups = &CompliancePortalCommitmentGroupService{svc: svc}
|
||||
svc.CompliancePortalCommitments = &CompliancePortalCommitmentService{svc: svc}
|
||||
svc.TrustCenterFiles = &TrustCenterFileService{svc: svc}
|
||||
svc.Reports = &ReportService{svc: svc}
|
||||
svc.Organizations = &OrganizationService{svc: svc}
|
||||
|
||||
Reference in New Issue
Block a user