From ff0deed5fb813121e5cfc4037548f72e5829ec59 Mon Sep 17 00:00:00 2001 From: Joel Brock Date: Fri, 5 Jun 2026 13:04:27 -0700 Subject: [PATCH] Staff report: add StaffReportPayload and supporting types --- types/form.ts | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/types/form.ts b/types/form.ts index b51d4db..7f8b4c1 100644 --- a/types/form.ts +++ b/types/form.ts @@ -273,6 +273,12 @@ export interface ActivitySummary { /** Stage value carried on this activity (non-empty → staff transition). */ stage?: string | null; subject?: string | null; + /** + * Display name of the source contact (form submitter). Only present on + * activities that have a source_contact_id; staff-created stage-change + * activities may not. The staff report shows this in its activity table. + */ + submittedBy?: string | null; } /** @@ -296,3 +302,94 @@ export interface ReportPayload { fieldHistory: Record; options?: Record; } + +/** + * Render kinds the staff report knows how to display. Built from CiviCRM + * field metadata at request time. `text` is the fallback for unknown + * data_type × html_type combinations. + */ +export type StaffRenderKind = + | "text" + | "number" + | "currency" + | "date" + | "datetime" + | "select" + | "multiselect" + | "file" + | "longtext" + | "boolean"; + +/** + * One field discovered via CustomField.get, normalised for the staff report. + */ +export interface StaffFieldDescriptor { + /** custom_group_id.name, e.g. "Stage_1" or "Food_Co_op_Organizing". */ + groupName: string; + /** custom_group_id.title (human label). */ + groupTitle: string; + /** Where the field lives: on the Activity or on the Organization Contact. */ + groupKind: "activity" | "org"; + /** APIv4 reference: ".". */ + civiField: string; + /** Just . */ + name: string; + /** Human label. */ + label: string; + /** How the UI should render this field's value. */ + render: StaffRenderKind; + /** For select/multiselect — which option group to resolve labels from. */ + optionGroupId?: number; +} + +/** + * One field + its history (per-activity values for activity fields; a + * single current value for org fields). + */ +export interface StaffReportField { + descriptor: StaffFieldDescriptor; + /** + * For activity fields: ordered history (latest first), one entry per + * activity that has a non-empty value. + * For org fields: at most one entry (the current value); activityId is + * set to 0 and date is the empty string since neither applies. + */ + history: FieldHistoryEntry[]; +} + +/** + * A section in the staff report — one per CiviCRM custom group. + */ +export interface StaffReportSection { + groupName: string; + groupTitle: string; + groupKind: "activity" | "org"; + fields: StaffReportField[]; +} + +/** + * The shape returned by /api/staff/report. + */ +export interface StaffReportPayload { + orgId: number; + orgName: string; + /** Current Framework Stage text value, or null if no stage on record. */ + currentStage: string | null; + /** Sections in render order: org section first, then activity groups. */ + sections: StaffReportSection[]; + /** Every Check-in (organizing) activity, ordered DESC by date. */ + activities: ActivitySummary[]; + /** Option-group labels for any select/multiselect/stage field referenced. */ + options: Record; +} + +/** + * Metadata returned by /api/staff/file?id=&key= when called with the JSON + * Accept header. Not currently used by the UI — the file proxy normally + * streams bytes — but documented here for future use. + */ +export interface StaffFileMeta { + id: number; + fileName: string | null; + mimeType: string | null; +}