Add vendor snapshots
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -135,42 +135,3 @@ VALUES (
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (f File) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
DELETE FROM files WHERE %s AND id = @file_id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"file_id": f.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (f File) SoftDelete(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
UPDATE files SET deleted_at = @deleted_at, updated_at = @updated_at WHERE %s AND id = @file_id
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"file_id": f.ID,
|
||||
"updated_at": time.Now(),
|
||||
"deleted_at": time.Now(),
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
84
pkg/coredata/migrations/20250829T165122Z.sql
Normal file
84
pkg/coredata/migrations/20250829T165122Z.sql
Normal file
@@ -0,0 +1,84 @@
|
||||
ALTER TABLE vendor_business_associate_agreements ADD COLUMN snapshot_id TEXT;
|
||||
ALTER TABLE vendor_business_associate_agreements ADD COLUMN source_id TEXT;
|
||||
|
||||
ALTER TABLE vendor_business_associate_agreements DROP CONSTRAINT vendor_business_associate_agreements_file_id_unique;
|
||||
ALTER TABLE vendor_business_associate_agreements DROP CONSTRAINT vendor_business_associate_agreements_file_id_fkey;
|
||||
ALTER TABLE vendor_business_associate_agreements ADD CONSTRAINT vendor_business_associate_agreements_file_id_fkey
|
||||
FOREIGN KEY (file_id)
|
||||
REFERENCES files(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT;
|
||||
|
||||
ALTER TABLE vendor_business_associate_agreements ADD CONSTRAINT vendor_business_associate_agreements_snapshot_id_fkey
|
||||
FOREIGN KEY (snapshot_id)
|
||||
REFERENCES snapshots(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE vendor_business_associate_agreements ADD CONSTRAINT vendor_business_associate_agreements_source_id_snapshot_id_key
|
||||
UNIQUE (source_id, snapshot_id);
|
||||
|
||||
ALTER TABLE vendor_contacts ADD COLUMN snapshot_id TEXT;
|
||||
ALTER TABLE vendor_contacts ADD COLUMN source_id TEXT;
|
||||
|
||||
ALTER TABLE vendor_contacts ADD CONSTRAINT vendor_contacts_snapshot_id_fkey
|
||||
FOREIGN KEY (snapshot_id)
|
||||
REFERENCES snapshots(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE vendor_contacts ADD CONSTRAINT vendor_contacts_source_id_snapshot_id_key
|
||||
UNIQUE (source_id, snapshot_id);
|
||||
|
||||
ALTER TABLE vendor_data_privacy_agreements ADD COLUMN snapshot_id TEXT;
|
||||
ALTER TABLE vendor_data_privacy_agreements ADD COLUMN source_id TEXT;
|
||||
|
||||
ALTER TABLE vendor_data_privacy_agreements DROP CONSTRAINT vendor_data_privacy_agreements_file_id_unique;
|
||||
ALTER TABLE vendor_data_privacy_agreements DROP CONSTRAINT vendor_data_privacy_agreements_file_id_fkey;
|
||||
ALTER TABLE vendor_data_privacy_agreements ADD CONSTRAINT vendor_data_privacy_agreements_file_id_fkey
|
||||
FOREIGN KEY (file_id)
|
||||
REFERENCES files(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT;
|
||||
|
||||
ALTER TABLE vendor_data_privacy_agreements ADD CONSTRAINT vendor_data_privacy_agreements_snapshot_id_fkey
|
||||
FOREIGN KEY (snapshot_id)
|
||||
REFERENCES snapshots(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE vendor_data_privacy_agreements ADD CONSTRAINT vendor_data_privacy_agreements_source_id_snapshot_id_key
|
||||
UNIQUE (source_id, snapshot_id);
|
||||
|
||||
ALTER TABLE vendor_risk_assessments ADD COLUMN snapshot_id TEXT;
|
||||
ALTER TABLE vendor_risk_assessments ADD COLUMN source_id TEXT;
|
||||
|
||||
ALTER TABLE vendor_risk_assessments ADD CONSTRAINT vendor_risk_assessments_snapshot_id_fkey
|
||||
FOREIGN KEY (snapshot_id)
|
||||
REFERENCES snapshots(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE vendor_risk_assessments ADD CONSTRAINT vendor_risk_assessments_source_id_snapshot_id_key
|
||||
UNIQUE (source_id, snapshot_id);
|
||||
|
||||
ALTER TABLE vendor_services ADD COLUMN snapshot_id TEXT;
|
||||
ALTER TABLE vendor_services ADD COLUMN source_id TEXT;
|
||||
|
||||
ALTER TABLE vendor_services ADD CONSTRAINT vendor_services_snapshot_id_fkey
|
||||
FOREIGN KEY (snapshot_id)
|
||||
REFERENCES snapshots(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE vendor_services ADD CONSTRAINT vendor_services_source_id_snapshot_id_key
|
||||
UNIQUE (source_id, snapshot_id);
|
||||
|
||||
ALTER TABLE vendor_compliance_reports ADD COLUMN snapshot_id TEXT;
|
||||
ALTER TABLE vendor_compliance_reports ADD COLUMN source_id TEXT;
|
||||
|
||||
ALTER TABLE vendor_compliance_reports ADD CONSTRAINT vendor_compliance_reports_snapshot_id_fkey
|
||||
FOREIGN KEY (snapshot_id)
|
||||
REFERENCES snapshots(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
@@ -40,6 +40,8 @@ func GetSnapshottable(snapshotType SnapshotsType) (Snapshottable, error) {
|
||||
return ContinualImprovementRegistries{}, nil
|
||||
case SnapshotsTypeProcessingActivityRegistries:
|
||||
return ProcessingActivityRegistries{}, nil
|
||||
case SnapshotsTypeVendors:
|
||||
return Vendors{}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported snapshot type: %s", snapshotType)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,10 @@ type (
|
||||
}
|
||||
|
||||
Vendors []*Vendor
|
||||
|
||||
VendorSnapshotter interface {
|
||||
InsertVendorSnapshots(ctx context.Context, conn pg.Conn, scope Scoper, organizationID, snapshotID gid.GID) error
|
||||
}
|
||||
)
|
||||
|
||||
func (v Vendor) CursorKey(orderBy VendorOrderField) page.CursorKey {
|
||||
@@ -914,3 +918,106 @@ FROM source_vendors v
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v Vendors) Snapshot(ctx context.Context, conn pg.Conn, scope Scoper, organizationID, snapshotID gid.GID) error {
|
||||
for _, snapshotter := range []VendorSnapshotter{
|
||||
Vendors{},
|
||||
VendorServices{},
|
||||
VendorContacts{},
|
||||
VendorRiskAssessments{},
|
||||
VendorComplianceReports{},
|
||||
VendorBusinessAssociateAgreements{},
|
||||
VendorDataPrivacyAgreements{},
|
||||
} {
|
||||
if err := snapshotter.InsertVendorSnapshots(ctx, conn, scope, organizationID, snapshotID); err != nil {
|
||||
return fmt.Errorf("cannot create vendor snapshots: (%T) %w", snapshotter, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v Vendors) InsertVendorSnapshots(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
snapshotID gid.GID,
|
||||
) error {
|
||||
query := `
|
||||
INSERT INTO vendors (
|
||||
tenant_id,
|
||||
id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
organization_id,
|
||||
name,
|
||||
description,
|
||||
category,
|
||||
headquarter_address,
|
||||
legal_name,
|
||||
website_url,
|
||||
privacy_policy_url,
|
||||
service_level_agreement_url,
|
||||
data_processing_agreement_url,
|
||||
business_associate_agreement_url,
|
||||
subprocessors_list_url,
|
||||
certifications,
|
||||
business_owner_id,
|
||||
security_owner_id,
|
||||
status_page_url,
|
||||
terms_of_service_url,
|
||||
security_page_url,
|
||||
trust_page_url,
|
||||
show_on_trust_center,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
@tenant_id,
|
||||
generate_gid(decode_base64_unpadded(@tenant_id), @vendor_entity_type),
|
||||
@snapshot_id,
|
||||
v.id,
|
||||
v.organization_id,
|
||||
v.name,
|
||||
v.description,
|
||||
v.category,
|
||||
v.headquarter_address,
|
||||
v.legal_name,
|
||||
v.website_url,
|
||||
v.privacy_policy_url,
|
||||
v.service_level_agreement_url,
|
||||
v.data_processing_agreement_url,
|
||||
v.business_associate_agreement_url,
|
||||
v.subprocessors_list_url,
|
||||
v.certifications,
|
||||
v.business_owner_id,
|
||||
v.security_owner_id,
|
||||
v.status_page_url,
|
||||
v.terms_of_service_url,
|
||||
v.security_page_url,
|
||||
v.trust_page_url,
|
||||
v.show_on_trust_center,
|
||||
v.created_at,
|
||||
v.updated_at
|
||||
FROM vendors v
|
||||
WHERE %s AND organization_id = @organization_id AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"snapshot_id": snapshotID,
|
||||
"organization_id": organizationID,
|
||||
"vendor_entity_type": VendorEntityType,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert vendor snapshots: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ type (
|
||||
ValidFrom *time.Time `db:"valid_from"`
|
||||
ValidUntil *time.Time `db:"valid_until"`
|
||||
FileID gid.GID `db:"file_id"`
|
||||
SnapshotID *gid.GID `db:"snapshot_id"`
|
||||
SourceID *gid.GID `db:"source_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
@@ -66,6 +68,8 @@ SELECT
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -110,6 +114,8 @@ SELECT
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -156,6 +162,7 @@ SET
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -192,6 +199,8 @@ INSERT INTO
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
@@ -203,6 +212,8 @@ VALUES (
|
||||
@valid_from,
|
||||
@valid_until,
|
||||
@file_id,
|
||||
@snapshot_id,
|
||||
@source_id,
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
@@ -211,6 +222,8 @@ ON CONFLICT (organization_id, vendor_id) DO UPDATE SET
|
||||
valid_from = EXCLUDED.valid_from,
|
||||
valid_until = EXCLUDED.valid_until,
|
||||
file_id = EXCLUDED.file_id,
|
||||
snapshot_id = EXCLUDED.snapshot_id,
|
||||
source_id = EXCLUDED.source_id,
|
||||
updated_at = EXCLUDED.updated_at
|
||||
`
|
||||
args := pgx.StrictNamedArgs{
|
||||
@@ -221,6 +234,8 @@ ON CONFLICT (organization_id, vendor_id) DO UPDATE SET
|
||||
"valid_from": vbaa.ValidFrom,
|
||||
"valid_until": vbaa.ValidUntil,
|
||||
"file_id": vbaa.FileID,
|
||||
"snapshot_id": vbaa.SnapshotID,
|
||||
"source_id": vbaa.SourceID,
|
||||
"created_at": vbaa.CreatedAt,
|
||||
"updated_at": vbaa.UpdatedAt,
|
||||
}
|
||||
@@ -241,6 +256,7 @@ FROM
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -265,6 +281,7 @@ FROM
|
||||
WHERE
|
||||
%s
|
||||
AND vendor_id = @vendor_id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -275,3 +292,65 @@ WHERE
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (v VendorBusinessAssociateAgreements) InsertVendorSnapshots(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
snapshotID gid.GID,
|
||||
) error {
|
||||
query := `
|
||||
WITH
|
||||
snapshot_vendors AS (
|
||||
SELECT id, source_id
|
||||
FROM vendors
|
||||
WHERE organization_id = @organization_id AND snapshot_id = @snapshot_id
|
||||
)
|
||||
INSERT INTO vendor_business_associate_agreements (
|
||||
tenant_id,
|
||||
id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
organization_id,
|
||||
vendor_id,
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
@tenant_id,
|
||||
generate_gid(decode_base64_unpadded(@tenant_id), @vendor_business_associate_agreement_entity_type),
|
||||
@snapshot_id,
|
||||
vbaa.id,
|
||||
vbaa.organization_id,
|
||||
sv.id,
|
||||
vbaa.valid_from,
|
||||
vbaa.valid_until,
|
||||
vbaa.file_id,
|
||||
vbaa.created_at,
|
||||
vbaa.updated_at
|
||||
FROM vendor_business_associate_agreements vbaa
|
||||
INNER JOIN snapshot_vendors sv ON sv.source_id = vbaa.vendor_id
|
||||
WHERE %s AND vbaa.snapshot_id IS NULL
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"snapshot_id": snapshotID,
|
||||
"organization_id": organizationID,
|
||||
"vendor_business_associate_agreement_entity_type": VendorBusinessAssociateAgreementEntityType,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert vendor business associate agreement snapshots: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ type (
|
||||
ReportName string
|
||||
FileKey string
|
||||
FileSize int
|
||||
SnapshotID *gid.GID
|
||||
SourceID *gid.GID
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
@@ -69,6 +71,8 @@ SELECT
|
||||
report_name,
|
||||
file_key,
|
||||
file_size,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -115,6 +119,8 @@ SELECT
|
||||
report_name,
|
||||
file_key,
|
||||
file_size,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -206,6 +212,7 @@ FROM
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -216,3 +223,67 @@ WHERE
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (vcrs VendorComplianceReports) InsertVendorSnapshots(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
snapshotID gid.GID,
|
||||
) error {
|
||||
query := `
|
||||
WITH
|
||||
snapshot_vendors AS (
|
||||
SELECT id, source_id
|
||||
FROM vendors
|
||||
WHERE organization_id = @organization_id AND snapshot_id = @snapshot_id
|
||||
)
|
||||
INSERT INTO vendor_compliance_reports (
|
||||
tenant_id,
|
||||
id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
vendor_id,
|
||||
report_date,
|
||||
valid_until,
|
||||
report_name,
|
||||
file_key,
|
||||
file_size,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
@tenant_id,
|
||||
generate_gid(decode_base64_unpadded(@tenant_id), @vendor_compliance_report_entity_type),
|
||||
@snapshot_id,
|
||||
vcr.id,
|
||||
sv.id,
|
||||
vcr.report_date,
|
||||
vcr.valid_until,
|
||||
vcr.report_name,
|
||||
vcr.file_key,
|
||||
vcr.file_size,
|
||||
vcr.created_at,
|
||||
vcr.updated_at
|
||||
FROM vendor_compliance_reports vcr
|
||||
INNER JOIN snapshot_vendors sv ON sv.source_id = vcr.vendor_id
|
||||
WHERE %s AND vcr.snapshot_id IS NULL
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"snapshot_id": snapshotID,
|
||||
"organization_id": organizationID,
|
||||
"vendor_compliance_report_entity_type": VendorComplianceReportEntityType,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert vendor compliance report snapshots: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -29,14 +29,16 @@ import (
|
||||
|
||||
type (
|
||||
VendorContact struct {
|
||||
ID gid.GID `db:"id"`
|
||||
VendorID gid.GID `db:"vendor_id"`
|
||||
FullName *string `db:"full_name"`
|
||||
Email *string `db:"email"`
|
||||
Phone *string `db:"phone"`
|
||||
Role *string `db:"role"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
ID gid.GID `db:"id"`
|
||||
VendorID gid.GID `db:"vendor_id"`
|
||||
FullName *string `db:"full_name"`
|
||||
Email *string `db:"email"`
|
||||
Phone *string `db:"phone"`
|
||||
Role *string `db:"role"`
|
||||
SnapshotID *gid.GID `db:"snapshot_id"`
|
||||
SourceID *gid.GID `db:"source_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
VendorContacts []*VendorContact
|
||||
@@ -77,6 +79,8 @@ SELECT
|
||||
email,
|
||||
phone,
|
||||
role,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -127,6 +131,8 @@ SELECT
|
||||
email,
|
||||
phone,
|
||||
role,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -228,6 +234,7 @@ SET
|
||||
WHERE
|
||||
%s
|
||||
AND id = @vendor_contact_id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -261,6 +268,7 @@ DELETE FROM
|
||||
WHERE
|
||||
%s
|
||||
AND id = @vendor_contact_id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -275,3 +283,65 @@ WHERE
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vc VendorContacts) InsertVendorSnapshots(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
snapshotID gid.GID,
|
||||
) error {
|
||||
query := `
|
||||
WITH
|
||||
snapshot_vendors AS (
|
||||
SELECT id, source_id
|
||||
FROM vendors
|
||||
WHERE organization_id = @organization_id AND snapshot_id = @snapshot_id
|
||||
)
|
||||
INSERT INTO vendor_contacts (
|
||||
tenant_id,
|
||||
id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
vendor_id,
|
||||
full_name,
|
||||
email,
|
||||
phone,
|
||||
role,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
@tenant_id,
|
||||
generate_gid(decode_base64_unpadded(@tenant_id), @vendor_contact_entity_type),
|
||||
@snapshot_id,
|
||||
vc.id,
|
||||
sv.id,
|
||||
vc.full_name,
|
||||
vc.email,
|
||||
vc.phone,
|
||||
vc.role,
|
||||
vc.created_at,
|
||||
vc.updated_at
|
||||
FROM vendor_contacts vc
|
||||
INNER JOIN snapshot_vendors sv ON sv.source_id = vc.vendor_id
|
||||
WHERE %s AND vc.snapshot_id IS NULL
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"snapshot_id": snapshotID,
|
||||
"organization_id": organizationID,
|
||||
"vendor_contact_entity_type": VendorContactEntityType,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert vendor contact snapshots: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -28,15 +28,16 @@ import (
|
||||
|
||||
type (
|
||||
VendorDataPrivacyAgreement struct {
|
||||
ID gid.GID `db:"id"`
|
||||
TenantID gid.TenantID `db:"tenant_id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
VendorID gid.GID `db:"vendor_id"`
|
||||
ValidFrom *time.Time `db:"valid_from"`
|
||||
ValidUntil *time.Time `db:"valid_until"`
|
||||
FileID gid.GID `db:"file_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
ID gid.GID `db:"id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
VendorID gid.GID `db:"vendor_id"`
|
||||
ValidFrom *time.Time `db:"valid_from"`
|
||||
ValidUntil *time.Time `db:"valid_until"`
|
||||
FileID gid.GID `db:"file_id"`
|
||||
SnapshotID *gid.GID `db:"snapshot_id"`
|
||||
SourceID *gid.GID `db:"source_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
VendorDataPrivacyAgreements []*VendorDataPrivacyAgreement
|
||||
@@ -62,12 +63,13 @@ func (vdpa *VendorDataPrivacyAgreement) LoadByVendorID(
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
tenant_id,
|
||||
organization_id,
|
||||
vendor_id,
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -107,12 +109,13 @@ func (vdpa *VendorDataPrivacyAgreement) LoadByID(
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
tenant_id,
|
||||
organization_id,
|
||||
vendor_id,
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -159,6 +162,7 @@ SET
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -195,6 +199,8 @@ INSERT INTO
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
@@ -206,6 +212,8 @@ VALUES (
|
||||
@valid_from,
|
||||
@valid_until,
|
||||
@file_id,
|
||||
@snapshot_id,
|
||||
@source_id,
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
@@ -214,6 +222,8 @@ ON CONFLICT (organization_id, vendor_id) DO UPDATE SET
|
||||
valid_from = EXCLUDED.valid_from,
|
||||
valid_until = EXCLUDED.valid_until,
|
||||
file_id = EXCLUDED.file_id,
|
||||
snapshot_id = EXCLUDED.snapshot_id,
|
||||
source_id = EXCLUDED.source_id,
|
||||
updated_at = EXCLUDED.updated_at
|
||||
`
|
||||
args := pgx.StrictNamedArgs{
|
||||
@@ -224,6 +234,8 @@ ON CONFLICT (organization_id, vendor_id) DO UPDATE SET
|
||||
"valid_from": vdpa.ValidFrom,
|
||||
"valid_until": vdpa.ValidUntil,
|
||||
"file_id": vdpa.FileID,
|
||||
"snapshot_id": vdpa.SnapshotID,
|
||||
"source_id": vdpa.SourceID,
|
||||
"created_at": vdpa.CreatedAt,
|
||||
"updated_at": vdpa.UpdatedAt,
|
||||
}
|
||||
@@ -244,6 +256,7 @@ FROM
|
||||
WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -278,3 +291,65 @@ WHERE
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
}
|
||||
|
||||
func (vdpa VendorDataPrivacyAgreements) InsertVendorSnapshots(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
snapshotID gid.GID,
|
||||
) error {
|
||||
query := `
|
||||
WITH
|
||||
snapshot_vendors AS (
|
||||
SELECT id, source_id
|
||||
FROM vendors
|
||||
WHERE organization_id = @organization_id AND snapshot_id = @snapshot_id
|
||||
)
|
||||
INSERT INTO vendor_data_privacy_agreements (
|
||||
tenant_id,
|
||||
id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
organization_id,
|
||||
vendor_id,
|
||||
valid_from,
|
||||
valid_until,
|
||||
file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
@tenant_id,
|
||||
generate_gid(decode_base64_unpadded(@tenant_id), @vendor_data_privacy_agreement_entity_type),
|
||||
@snapshot_id,
|
||||
vdpa.id,
|
||||
vdpa.organization_id,
|
||||
sv.id,
|
||||
vdpa.valid_from,
|
||||
vdpa.valid_until,
|
||||
vdpa.file_id,
|
||||
vdpa.created_at,
|
||||
vdpa.updated_at
|
||||
FROM vendor_data_privacy_agreements vdpa
|
||||
INNER JOIN snapshot_vendors sv ON sv.source_id = vdpa.vendor_id
|
||||
WHERE %s AND vdpa.snapshot_id IS NULL
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"snapshot_id": snapshotID,
|
||||
"organization_id": organizationID,
|
||||
"vendor_data_privacy_agreement_entity_type": VendorDataPrivacyAgreementEntityType,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert vendor data privacy agreement snapshots: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ type (
|
||||
DataSensitivity DataSensitivity `db:"data_sensitivity"`
|
||||
BusinessImpact BusinessImpact `db:"business_impact"`
|
||||
Notes *string `db:"notes"`
|
||||
SnapshotID *gid.GID `db:"snapshot_id"`
|
||||
SourceID *gid.GID `db:"source_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
@@ -137,6 +139,8 @@ SELECT
|
||||
data_sensitivity,
|
||||
business_impact,
|
||||
notes,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -187,6 +191,8 @@ SELECT
|
||||
data_sensitivity,
|
||||
business_impact,
|
||||
notes,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -240,6 +246,8 @@ SELECT
|
||||
data_sensitivity,
|
||||
business_impact,
|
||||
notes,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -270,3 +278,73 @@ WHERE
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v VendorRiskAssessments) InsertVendorSnapshots(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
snapshotID gid.GID,
|
||||
) error {
|
||||
query := `
|
||||
WITH
|
||||
snapshot_vendors AS (
|
||||
SELECT id, source_id
|
||||
FROM vendors
|
||||
WHERE organization_id = @organization_id AND snapshot_id = @snapshot_id
|
||||
)
|
||||
INSERT INTO vendor_risk_assessments (
|
||||
tenant_id,
|
||||
id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
vendor_id,
|
||||
assessed_at,
|
||||
assessed_by,
|
||||
approved_by,
|
||||
approved_at,
|
||||
expires_at,
|
||||
data_sensitivity,
|
||||
business_impact,
|
||||
notes,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
@tenant_id,
|
||||
generate_gid(decode_base64_unpadded(@tenant_id), @vendor_risk_assessment_entity_type),
|
||||
@snapshot_id,
|
||||
vra.id,
|
||||
sv.id,
|
||||
vra.assessed_at,
|
||||
vra.assessed_by,
|
||||
vra.approved_by,
|
||||
vra.approved_at,
|
||||
vra.expires_at,
|
||||
vra.data_sensitivity,
|
||||
vra.business_impact,
|
||||
vra.notes,
|
||||
vra.created_at,
|
||||
vra.updated_at
|
||||
FROM vendor_risk_assessments vra
|
||||
INNER JOIN snapshot_vendors sv ON sv.source_id = vra.vendor_id
|
||||
WHERE %s AND vra.snapshot_id IS NULL
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"snapshot_id": snapshotID,
|
||||
"organization_id": organizationID,
|
||||
"vendor_risk_assessment_entity_type": VendorRiskAssessmentEntityType,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert vendor risk assessment snapshots: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ type (
|
||||
VendorID gid.GID `db:"vendor_id"`
|
||||
Name string `db:"name"`
|
||||
Description *string `db:"description"`
|
||||
SnapshotID *gid.GID `db:"snapshot_id"`
|
||||
SourceID *gid.GID `db:"source_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
@@ -71,6 +73,8 @@ SELECT
|
||||
vendor_id,
|
||||
name,
|
||||
description,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -119,6 +123,8 @@ SELECT
|
||||
vendor_id,
|
||||
name,
|
||||
description,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
@@ -212,6 +218,7 @@ SET
|
||||
WHERE
|
||||
%s
|
||||
AND id = @vendor_service_id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -243,6 +250,7 @@ DELETE FROM
|
||||
WHERE
|
||||
%s
|
||||
AND id = @vendor_service_id
|
||||
AND snapshot_id IS NULL
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -257,3 +265,61 @@ WHERE
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vs VendorServices) InsertVendorSnapshots(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
organizationID gid.GID,
|
||||
snapshotID gid.GID,
|
||||
) error {
|
||||
query := `
|
||||
WITH
|
||||
snapshot_vendors AS (
|
||||
SELECT id, source_id
|
||||
FROM vendors
|
||||
WHERE organization_id = @organization_id AND snapshot_id = @snapshot_id
|
||||
)
|
||||
INSERT INTO vendor_services (
|
||||
tenant_id,
|
||||
id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
vendor_id,
|
||||
name,
|
||||
description,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
@tenant_id,
|
||||
generate_gid(decode_base64_unpadded(@tenant_id), @vendor_service_entity_type),
|
||||
@snapshot_id,
|
||||
vs.id,
|
||||
sv.id,
|
||||
vs.name,
|
||||
vs.description,
|
||||
vs.created_at,
|
||||
vs.updated_at
|
||||
FROM vendor_services vs
|
||||
INNER JOIN snapshot_vendors sv ON sv.source_id = vs.vendor_id
|
||||
WHERE %s AND vs.snapshot_id IS NULL
|
||||
`
|
||||
|
||||
query = fmt.Sprintf(query, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"snapshot_id": snapshotID,
|
||||
"organization_id": organizationID,
|
||||
"vendor_service_entity_type": VendorServiceEntityType,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot insert vendor service snapshots: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -302,16 +302,10 @@ func (s VendorBusinessAssociateAgreementService) Delete(
|
||||
return fmt.Errorf("cannot load vendor business associate agreement: %w", err)
|
||||
}
|
||||
|
||||
file := &coredata.File{ID: vendorBusinessAssociateAgreement.FileID}
|
||||
|
||||
if err := vendorBusinessAssociateAgreement.Delete(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot delete vendor business associate agreement: %w", err)
|
||||
}
|
||||
|
||||
if err := file.SoftDelete(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot soft delete file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
@@ -329,16 +323,10 @@ func (s VendorBusinessAssociateAgreementService) DeleteByVendorID(
|
||||
return fmt.Errorf("cannot load vendor business associate agreement: %w", err)
|
||||
}
|
||||
|
||||
file := &coredata.File{ID: vendorBusinessAssociateAgreement.FileID}
|
||||
|
||||
if err := vendorBusinessAssociateAgreement.DeleteByVendorID(ctx, conn, s.svc.scope, vendorID); err != nil {
|
||||
return fmt.Errorf("cannot delete vendor business associate agreement: %w", err)
|
||||
}
|
||||
|
||||
if err := file.SoftDelete(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot soft delete file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
@@ -139,7 +139,6 @@ func (s VendorDataPrivacyAgreementService) Upload(
|
||||
|
||||
vendorDataPrivacyAgreement = &coredata.VendorDataPrivacyAgreement{
|
||||
ID: vendorDataPrivacyAgreementID,
|
||||
TenantID: s.svc.scope.GetTenantID(),
|
||||
OrganizationID: vendor.OrganizationID,
|
||||
VendorID: vendorID,
|
||||
ValidFrom: req.ValidFrom,
|
||||
@@ -303,16 +302,10 @@ func (s VendorDataPrivacyAgreementService) Delete(
|
||||
return fmt.Errorf("cannot load vendor data privacy agreement: %w", err)
|
||||
}
|
||||
|
||||
file := &coredata.File{ID: vendorDataPrivacyAgreement.FileID}
|
||||
|
||||
if err := vendorDataPrivacyAgreement.Delete(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot delete vendor data privacy agreement: %w", err)
|
||||
}
|
||||
|
||||
if err := file.SoftDelete(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot soft delete file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
@@ -330,16 +323,10 @@ func (s VendorDataPrivacyAgreementService) DeleteByVendorID(
|
||||
return fmt.Errorf("cannot load vendor data privacy agreement: %w", err)
|
||||
}
|
||||
|
||||
file := &coredata.File{ID: vendorDataPrivacyAgreement.FileID}
|
||||
|
||||
if err := vendorDataPrivacyAgreement.DeleteByVendorID(ctx, conn, s.svc.scope, vendorID); err != nil {
|
||||
return fmt.Errorf("cannot delete vendor data privacy agreement: %w", err)
|
||||
}
|
||||
|
||||
if err := file.SoftDelete(ctx, conn, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot soft delete file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1134,6 +1134,10 @@ input AssetFilter {
|
||||
snapshotId: ID
|
||||
}
|
||||
|
||||
input VendorFilter {
|
||||
snapshotId: ID
|
||||
}
|
||||
|
||||
# Core Types
|
||||
type TrustCenter implements Node {
|
||||
id: ID!
|
||||
@@ -1196,6 +1200,7 @@ type Organization implements Node {
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: VendorOrder
|
||||
filter: VendorFilter = { snapshotId: null }
|
||||
): VendorConnection! @goField(forceResolver: true)
|
||||
|
||||
peoples(
|
||||
@@ -1351,6 +1356,7 @@ type People implements Node {
|
||||
|
||||
type Vendor implements Node {
|
||||
id: ID!
|
||||
snapshotId: ID
|
||||
name: String!
|
||||
category: VendorCategory!
|
||||
description: String
|
||||
|
||||
@@ -897,7 +897,7 @@ type ComplexityRoot struct {
|
||||
TrustCenter func(childComplexity int) int
|
||||
UpdatedAt func(childComplexity int) int
|
||||
Users func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.UserOrderBy) int
|
||||
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) int
|
||||
Vendors func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy, filter *types.VendorFilter) int
|
||||
}
|
||||
|
||||
OrganizationConnection struct {
|
||||
@@ -1300,6 +1300,7 @@ type ComplexityRoot struct {
|
||||
ServiceLevelAgreementURL func(childComplexity int) int
|
||||
Services func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorServiceOrderBy) int
|
||||
ShowOnTrustCenter func(childComplexity int) int
|
||||
SnapshotID func(childComplexity int) int
|
||||
StatusPageURL func(childComplexity int) int
|
||||
SubprocessorsListURL func(childComplexity int) int
|
||||
TermsOfServiceURL func(childComplexity int) int
|
||||
@@ -1666,7 +1667,7 @@ type OrganizationResolver interface {
|
||||
Connectors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ConnectorOrder) (*types.ConnectorConnection, error)
|
||||
Frameworks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.FrameworkOrderBy) (*types.FrameworkConnection, error)
|
||||
Controls(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) (*types.ControlConnection, error)
|
||||
Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error)
|
||||
Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy, filter *types.VendorFilter) (*types.VendorConnection, error)
|
||||
Peoples(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PeopleOrderBy, filter *types.PeopleFilter) (*types.PeopleConnection, error)
|
||||
Documents(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentOrderBy, filter *types.DocumentFilter) (*types.DocumentConnection, error)
|
||||
Measures(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MeasureOrderBy, filter *types.MeasureFilter) (*types.MeasureConnection, error)
|
||||
@@ -5634,7 +5635,7 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Organization.Vendors(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.VendorOrderBy)), true
|
||||
return e.complexity.Organization.Vendors(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.VendorOrderBy), args["filter"].(*types.VendorFilter)), true
|
||||
|
||||
case "OrganizationConnection.edges":
|
||||
if e.complexity.OrganizationConnection.Edges == nil {
|
||||
@@ -7124,6 +7125,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
|
||||
return e.complexity.Vendor.ShowOnTrustCenter(childComplexity), true
|
||||
|
||||
case "Vendor.snapshotId":
|
||||
if e.complexity.Vendor.SnapshotID == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.Vendor.SnapshotID(childComplexity), true
|
||||
|
||||
case "Vendor.statusPageUrl":
|
||||
if e.complexity.Vendor.StatusPageURL == nil {
|
||||
break
|
||||
@@ -7850,6 +7858,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||
ec.unmarshalInputUserOrder,
|
||||
ec.unmarshalInputVendorComplianceReportOrder,
|
||||
ec.unmarshalInputVendorContactOrder,
|
||||
ec.unmarshalInputVendorFilter,
|
||||
ec.unmarshalInputVendorOrder,
|
||||
ec.unmarshalInputVendorRiskAssessmentOrder,
|
||||
ec.unmarshalInputVendorServiceOrder,
|
||||
@@ -9086,6 +9095,10 @@ input AssetFilter {
|
||||
snapshotId: ID
|
||||
}
|
||||
|
||||
input VendorFilter {
|
||||
snapshotId: ID
|
||||
}
|
||||
|
||||
# Core Types
|
||||
type TrustCenter implements Node {
|
||||
id: ID!
|
||||
@@ -9148,6 +9161,7 @@ type Organization implements Node {
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: VendorOrder
|
||||
filter: VendorFilter = { snapshotId: null }
|
||||
): VendorConnection! @goField(forceResolver: true)
|
||||
|
||||
peoples(
|
||||
@@ -9303,6 +9317,7 @@ type People implements Node {
|
||||
|
||||
type Vendor implements Node {
|
||||
id: ID!
|
||||
snapshotId: ID
|
||||
name: String!
|
||||
category: VendorCategory!
|
||||
description: String
|
||||
@@ -17711,6 +17726,11 @@ func (ec *executionContext) field_Organization_vendors_args(ctx context.Context,
|
||||
return nil, err
|
||||
}
|
||||
args["orderBy"] = arg4
|
||||
arg5, err := ec.field_Organization_vendors_argsFilter(ctx, rawArgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args["filter"] = arg5
|
||||
return args, nil
|
||||
}
|
||||
func (ec *executionContext) field_Organization_vendors_argsFirst(
|
||||
@@ -17778,6 +17798,19 @@ func (ec *executionContext) field_Organization_vendors_argsOrderBy(
|
||||
return zeroVal, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Organization_vendors_argsFilter(
|
||||
ctx context.Context,
|
||||
rawArgs map[string]any,
|
||||
) (*types.VendorFilter, error) {
|
||||
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("filter"))
|
||||
if tmp, ok := rawArgs["filter"]; ok {
|
||||
return ec.unmarshalOVendorFilter2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorFilter(ctx, tmp)
|
||||
}
|
||||
|
||||
var zeroVal *types.VendorFilter
|
||||
return zeroVal, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||
var err error
|
||||
args := map[string]any{}
|
||||
@@ -19123,6 +19156,8 @@ func (ec *executionContext) fieldContext_AssessVendorPayload_vendor(_ context.Co
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -41697,7 +41732,7 @@ func (ec *executionContext) _Organization_vendors(ctx context.Context, field gra
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return ec.resolvers.Organization().Vendors(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.VendorOrderBy))
|
||||
return ec.resolvers.Organization().Vendors(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.VendorOrderBy), fc.Args["filter"].(*types.VendorFilter))
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
@@ -51442,6 +51477,8 @@ func (ec *executionContext) fieldContext_UpdateVendorPayload_vendor(_ context.Co
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -52457,6 +52494,47 @@ func (ec *executionContext) fieldContext_Vendor_id(_ context.Context, field grap
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Vendor_snapshotId(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
if err != nil {
|
||||
return graphql.Null
|
||||
}
|
||||
ctx = graphql.WithFieldContext(ctx, fc)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
|
||||
ctx = rctx // use context from middleware stack in children
|
||||
return obj.SnapshotID, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*gid.GID)
|
||||
fc.Result = res
|
||||
return ec.marshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_Vendor_snapshotId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "Vendor",
|
||||
Field: field,
|
||||
IsMethod: false,
|
||||
IsResolver: false,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
return nil, errors.New("field of type ID does not have child fields")
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Vendor_name(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
|
||||
fc, err := ec.fieldContext_Vendor_name(ctx, field)
|
||||
if err != nil {
|
||||
@@ -53925,6 +54003,8 @@ func (ec *executionContext) fieldContext_VendorBusinessAssociateAgreement_vendor
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -54375,6 +54455,8 @@ func (ec *executionContext) fieldContext_VendorComplianceReport_vendor(_ context
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -55188,6 +55270,8 @@ func (ec *executionContext) fieldContext_VendorContact_vendor(_ context.Context,
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -55798,6 +55882,8 @@ func (ec *executionContext) fieldContext_VendorDataPrivacyAgreement_vendor(_ con
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -56248,6 +56334,8 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -56396,6 +56484,8 @@ func (ec *executionContext) fieldContext_VendorRiskAssessment_vendor(_ context.C
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -57129,6 +57219,8 @@ func (ec *executionContext) fieldContext_VendorService_vendor(_ context.Context,
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Vendor_id(ctx, field)
|
||||
case "snapshotId":
|
||||
return ec.fieldContext_Vendor_snapshotId(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Vendor_name(ctx, field)
|
||||
case "category":
|
||||
@@ -66011,6 +66103,33 @@ func (ec *executionContext) unmarshalInputVendorContactOrder(ctx context.Context
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputVendorFilter(ctx context.Context, obj any) (types.VendorFilter, error) {
|
||||
var it types.VendorFilter
|
||||
asMap := map[string]any{}
|
||||
for k, v := range obj.(map[string]any) {
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
fieldsInOrder := [...]string{"snapshotId"}
|
||||
for _, k := range fieldsInOrder {
|
||||
v, ok := asMap[k]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
switch k {
|
||||
case "snapshotId":
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("snapshotId"))
|
||||
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
it.SnapshotID = data
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputVendorOrder(ctx context.Context, obj any) (types.VendorOrderBy, error) {
|
||||
var it types.VendorOrderBy
|
||||
asMap := map[string]any{}
|
||||
@@ -78797,6 +78916,8 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "snapshotId":
|
||||
out.Values[i] = ec._Vendor_snapshotId(ctx, field, obj)
|
||||
case "name":
|
||||
out.Values[i] = ec._Vendor_name(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
@@ -88481,6 +88602,14 @@ func (ec *executionContext) marshalOVendorDataPrivacyAgreement2ᚖgithubᚗcom
|
||||
return ec._VendorDataPrivacyAgreement(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalOVendorFilter2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorFilter(ctx context.Context, v any) (*types.VendorFilter, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
res, err := ec.unmarshalInputVendorFilter(ctx, v)
|
||||
return &res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalOVendorOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorOrderBy(ctx context.Context, v any) (*types.VendorOrderBy, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
|
||||
@@ -1881,6 +1881,7 @@ type UserEdge struct {
|
||||
|
||||
type Vendor struct {
|
||||
ID gid.GID `json:"id"`
|
||||
SnapshotID *gid.GID `json:"snapshotId,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Category coredata.VendorCategory `json:"category"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
@@ -1998,6 +1999,10 @@ type VendorEdge struct {
|
||||
Node *Vendor `json:"node"`
|
||||
}
|
||||
|
||||
type VendorFilter struct {
|
||||
SnapshotID *gid.GID `json:"snapshotId,omitempty"`
|
||||
}
|
||||
|
||||
type VendorRiskAssessment struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Vendor *Vendor `json:"vendor"`
|
||||
|
||||
@@ -80,6 +80,7 @@ func NewVendor(v *coredata.Vendor) *Vendor {
|
||||
WebsiteURL: v.WebsiteURL,
|
||||
Category: v.Category,
|
||||
ShowOnTrustCenter: v.ShowOnTrustCenter,
|
||||
SnapshotID: v.SnapshotID,
|
||||
UpdatedAt: v.UpdatedAt,
|
||||
CreatedAt: v.CreatedAt,
|
||||
}
|
||||
|
||||
@@ -3459,7 +3459,7 @@ func (r *organizationResolver) Controls(ctx context.Context, obj *types.Organiza
|
||||
}
|
||||
|
||||
// Vendors is the resolver for the vendors field.
|
||||
func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy) (*types.VendorConnection, error) {
|
||||
func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy, filter *types.VendorFilter) (*types.VendorConnection, error) {
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.VendorOrderField]{
|
||||
@@ -3474,8 +3474,11 @@ func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organizat
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
var nilSnapshotID *gid.GID = nil
|
||||
vendorFilter := coredata.NewVendorFilter(&nilSnapshotID, nil)
|
||||
|
||||
var vendorFilter = coredata.NewVendorFilter(nil, nil)
|
||||
if filter != nil {
|
||||
vendorFilter = coredata.NewVendorFilter(&filter.SnapshotID, nil)
|
||||
}
|
||||
|
||||
page, err := prb.Vendors.ListForOrganizationID(ctx, obj.ID, cursor, vendorFilter)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user