Customer CMS user export¶
Purpose¶
customer-users:export creates a repeatable list of external BetterFleet CMS
users across APSE, Canada, EU, and US. It is an internal operator command for
bounded customer-list requests. It does not change product data or send the
result anywhere.
The export includes users who:
- have a
workspace_permissionsCMS membership; - belong to an active, non-protected workspace;
- are active; and
- are not BetterFleet system administrators.
Email addresses are normalised and deduplicated across regions. All associated regions and workspaces are retained in the final row. Roaming-only users are not included.
Prerequisites¶
uvand the PostgreSQLpsqlclient are installed.- Network access to each regional database is available.
- Each connection uses a database role limited to read-only access.
- The four connection URLs are supplied through runtime environment variables.
The command also sets the PostgreSQL session to read-only and applies a 30-second statement timeout. This is a second guard; it does not replace a read-only database role.
Connection configuration¶
Set these variables at runtime:
BF_CUSTOMER_USERS_APSE_DATABASE_URL
BF_CUSTOMER_USERS_CANADA_DATABASE_URL
BF_CUSTOMER_USERS_EU_DATABASE_URL
BF_CUSTOMER_USERS_US_DATABASE_URL
Use PostgreSQL URLs in this form:
Do not commit URLs or passwords. Prefer an ignored local environment file that
contains 1Password secret references, for example
env/customer-users-export.env:
BF_CUSTOMER_USERS_APSE_DATABASE_URL="op://Product Team/<read-only APSE item>/connection-string"
BF_CUSTOMER_USERS_CANADA_DATABASE_URL="op://Product Team/<read-only Canada item>/connection-string"
BF_CUSTOMER_USERS_EU_DATABASE_URL="op://Product Team/<read-only EU item>/connection-string"
BF_CUSTOMER_USERS_US_DATABASE_URL="op://Product Team/<read-only US item>/connection-string"
The repository ignores *.env files. Confirm that the referenced items use
read-only database accounts before running the export.
Run the export¶
Run with 1Password injection:
The direct wrapper is also available:
Choose another private output directory when required:
op run --env-file env/customer-users-export.env -- \
mise run customer-users:export -- \
--output-directory scratch/customer-users-export/cassie
Output and handling¶
The default output directory is:
Each run creates:
<timestamp>-cms-users.csv, containing the personal data; and<timestamp>-manifest.json, containing generation time, applied filters, per-region membership counts, and the final unique-email count.
The directory is owner-only and output files are written with mode 0600.
The command prints counts and paths, not names or email addresses. scratch/ is
gitignored, but operators must still treat the CSV as personal data: share it
only through an approved restricted location and delete local copies when they
are no longer needed.
The command validates all four connections before writing either output file. If a regional query fails, the export stops without producing a partial list.