Setup Database: linked_accounts Table
Creates the database table that tracks linked Merge accounts — one row per active integration per organization. All Merge Link API flows read and write this table.
Prerequisites
Tech stack and ORM identified (either from Step 1 of implementing-link, or by scanning the codebase now).
Before Proceeding
Step 1 — Confirm or gather required context:
Two pieces of information are needed before showing the schema:
- Organization/tenant table: The table or model in your app that represents a customer org or tenant (e.g.
organizations,companies,tenants). Needed to wire theorganization_idFK. - Linked Account strategy: Strategy 1 (1 Linked Account per category per org) or Strategy 2 (multiple per category)? Needed to annotate
end_user_origin_id.
If invoked from implementing-link, both were answered in Steps 1b and 1d — use that context. Otherwise, ask the user now:
- What is the table/model that represents a customer organization or tenant in your system? What is its primary key column?
- Do you want 1 Linked Account per category per org, or multiple Linked Accounts per category?
Step 2 — Show the schema and wait for confirmation:
Here is the
linked_accountstable I'll create:
Column Type Constraints Notes idinteger PRIMARY KEY, auto-increment organization_idinteger NOT NULL, FK → {org_table}.{pk}Ties to your org/tenant table end_user_origin_idvarchar(200) NOT NULL Stable per-org GUID (Strategy 1) or per-connection GUID (Strategy 2) categoryvarchar(50) NOT NULL e.g. hris,ats,crmintegration_slugvarchar(100) nullable Populated after token exchange account_tokenTEXT nullable Must be TEXT — tokens exceed 100 chars and a fixed VARCHAR truncates silently statusvarchar(20) NOT NULL, default 'pending'pending,active,error,disabledinitial_sync_completeboolean NOT NULL, default falsecreated_attimestamp NOT NULL, default now updated_attimestamp NOT NULL, default now, auto-update Unique constraint:
(organization_id, end_user_origin_id)FK for
organization_id: I'll reference{org_table}.{pk}. [If no org table was identified: I'll createorganization_idas a plain integer — you can add theREFERENCESconstraint manually.]Does this look right? Any columns to add, rename, or change before I generate the migration?
Wait for confirmation before continuing.
Implementation Prompt
Tell your coding agent:
Create a
linked_accountstable (or equivalent model for our ORM) with these exact fields:For
organization_id, emit a proper FK constraint referencing the org/tenant table identified in Step 1:organization_id INTEGER NOT NULL REFERENCES {org_table}({pk_col})If the org table was not identified in Step 1, emit
organization_id INTEGER NOT NULLand add a-- TODO: add REFERENCES constraintcomment. Do NOT invent a table name.
Field Type Notes idinteger, primary key auto-increment organization_idinteger, foreign key ties integration to your org/tenant table (see FK instruction above) end_user_origin_idvarchar(200), not null stable per-org GUID (Strategy 1) or per-connection GUID (Strategy 2) categorystring, at least 50 chars, not null Merge category: hris,ats,crm, etc.integration_slugstring, at least 100 chars, nullable e.g. gusto,workday— set after token exchangeaccount_tokenTEXT (or string with no fixed cap), nullable permanent Merge API token — null until exchange completes. Use TEXTrather than a fixedVARCHAR(64/128); account tokens can exceed 100 chars and a too-tight column truncates silently in some driversstatusstring, at least 20 chars, default pendingpending,active,error,disabledinitial_sync_completeboolean, default false flipped true after first full sync created_attimestamp default now updated_attimestamp default now, auto-update Add a unique constraint on
(organization_id, end_user_origin_id).Use the project's existing migration/ORM system (e.g. Alembic, Django migrations, ActiveRecord, Prisma). Generate the migration file and show it to the user for review before running it.
Critical Gotchas
end_user_origin_id MUST be written to the database BEFORE calling the Merge API.
The record is created during link token generation — not after. If the Merge API call fails mid-flow, the local record prevents duplicate incomplete accounts on retry.
account_token is nullable by design.
It does not exist until the public token exchange completes (Step 4). Any non-null constraint here will break the flow.
The unique constraint on (organization_id, end_user_origin_id) prevents duplicate integrations.
This is the deduplication guard. Without it, users can create multiple conflicting records for the same integration.
Testing Checklist
- Table created with all required columns
- Unique constraint on
(organization_id, end_user_origin_id)exists -
account_tokencolumn is nullable -
initial_sync_completedefaults to false - Migration runs cleanly with no errors (or equivalent ORM check)