Unify JSON output of calls endpoints for UI

This commit is contained in:
Daniel Ponte 2025-01-05 10:50:19 -05:00
parent 955cced4df
commit 064e8d8a97
6 changed files with 64 additions and 29 deletions

View file

@ -32,7 +32,7 @@ func call(url string, call *calls.Call) error {
var buf bytes.Buffer var buf bytes.Buffer
body := multipart.NewWriter(&buf) body := multipart.NewWriter(&buf)
err := forms.Marshal(call, body, forms.WithTag("json")) err := forms.Marshal(call, body, forms.WithTag("relayOut"))
if err != nil { if err != nil {
return fmt.Errorf("relay form parse: %w", err) return fmt.Errorf("relay form parse: %w", err)
} }

View file

@ -46,24 +46,29 @@ type CallAudio struct {
AudioBlob []byte `json:"audioBlob"` AudioBlob []byte `json:"audioBlob"`
} }
// The tags here are snake_case for compatibility with sqlc generated
// struct tags in ListCallsPRow. This allows the heavier-weight calls
// queries/endpoints to render DB output directly to the wire without
// further transformation. relayOut exists for compatibility with http
// source CallUploadRequest as used in the relay sink.
type Call struct { type Call struct {
ID uuid.UUID `json:"id"` ID uuid.UUID `json:"id" relayOut:"id"`
Audio []byte `json:"audio,omitempty" filenameField:"AudioName"` Audio []byte `json:"audio,omitempty" relayOut:"audio,omitempty" filenameField:"AudioName"`
AudioName string `json:"audioName,omitempty"` AudioName string `json:"audioName,omitempty" relayOut:"audioName,omitempty"`
AudioType string `json:"audioType,omitempty"` AudioType string `json:"audioType,omitempty" relayOut:"audioType,omitempty"`
Duration CallDuration `json:"duration,omitempty"` Duration CallDuration `json:"duration,omitempty" relayOut:"duration,omitempty"`
DateTime time.Time `json:"dateTime,omitempty"` DateTime time.Time `json:"call_date,omitempty" relayOut:"dateTime,omitempty"`
Frequencies []int `json:"frequencies,omitempty"` Frequencies []int `json:"frequencies,omitempty" relayOut:"frequencies,omitempty"`
Frequency int `json:"frequency,omitempty"` Frequency int `json:"frequency,omitempty" relayOut:"frequency,omitempty"`
Patches []int `json:"patches,omitempty"` Patches []int `json:"patches,omitempty" relayOut:"patches,omitempty"`
Source int `json:"source,omitempty"` Source int `json:"source,omitempty" relayOut:"source,omitempty"`
System int `json:"system,omitempty"` System int `json:"system_id,omitempty" relayOut:"system,omitempty"`
Submitter *auth.UserID `json:"submitter,omitempty"` Submitter *auth.UserID `json:"submitter,omitempty" relayOut:"submitter,omitempty"`
SystemLabel string `json:"systemLabel,omitempty"` SystemLabel string `json:"system_name,omitempty" relayOut:"systemLabel,omitempty"`
Talkgroup int `json:"talkgroup,omitempty"` Talkgroup int `json:"tgid,omitempty" relayOut:"talkgroup,omitempty"`
TalkgroupGroup *string `json:"talkgroupGroup,omitempty"` TalkgroupGroup *string `json:"talkgroupGroup,omitempty" relayOut:"talkgroupGroup,omitempty"`
TalkgroupLabel *string `json:"talkgroupLabel,omitempty"` TalkgroupLabel *string `json:"talkgroupLabel,omitempty" relayOut:"talkgroupLabel,omitempty"`
TGAlphaTag *string `json:"talkgroupTag,omitempty"` TGAlphaTag *string `json:"tg_name,omitempty" relayOut:"talkgroupTag,omitempty"`
shouldStore bool `json:"-"` shouldStore bool `json:"-"`
} }

View file

@ -132,7 +132,22 @@ func (q *Queries) GetIncident(ctx context.Context, id uuid.UUID) (Incident, erro
} }
const getIncidentCalls = `-- name: GetIncidentCalls :many const getIncidentCalls = `-- name: GetIncidentCalls :many
SELECT ic.call_id, ic.call_date, ic.notes, c.submitter, c.system, c.talkgroup, c.audio_name, c.duration, c.audio_type, c.audio_url, c.frequency, c.frequencies, c.patches, c.source, c.transcript SELECT
ic.call_id,
ic.call_date,
c.duration,
c.system system_id,
c.talkgroup tgid,
ic.notes,
c.submitter,
c.audio_name,
c.audio_type,
c.audio_url,
c.frequency,
c.frequencies,
c.patches,
c.source,
c.transcript
FROM incidents_calls ic, LATERAL ( FROM incidents_calls ic, LATERAL (
SELECT SELECT
ca.submitter, ca.submitter,
@ -170,12 +185,12 @@ WHERE ic.incident_id = $1
type GetIncidentCallsRow struct { type GetIncidentCallsRow struct {
CallID uuid.UUID `json:"call_id"` CallID uuid.UUID `json:"call_id"`
CallDate pgtype.Timestamptz `json:"call_date"` CallDate pgtype.Timestamptz `json:"call_date"`
Duration *int32 `json:"duration"`
SystemID int `json:"system_id"`
TGID int `json:"tgid"`
Notes []byte `json:"notes"` Notes []byte `json:"notes"`
Submitter *int32 `json:"submitter"` Submitter *int32 `json:"submitter"`
System int `json:"system"`
Talkgroup int `json:"talkgroup"`
AudioName *string `json:"audio_name"` AudioName *string `json:"audio_name"`
Duration *int32 `json:"duration"`
AudioType *string `json:"audio_type"` AudioType *string `json:"audio_type"`
AudioUrl *string `json:"audio_url"` AudioUrl *string `json:"audio_url"`
Frequency int `json:"frequency"` Frequency int `json:"frequency"`
@ -197,12 +212,12 @@ func (q *Queries) GetIncidentCalls(ctx context.Context, id uuid.UUID) ([]GetInci
if err := rows.Scan( if err := rows.Scan(
&i.CallID, &i.CallID,
&i.CallDate, &i.CallDate,
&i.Duration,
&i.SystemID,
&i.TGID,
&i.Notes, &i.Notes,
&i.Submitter, &i.Submitter,
&i.System,
&i.Talkgroup,
&i.AudioName, &i.AudioName,
&i.Duration,
&i.AudioType, &i.AudioType,
&i.AudioUrl, &i.AudioUrl,
&i.Frequency, &i.Frequency,

View file

@ -240,9 +240,9 @@ func fromDBCalls(d []database.GetIncidentCallsRow) []incidents.IncidentCall {
Frequency: v.Frequency, Frequency: v.Frequency,
Patches: v.Patches, Patches: v.Patches,
Source: v.Source, Source: v.Source,
System: v.System, System: v.SystemID,
Submitter: sub, Submitter: sub,
Talkgroup: v.Talkgroup, Talkgroup: v.TGID,
}, },
Notes: v.Notes, Notes: v.Notes,
}) })

View file

@ -81,7 +81,7 @@ func (s *Relay) Call(ctx context.Context, call *calls.Call) error {
var buf bytes.Buffer var buf bytes.Buffer
body := multipart.NewWriter(&buf) body := multipart.NewWriter(&buf)
err := forms.Marshal(call, body, forms.WithTag("json")) err := forms.Marshal(call, body, forms.WithTag("relayOut"))
if err != nil { if err != nil {
return fmt.Errorf("relay form parse: %w", err) return fmt.Errorf("relay form parse: %w", err)
} }

View file

@ -94,7 +94,22 @@ CASE WHEN sqlc.narg('end')::TIMESTAMPTZ IS NOT NULL THEN
; ;
-- name: GetIncidentCalls :many -- name: GetIncidentCalls :many
SELECT ic.call_id, ic.call_date, ic.notes, c.* SELECT
ic.call_id,
ic.call_date,
c.duration,
c.system system_id,
c.talkgroup tgid,
ic.notes,
c.submitter,
c.audio_name,
c.audio_type,
c.audio_url,
c.frequency,
c.frequencies,
c.patches,
c.source,
c.transcript
FROM incidents_calls ic, LATERAL ( FROM incidents_calls ic, LATERAL (
SELECT SELECT
ca.submitter, ca.submitter,