Skip to main content

Uploaded Customer Database

Overview

This domain has two tables. customer_database holds the metadata of an uploaded customer dataset (CSV) — its name, column definitions and row count — while customer_database_row stores the individual rows as JSONB. Together they back user profile mapping: matching what a user enters in a form against existing customer records.

Table customer_database

ColumnTypeNullableDefaultDescription
idINTEGERNOT NULLnextval (serial)Primary key of the dataset
line_oa_idINTEGERNOT NULLLINE OA channel that owns the dataset
nameTEXTNOT NULLUser-supplied dataset name
descriptionTEXTNULLAdditional description of the dataset
columnsJSONBNOT NULLColumn definitions of the dataset (derived from the CSV header row)
row_countINTEGERNOT NULL0Number of data rows in the dataset
statusVARCHAR(20)NOT NULL'active'Dataset status (defaults to active)
created_byINTEGERNOT NULL0User id who uploaded the dataset
created_atTIMESTAMPTZNOT NULLnow()Upload timestamp
updated_byINTEGERNULLUser id of the last editor
updated_atTIMESTAMPTZNULLLast update timestamp

Table customer_database_row

ColumnTypeNullableDefaultDescription
idINTEGERNOT NULLnextval (serial)Primary key of the row
database_idINTEGERNOT NULLDataset this row belongs to (FK to customer_database.id, ON DELETE CASCADE)
dataJSONBNOT NULLThe row payload, stored as key-value pairs matching customer_database.columns

Notes

  • Neither table exists in schema.prisma. They were created via manual SQL (manual-sql/6.customer_database.sql) and applied to preprod on 2 July 2026, which is why they use created_at/updated_at column names (rather than the created_date/updated_date convention of Prisma-managed tables) and plain TIMESTAMPTZ without a precision.
  • Foreign key: customer_database_row.database_id -> customer_database.id with ON DELETE CASCADE — deleting a dataset removes all of its rows.
  • Indexes: customer_database_row_db_idx (btree on database_id) and customer_database_row_data_gin (GIN on data using jsonb_path_ops). The latter makes searching inside each row's JSON fast when matching against user-entered values.
  • These tables work together with the profile_mapping (JSONB) column added to form_builder by the same script, which stores which form maps to which dataset and on which column.
  • customer_database is linked to a channel through line_oa_id directly; it has no organization_id column, so filtering by organization requires a join through line_oa.