Skip to Content
Living documentation — last reviewed 2026-05-28
FeaturesExports ImportsExports & Imports — Data Model

Exports & Imports — Data Model

export_jobs (libs/db/src/lib/schema/exports.ts)

ColumnTypeNotes
iduuid PKJob identity.
organization_iduuid FKScope.
typevarcharcsv_members today; expandable.
statusenumpending → in_progress → completed / failed.
configjsonbExportMembersDto.
started_byuuid FK → users.idRequester (for email + audit).
started_at, completed_at, updated_at, created_attimestampsLifecycle.
file_keyvarchar nullableR2 key on success (exports/<orgId>/<jobId>.csv).
resultsjsonb nullable{ rowCount, fileSize } on success.
error_messagetext nullablePopulated on failure.

import_jobs (libs/db/src/lib/schema/imports.ts)

ColumnTypeNotes
iduuid PKJob identity.
organization_iduuid FKScope.
sourceenumarbox or csv.
statusenumpending → in_progress → completed / failed / cancelled.
phasevarcharFree-form phase label (plans, members, enrichment, done).
configjsonbSource-specific. Arbox: ImportConfigDto. CSV: { parsedRows, headers, suggestedMapping, columnMapping?, entities?, memberFields?, planFields? }.
started_byuuid FKRequester.
started_at, completed_at, updated_at, created_attimestampsLifecycle.
resultsjsonbPer-entity { created, skipped, failed, errors[] }; Arbox jobs add enrichment counters and receipts: { imported, windows, failedWindows[] }.
error_messagetext nullableOrchestration-level failure.

import_provider_configs (libs/db/src/lib/schema/imports.ts)

ColumnTypeNotes
iduuid PKRow identity.
organization_iduuid FKScope.
providerenumarbox.
credentials_encryptedtextEncrypted JSON { apiKey, email?, password? }.
is_activebooleanOnly one active row per (org, provider).
created_at, updated_attimestampsAudit.

Encryption uses CredentialEncryptionService (shared with payment providers). FIT-120: rotating CREDENTIAL_ENCRYPTION_KEY makes old rows unreadable — re-enter credentials after rotation.

imported_receipts (libs/db/src/lib/schema/imports.ts)

Receipts a member received under the gym’s previous system. History only: never read by billing, refunds or revenue analytics.

ColumnTypeNotes
iduuid PKRow identity.
organization_iduuid FKScope.
membership_iduuid FK, cascadeThe member the receipt belongs to.
import_job_iduuid FK, set nullThe import that copied it.
sourceimport_sourcearbox.
external_idvarchar(64)Source transaction id. Unique with org + source: re-runs skip existing rows.
issued_attimestamptzSource’s box-local time converted with the org timezone.
descriptiontext nullableItem name on the document.
amount_in_cents, currencyinteger, varchar(3)Amount; currency is the org’s.
installmentsinteger nullableNumber of card payments.
card_last_fourvarchar(4) nullableOnly a real four-digit suffix is kept.
document_urltextBearer link to the provider’s PDF. Staff-only reads; deleted on member erasure.
created_attimestamptzCopy time.

Tables written by imports

TableWrite
usersINSERT (new emails) or UPDATE (existing emails — merge non-null source fields).
membershipsINSERT a member role row in active status (or per arboxStatus).
member_profilesINSERT/UPDATE — full profile mirror including arbox_user_id for back-reference. The collected national/personal ID is written encrypted into personal_id (AES-256-GCM via NationalIdEncryptionService; the column is text to fit ciphertext). Readers (member CSV export, invoice tax ID in PlansService) decrypt it, returning any non-decryptable legacy plaintext as-is. Use scripts/encrypt-personal-ids.ts to encrypt pre-existing plaintext rows in place.
plansINSERT new plans by name + price; updates existing on name collision.
leads (when entity targeted)INSERT lead rows from CSV.
imported_receipts (Arbox enrichment)INSERT … ON CONFLICT DO NOTHING per receipt of an imported member.

R2

  • exports/<orgId>/<jobId>.csv — UTF-8 with BOM.

Email

  • Sent from notifications/email.service.ts using the export-ready.ts template with a 1h presigned download URL.

Queues

QueueJob dataProducerConsumer
export{ jobId, orgId }ExportService.enqueueExportExportProcessor
import{ jobId, orgId }ImportService.{enqueueImport, confirmCsvImport}ImportProcessor
import-memberImportMemberJobDataImportService.fanOutMemberJobsImportMemberProcessor
import-enrichEnrichMemberJobDataImportService enrichment phaseImportEnrichProcessor
member-profiles-enrichment{ memberProfileId }ImportService (downstream)embeddings worker