File refs in one table
Added a file service Refactored evidence and vendor compliance associated services and resolvers Created SQL migration scripts Updated GraphQL schema accordingly and the UI components Removed unused methods and resolvers for evidence service Signed-off-by: Yannis Varni <yannis@edinomis.fr>
This commit is contained in:
committed by
Sacha Al Himdani
parent
3822b1916c
commit
ff7ba08fc1
@@ -28,20 +28,17 @@ import (
|
||||
|
||||
type (
|
||||
Evidence struct {
|
||||
ID gid.GID `db:"id"`
|
||||
MeasureID gid.GID `db:"measure_id"`
|
||||
TaskID *gid.GID `db:"task_id"`
|
||||
State EvidenceState `db:"state"`
|
||||
ReferenceID string `db:"reference_id"`
|
||||
Type EvidenceType `db:"type"`
|
||||
ObjectKey string `db:"object_key"`
|
||||
MimeType string `db:"mime_type"`
|
||||
Size uint64 `db:"size"`
|
||||
Filename string `db:"filename"`
|
||||
URL string `db:"url"`
|
||||
Description string `db:"description"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
ID gid.GID `db:"id"`
|
||||
MeasureID gid.GID `db:"measure_id"`
|
||||
TaskID *gid.GID `db:"task_id"`
|
||||
State EvidenceState `db:"state"`
|
||||
ReferenceID string `db:"reference_id"`
|
||||
Type EvidenceType `db:"type"`
|
||||
URL string `db:"url"`
|
||||
EvidenceFileId *gid.GID `db:"evidence_file_id"`
|
||||
Description string `db:"description"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
Evidences []*Evidence
|
||||
@@ -69,13 +66,10 @@ INSERT INTO
|
||||
measure_id,
|
||||
task_id,
|
||||
reference_id,
|
||||
object_key,
|
||||
mime_type,
|
||||
size,
|
||||
state,
|
||||
type,
|
||||
filename,
|
||||
url,
|
||||
evidence_file_id,
|
||||
description,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -86,13 +80,10 @@ VALUES (
|
||||
@measure_id,
|
||||
@task_id,
|
||||
@reference_id,
|
||||
@object_key,
|
||||
@mime_type,
|
||||
@size,
|
||||
@state,
|
||||
@type,
|
||||
@filename,
|
||||
@url,
|
||||
@evidence_file_id,
|
||||
@description,
|
||||
@created_at,
|
||||
@updated_at
|
||||
@@ -105,21 +96,18 @@ WHERE evidences.state = 'REQUESTED';
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"evidence_id": e.ID,
|
||||
"measure_id": e.MeasureID,
|
||||
"task_id": e.TaskID,
|
||||
"reference_id": e.ReferenceID,
|
||||
"object_key": e.ObjectKey,
|
||||
"mime_type": e.MimeType,
|
||||
"size": e.Size,
|
||||
"filename": e.Filename,
|
||||
"created_at": e.CreatedAt,
|
||||
"updated_at": e.UpdatedAt,
|
||||
"state": e.State,
|
||||
"type": e.Type,
|
||||
"url": e.URL,
|
||||
"description": e.Description,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"evidence_id": e.ID,
|
||||
"measure_id": e.MeasureID,
|
||||
"task_id": e.TaskID,
|
||||
"reference_id": e.ReferenceID,
|
||||
"evidence_file_id": e.EvidenceFileId,
|
||||
"created_at": e.CreatedAt,
|
||||
"updated_at": e.UpdatedAt,
|
||||
"state": e.State,
|
||||
"type": e.Type,
|
||||
"url": e.URL,
|
||||
"description": e.Description,
|
||||
}
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
@@ -138,13 +126,10 @@ INSERT INTO
|
||||
measure_id,
|
||||
task_id,
|
||||
reference_id,
|
||||
object_key,
|
||||
mime_type,
|
||||
size,
|
||||
state,
|
||||
type,
|
||||
filename,
|
||||
url,
|
||||
evidence_file_id,
|
||||
description,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -155,13 +140,10 @@ VALUES (
|
||||
@measure_id,
|
||||
@task_id,
|
||||
@reference_id,
|
||||
@object_key,
|
||||
@mime_type,
|
||||
@size,
|
||||
@state,
|
||||
@type,
|
||||
@filename,
|
||||
@url,
|
||||
@evidence_file_id,
|
||||
@description,
|
||||
@created_at,
|
||||
@updated_at
|
||||
@@ -169,21 +151,18 @@ VALUES (
|
||||
`
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"evidence_id": e.ID,
|
||||
"measure_id": e.MeasureID,
|
||||
"task_id": e.TaskID,
|
||||
"reference_id": e.ReferenceID,
|
||||
"object_key": e.ObjectKey,
|
||||
"mime_type": e.MimeType,
|
||||
"size": e.Size,
|
||||
"filename": e.Filename,
|
||||
"created_at": e.CreatedAt,
|
||||
"updated_at": e.UpdatedAt,
|
||||
"state": e.State,
|
||||
"type": e.Type,
|
||||
"url": e.URL,
|
||||
"description": e.Description,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"evidence_id": e.ID,
|
||||
"measure_id": e.MeasureID,
|
||||
"task_id": e.TaskID,
|
||||
"reference_id": e.ReferenceID,
|
||||
"evidence_file_id": e.EvidenceFileId,
|
||||
"created_at": e.CreatedAt,
|
||||
"updated_at": e.UpdatedAt,
|
||||
"state": e.State,
|
||||
"type": e.Type,
|
||||
"url": e.URL,
|
||||
"description": e.Description,
|
||||
}
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
@@ -203,11 +182,8 @@ SELECT
|
||||
reference_id,
|
||||
state,
|
||||
type,
|
||||
object_key,
|
||||
mime_type,
|
||||
size,
|
||||
filename,
|
||||
url,
|
||||
evidence_file_id,
|
||||
description,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -286,11 +262,8 @@ SELECT
|
||||
reference_id,
|
||||
state,
|
||||
type,
|
||||
object_key,
|
||||
mime_type,
|
||||
size,
|
||||
filename,
|
||||
url,
|
||||
evidence_file_id,
|
||||
description,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -370,11 +343,8 @@ SELECT
|
||||
reference_id,
|
||||
state,
|
||||
type,
|
||||
object_key,
|
||||
mime_type,
|
||||
size,
|
||||
filename,
|
||||
url,
|
||||
evidence_file_id,
|
||||
description,
|
||||
created_at,
|
||||
updated_at
|
||||
@@ -418,10 +388,7 @@ UPDATE
|
||||
SET
|
||||
type = @type,
|
||||
state = @state,
|
||||
object_key = @object_key,
|
||||
mime_type = @mime_type,
|
||||
size = @size,
|
||||
filename = @filename,
|
||||
evidence_file_id = @evidence_file_id,
|
||||
url = @url,
|
||||
description = @description,
|
||||
updated_at = @updated_at
|
||||
@@ -433,16 +400,13 @@ WHERE
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"evidence_id": e.ID,
|
||||
"type": e.Type,
|
||||
"state": e.State,
|
||||
"object_key": e.ObjectKey,
|
||||
"mime_type": e.MimeType,
|
||||
"size": e.Size,
|
||||
"filename": e.Filename,
|
||||
"url": e.URL,
|
||||
"description": e.Description,
|
||||
"updated_at": e.UpdatedAt,
|
||||
"evidence_id": e.ID,
|
||||
"type": e.Type,
|
||||
"state": e.State,
|
||||
"evidence_file_id": e.EvidenceFileId,
|
||||
"url": e.URL,
|
||||
"description": e.Description,
|
||||
"updated_at": e.UpdatedAt,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
@@ -454,13 +418,14 @@ func (e Evidence) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
) (*string, error) {
|
||||
q := `
|
||||
DELETE FROM
|
||||
evidences
|
||||
WHERE
|
||||
%s
|
||||
%s
|
||||
AND id = @evidence_id
|
||||
RETURNING evidence_file_id;
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -468,6 +433,23 @@ WHERE
|
||||
args := pgx.StrictNamedArgs{"evidence_id": e.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
var evidenceFileId *gid.GID
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&evidenceFileId)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to delete evidence: %w", err)
|
||||
}
|
||||
|
||||
if evidenceFileId != nil {
|
||||
var err error
|
||||
var fileKey *string
|
||||
file := &File{ID: *evidenceFileId}
|
||||
if fileKey, err = file.HardDelete(ctx, conn, scope); err != nil {
|
||||
return nil, fmt.Errorf("failed to hard delete evidence file: %w", err)
|
||||
}
|
||||
return fileKey, nil
|
||||
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -135,3 +135,39 @@ VALUES (
|
||||
_, 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 = NOW()
|
||||
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) HardDelete(ctx context.Context, conn pg.Conn, scope Scoper) (*string, error) {
|
||||
q := `
|
||||
DELETE FROM files
|
||||
WHERE %s
|
||||
AND id = @file_id
|
||||
RETURNING file_key
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
args := pgx.StrictNamedArgs{"file_id": f.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
var vcrFileKey *string
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&vcrFileKey)
|
||||
|
||||
return vcrFileKey, err
|
||||
}
|
||||
|
||||
41
pkg/coredata/migrations/20251003T132724Z.sql
Normal file
41
pkg/coredata/migrations/20251003T132724Z.sql
Normal file
@@ -0,0 +1,41 @@
|
||||
ALTER TABLE evidences
|
||||
ADD COLUMN evidence_file_id text;
|
||||
|
||||
/* 10 is for FileEntityType */
|
||||
WITH
|
||||
evidence_files AS (
|
||||
SELECT
|
||||
e.id as evidence_id,
|
||||
generate_gid(decode_base64_unpadded(e.tenant_id), 25) as file_id,
|
||||
e.tenant_id,
|
||||
'probod' as bucket_name,
|
||||
e.mime_type,
|
||||
e.filename,
|
||||
e.object_key,
|
||||
e.size,
|
||||
e.created_at,
|
||||
e.updated_at
|
||||
FROM evidences e
|
||||
),
|
||||
inserted_files AS (
|
||||
INSERT INTO files (id, tenant_id, bucket_name, mime_type, file_name, file_key, file_size, created_at, updated_at)
|
||||
SELECT file_id, tenant_id, bucket_name, mime_type, filename, object_key::uuid, size, created_at, updated_at
|
||||
FROM evidence_files
|
||||
RETURNING id, tenant_id
|
||||
)
|
||||
|
||||
SELECT ef.evidence_id, ef.file_id
|
||||
INTO TEMP TABLE file_evidence_mapping
|
||||
FROM evidence_files ef;
|
||||
|
||||
UPDATE evidences
|
||||
SET evidence_file_id = fm.file_id
|
||||
FROM file_evidence_mapping fm
|
||||
WHERE evidences.id = fm.evidence_id;
|
||||
|
||||
|
||||
ALTER TABLE evidences
|
||||
ALTER COLUMN filename DROP NOT NULL,
|
||||
ALTER COLUMN mime_type DROP NOT NULL,
|
||||
ALTER COLUMN size DROP NOT NULL,
|
||||
ALTER COLUMN oject_key DROP NOT NULL;
|
||||
41
pkg/coredata/migrations/20251003T151644Z.sql
Normal file
41
pkg/coredata/migrations/20251003T151644Z.sql
Normal file
@@ -0,0 +1,41 @@
|
||||
ALTER TABLE
|
||||
vendor_compliance_reports
|
||||
ADD COLUMN report_file_id text
|
||||
REFERENCES files(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT;
|
||||
|
||||
WITH
|
||||
/* 25 is for FileEntityType */
|
||||
vcr_files AS (
|
||||
SELECT
|
||||
vcr.id as report_id,
|
||||
generate_gid(decode_base64_unpadded(vcr.tenant_id), 25) as file_id,
|
||||
vcr.tenant_id,
|
||||
'probod' as bucket_name,
|
||||
'application/pdf' as mime_type,
|
||||
vcr.report_name,
|
||||
vcr.file_key,
|
||||
vcr.file_size,
|
||||
vcr.created_at,
|
||||
vcr.updated_at
|
||||
FROM vendor_compliance_reports vcr
|
||||
),
|
||||
inserted_files AS (
|
||||
INSERT INTO files (id, tenant_id, bucket_name, mime_type, file_name, file_key, file_size, created_at, updated_at)
|
||||
SELECT file_id, tenant_id, bucket_name, mime_type, report_name, file_key::uuid, file_size, created_at, updated_at
|
||||
FROM vcr_files
|
||||
RETURNING id, tenant_id
|
||||
)
|
||||
SELECT vf.report_id, vf.file_id
|
||||
INTO TEMP TABLE file_vcr_mapping
|
||||
FROM vcr_files vf;
|
||||
|
||||
UPDATE vendor_compliance_reports
|
||||
SET report_file_id = fv.file_id
|
||||
FROM file_vcr_mapping fv
|
||||
WHERE vendor_compliance_reports.id = fv.report_id;
|
||||
|
||||
ALTER TABLE vendor_compliance_reports
|
||||
ALTER COLUMN file_key DROP NOT NULL,
|
||||
ALTER COLUMN file_size DROP NOT NULL;
|
||||
7
pkg/coredata/migrations/20251006T133729Z.sql
Normal file
7
pkg/coredata/migrations/20251006T133729Z.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE
|
||||
evidences
|
||||
ADD CONSTRAINT fk_evidence_file
|
||||
FOREIGN KEY (evidence_file_id)
|
||||
REFERENCES files(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT;
|
||||
@@ -28,17 +28,16 @@ import (
|
||||
|
||||
type (
|
||||
VendorComplianceReport struct {
|
||||
ID gid.GID
|
||||
VendorID gid.GID
|
||||
ReportDate time.Time
|
||||
ValidUntil *time.Time
|
||||
ReportName string
|
||||
FileKey string
|
||||
FileSize int64
|
||||
SnapshotID *gid.GID
|
||||
SourceID *gid.GID
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
ID gid.GID
|
||||
VendorID gid.GID
|
||||
ReportDate time.Time
|
||||
ValidUntil *time.Time
|
||||
ReportName string
|
||||
ReportFileId *gid.GID
|
||||
SnapshotID *gid.GID
|
||||
SourceID *gid.GID
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
VendorComplianceReports []*VendorComplianceReport
|
||||
@@ -69,8 +68,7 @@ SELECT
|
||||
report_date,
|
||||
valid_until,
|
||||
report_name,
|
||||
file_key,
|
||||
file_size,
|
||||
report_file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
@@ -117,8 +115,7 @@ SELECT
|
||||
report_date,
|
||||
valid_until,
|
||||
report_name,
|
||||
file_key,
|
||||
file_size,
|
||||
report_file_id,
|
||||
snapshot_id,
|
||||
source_id,
|
||||
created_at,
|
||||
@@ -165,8 +162,7 @@ INSERT INTO
|
||||
report_date,
|
||||
valid_until,
|
||||
report_name,
|
||||
file_key,
|
||||
file_size,
|
||||
report_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
@@ -177,23 +173,21 @@ VALUES (
|
||||
@report_date,
|
||||
@valid_until,
|
||||
@report_name,
|
||||
@file_key,
|
||||
@file_size,
|
||||
@report_file_id,
|
||||
@created_at,
|
||||
@updated_at
|
||||
)
|
||||
`
|
||||
args := pgx.NamedArgs{
|
||||
"id": vcr.ID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"vendor_id": vcr.VendorID,
|
||||
"report_date": vcr.ReportDate,
|
||||
"valid_until": vcr.ValidUntil,
|
||||
"report_name": vcr.ReportName,
|
||||
"file_key": vcr.FileKey,
|
||||
"file_size": vcr.FileSize,
|
||||
"created_at": vcr.CreatedAt,
|
||||
"updated_at": vcr.UpdatedAt,
|
||||
"id": vcr.ID,
|
||||
"tenant_id": scope.GetTenantID(),
|
||||
"vendor_id": vcr.VendorID,
|
||||
"report_date": vcr.ReportDate,
|
||||
"valid_until": vcr.ValidUntil,
|
||||
"report_name": vcr.ReportName,
|
||||
"report_file_id": vcr.ReportFileId,
|
||||
"created_at": vcr.CreatedAt,
|
||||
"updated_at": vcr.UpdatedAt,
|
||||
}
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
@@ -213,6 +207,7 @@ WHERE
|
||||
%s
|
||||
AND id = @id
|
||||
AND snapshot_id IS NULL
|
||||
RETURNING report_file_id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
@@ -220,8 +215,20 @@ WHERE
|
||||
args := pgx.StrictNamedArgs{"id": vcr.ID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
_, err := conn.Exec(ctx, q, args)
|
||||
return err
|
||||
var vcrFileId *gid.GID
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&vcrFileId)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete vendor compliance report: %w", err)
|
||||
}
|
||||
|
||||
if vcrFileId != nil {
|
||||
file := &File{ID: *vcrFileId}
|
||||
if err = file.SoftDelete(ctx, conn, scope); err != nil {
|
||||
return fmt.Errorf("failed to soft delete vendor compliance file: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vcrs VendorComplianceReports) InsertVendorSnapshots(
|
||||
@@ -247,8 +254,7 @@ INSERT INTO vendor_compliance_reports (
|
||||
report_date,
|
||||
valid_until,
|
||||
report_name,
|
||||
file_key,
|
||||
file_size,
|
||||
report_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
@@ -261,8 +267,7 @@ SELECT
|
||||
vcr.report_date,
|
||||
vcr.valid_until,
|
||||
vcr.report_name,
|
||||
vcr.file_key,
|
||||
vcr.file_size,
|
||||
vcr.report_file_id,
|
||||
vcr.created_at,
|
||||
vcr.updated_at
|
||||
FROM vendor_compliance_reports vcr
|
||||
|
||||
Reference in New Issue
Block a user