Saltar al contenido principal

RPApos Gateway — Database Schema

PostgreSQL objects used by the RPApos gateway integration.

Document version: 1.0 · Last updated: 2026-05


Migrations

FilePurpose
packages/backend/database/src/migrations/2026-05-09t10-00-00-add-rpapos-integration.mjsCore tables + enum + product.is_raw_material
packages/backend/database/src/migrations/2026-05-10t11-00-00-add-rpapos-phase2-entities.mjsEnum extension: mesa, persona, precio, produccion_grupo
packages/backend/database/src/migrations/2026-05-17t10-00-00-rpapos-soap-token.mjsSOAP device token + SAT connection metadata on rpapos_connection
packages/backend/database/src/migrations/2026-05-17t12-00-00-rpapos-sat-credentials.mjsOptional sat_usuario / sat_password_encrypted
packages/backend/database/src/migrations/2026-05-18t14-00-00-rpapos-modifier-entities.mjsEnum extension: plu_option_group, plu_option_item, plu_option_group_assignment

Target FlowPOS tables for those enum values: product_modifier_group, product_modifier, product_modifier_group_assignment. See Menus & Modifier Groups — All related tables.

Apply locally:

pnpm run migration:local:push
pnpm run generate:types

Enum: rpapos_entity_type

Phase 1 + Phase 2 + modifier values (planner uses the catalog subset):

plu, plu_grupo, sku, sku_grupo, batch_maestro, proveedor, unidad_medida,
moneda, tipo_gestion, area, bodega, usuario, estacion_trabajo, dispositivo_io,
compra, traslado, conteo_fisico, merma, salida_sku, produccion,
mesa, persona, precio, produccion_grupo,
plu_option_group, plu_option_item, plu_option_group_assignment

TypeScript mirror: RpaposEntityType in packages/global/enums/rpapos.enums.ts.


Table: rpapos_connection

One row per business + subdomain pair.

ColumnTypeNotes
iduuid PK
business_iduuidMulti-tenant scope
subdomaintextUnique per business
usuariotextRPApos login user
password_encryptedtextCryptoService
api_key_encryptedtextOptional; default ''
timezonetextDefault America/Guatemala
currency_codetextDefault GTQ
statustextactive, disconnected, error
sync_interval_minutesintNullable; scheduled sync hook
tipo_gestion_mapjsonbRPA order type → FlowPOS order type
last_synced_attimestamptz
last_full_sync_attimestamptz
last_errortextSet on sync failure
sat_usuariotextOptional SAT login user (defaults to usuario when SAT password is set)
sat_password_encryptedtextOptional SAT password
soap_token_encryptedtextDevice token from Dispositivo_Registra_2 (pToken on db4 SOAP)
localizacion_idsmallintFrom SAT registration
conexion_dbintegerFrom SAT registration
conexion_mainframeintegerFrom SAT registration
estacion_trabajosmallintWorkstation id — required for Catalogo_4 / Producto_U_M
created_byuuid
created_at / updated_attimestamptz

Constraint: UNIQUE (business_id, subdomain)

API exposes hasSoapToken: boolean (derived from soap_token_encrypted IS NOT NULL); never returns token plaintext.


Table: rpapos_id_map

Idempotency for all entity types.

ColumnTypeNotes
iduuid PK
business_iduuid
entity_typerpapos_entity_type
external_idtextRPApos primary key / code as string
flowpos_entity_iduuidTarget row in FlowPOS
import_job_iduuidNullable; link to CSV/import job when applicable
source_payload_hashtextOptional change detection
last_synced_attimestamptz

Constraint: UNIQUE (business_id, entity_type, external_id)

Index: (business_id, entity_type)


Table: rpapos_sync_run

One row per migration/sync execution.

ColumnTypeNotes
iduuid PKReturned as syncRunId
business_iduuid
connection_iduuid FK → rpapos_connection ON DELETE CASCADE
modetextcatalog, historical, incremental, custom
statustextrunning, paused, completed, failed, cancelled
pausedbooleanPause flag (polled every 5s during run)
per_entity_statsjsonbMap of entity → { extracted, loaded, failed, status }. May include synthetic key product_images when image import ran (not a PostgreSQL enum value)
date_from / date_totimestamptzHistorical sync window (optional)
started_attimestamptz
completed_attimestamptz
created_byuuidFirebase user

Indexes: (connection_id, status), (business_id)


Table: rpapos_extraction_archive

Raw JSON snapshots for audit and replay.

ColumnTypeNotes
iduuid PK
business_iduuid
sync_run_iduuid
entity_typerpapos_entity_type
record_countinteger
payloadjsonbFull extracted array
extracted_attimestamptz

Index: (business_id, sync_run_id)


ALTER TABLE product
ADD COLUMN is_raw_material boolean NOT NULL DEFAULT false;
  • PLU imports → is_raw_material = false
  • SKU imports → is_raw_material = true
  • Product image import → updates product.image_url (GCS path) for rows matched via rpapos_id_map (entity_type = plu)

Import job linkage (product images)

Image runs create rows in existing import tables:

TableUsage
import_jobimport_type = 'product-image', options.syncRunId links to rpapos_sync_run.id
import_rowPer-PLU outcomes (success / error, Codigo_PLU, objeto_archivo)

Resolve from a sync run: GET /rpapos/sync-runs/:id/product-image-import-job?businessId=...


Kysely types

After migration, regenerate:

pnpm run generate:types

Generated table names use camelCase in TypeScript (e.g. rpaposConnection, rpaposIdMap).


Repositories

TableRepository
rpapos_connectionrpapos-connection.repository.ts
rpapos_sync_runsync-run.repository.ts
rpapos_id_mapid-map.repository.ts
rpapos_extraction_archiveextraction-archive.repository.ts