Return communication database rows from communication API

This is a pretty big refactor of how communication works to start moving
us in the direction we want to go long-term. This adds the new
communication row and migrates existing reports to add rows for
communication.

There's also a bunch of automatic fixes from the new linter. I should
have added them separately, but whatever.
This commit is contained in:
Eli Ribble 2026-05-01 20:49:37 +00:00
parent a6ce0b7e67
commit a82732a49c
No known key found for this signature in database
41 changed files with 365 additions and 220 deletions

View file

@ -149,10 +149,6 @@ func InitializeDatabase(ctx context.Context, uri string) error {
if err != nil {
return fmt.Errorf("Failed to get database current: %w", err)
}
err = prepareStatements(ctx)
if err != nil {
return fmt.Errorf("Failed to initialize prepared statements: %w", err)
}
return nil
}

View file

@ -15,6 +15,8 @@ import (
var schemas []string = []string{
"arcgis",
"public",
"publicreport",
"stadia",
}

View file

@ -8,6 +8,7 @@ CREATE TABLE communication (
invalidated_by INTEGER REFERENCES user_(id),
opened TIMESTAMP WITHOUT TIME ZONE,
opened_by INTEGER REFERENCES user_(id),
organization_id INTEGER NOT NULL REFERENCES organization(id),
response_email_log_id INTEGER REFERENCES comms.email_log(id),
response_text_log_id INTEGER REFERENCES comms.text_log(id),
set_pending TIMESTAMP WITHOUT TIME ZONE,

View file

@ -0,0 +1,37 @@
-- +goose Up
INSERT INTO communication (
closed,
closed_by,
created,
--id,
invalidated,
invalidated_by,
opened,
opened_by,
organization_id,
response_email_log_id,
response_text_log_id,
set_pending,
set_pending_by,
source_email_log_id,
source_report_id,
source_text_log_id
) SELECT
NULL,
NULL,
created,
NULL,
NULL,
NULL,
NULL,
organization_id,
NULL,
NULL,
NULL,
NULL,
NULL,
id,
NULL
FROM publicreport.report;
-- +goose Down
DELETE FROM communication;

View file

@ -0,0 +1,22 @@
-- +goose Up
CREATE TYPE publicreport.PermissionAccessType AS ENUM (
'denied',
'granted',
'unselected',
'with-owner'
);
ALTER TABLE publicreport.compliance
ALTER COLUMN permission_type
TYPE publicreport.PermissionAccessType USING permission_type::text::publicreport.PermissionAccessType;
DROP TYPE PermissionAccessType;
-- +goose Down
CREATE TYPE PermissionAccessType AS ENUM (
'denied',
'granted',
'unselected',
'with-owner'
);
ALTER TABLE publicreport.compliance
ALTER COLUMN permission_type
TYPE PermissionAccessType;
DROP TYPE publicreport.PermissionAccessType;

View file

@ -5,7 +5,6 @@ import (
"embed"
"encoding/json"
"fmt"
"path/filepath"
"strings"
"time"
@ -21,52 +20,6 @@ import (
//go:embed prepared_functions/*.sql
var sqlFiles embed.FS
// PrepareStatements reads all embedded SQL files and executes them
// against the provided database connection. This is intended for
// preparing statements that will be used later.
func prepareStatements(ctx context.Context) error {
return nil
// Get a list of all embedded SQL files
entries, err := sqlFiles.ReadDir("prepared_functions")
if err != nil {
return fmt.Errorf("failed to read SQL directory: %w", err)
}
log.Info().Int("len", len(entries)).Msg("Reading prepared functions")
// Process each SQL file
for _, entry := range entries {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".sql") {
log.Info().Str("name", entry.Name()).Msg("Skipping")
continue
}
// Read the SQL file content
content, err := sqlFiles.ReadFile(filepath.Join("prepared_functions", entry.Name()))
if err != nil {
return fmt.Errorf("failed to read SQL file %s: %w", entry.Name(), err)
}
// Get the statement name from the filename (without extension)
statementName := strings.TrimSuffix(filepath.Base(entry.Name()), ".sql")
// Execute the SQL to prepare the statement
_, err = PGInstance.BobDB.Exec(string(content))
if err != nil {
return fmt.Errorf("failed to prepare statement %s: %w", statementName, err)
}
/*
query := psql.RawQuery(string(content))
stmt, err := bob.Prepare(ctx, PGInstance.BobDB, query)
if err != nil {
return fmt.Errorf("failed to prepare statement %s: %w", statementName, err)
}
*/
log.Info().Str("statement", statementName).Msg("Prepared statement")
}
return nil
}
func TestPreparedQueryOld(ctx context.Context) error {
type Skn struct {
Result int

View file

@ -0,0 +1,26 @@
package public
import (
"context"
"time"
"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/model"
"github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/public/table"
"github.com/go-jet/jet/v2/postgres"
)
func CommunicationInsert(ctx context.Context, txn bob.Tx, m *model.Communication) (*model.Communication, error) {
m.Created = time.Now()
statement := table.Communication.INSERT(table.Communication.MutableColumns).
MODEL(m)
return db.ExecuteOne[model.Communication](ctx, statement)
}
func CommunicationsFromOrganization(ctx context.Context, org_id int64) ([]*model.Communication, error) {
statement := table.Communication.SELECT(
table.Communication.AllColumns,
).FROM(table.Communication).
WHERE(table.Communication.OrganizationID.EQ(postgres.Int(org_id)))
return db.ExecuteMany[model.Communication](ctx, statement)
}

View file

@ -0,0 +1,32 @@
package public
import (
"context"
//"time"
//"github.com/Gleipnir-Technology/bob"
"github.com/Gleipnir-Technology/nidus-sync/db"
"github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/publicreport/model"
"github.com/Gleipnir-Technology/nidus-sync/db/gen/nidus-sync/publicreport/table"
"github.com/go-jet/jet/v2/postgres"
)
/*
func CommunicationInsert(ctx context.Context, txn bob.Tx, m *model.Communication) (*model.Communication, error) {
m.Created = time.Now()
statement := table.Communication.INSERT(table.Communication.MutableColumns).
MODEL(m)
return db.ExecuteOne[model.Communication](ctx, statement)
}
*/
func PublicReportsFromIDs(ctx context.Context, report_ids []int64) ([]*model.Report, error) {
sql_ids := make([]postgres.Expression, len(report_ids))
for i, report_id := range report_ids {
sql_ids[i] = postgres.Int(report_id)
}
statement := table.Report.SELECT(
table.Report.AllColumns,
).FROM(table.Report).
WHERE(table.Report.ID.IN(sql_ids...))
return db.ExecuteMany[model.Report](ctx, statement)
}