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 NULL–LINE OA channel that owns the dataset
nameTEXTNOT NULL–User-supplied dataset name
descriptionTEXTNULL–Additional description of the dataset
columnsJSONBNOT NULL–Column 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_byINTEGERNULL–User id of the last editor
updated_atTIMESTAMPTZNULL–Last update timestamp

Table customer_database_row​

ColumnTypeNullableDefaultDescription
idINTEGERNOT NULLnextval (serial)Primary key of the row
database_idINTEGERNOT NULL–Dataset this row belongs to (FK to customer_database.id, ON DELETE CASCADE)
dataJSONBNOT NULL–The 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.