RPApos Gateway — Entity Mapping
How each RPApos catalog entity is transformed and loaded into FlowPOS.
Document version: 1.0 · Last updated: 2026-05
Dependency graph
Hard prerequisites (auto-expanded in custom sync):
flowchart TD
moneda[moneda]
uom[unidad_medida]
plu_g[plu_grupo]
sku_g[sku_grupo]
prod_g[produccion_grupo]
bodega[bodega]
proveedor[proveedor]
area[area]
persona[persona]
sku[sku]
plu[plu]
usuario[usuario]
mesa[mesa]
batch[batch_maestro]
plu_option_g[plu_option_group]
plu_option_i[plu_option_item]
plu_option_a[plu_option_group_assignment]
plu_g --> plu
uom --> plu
sku_g --> sku
uom --> sku
bodega --> area
area --> mesa
plu --> batch
sku --> batch
uom --> batch
plu --> plu_option_i
plu_option_g --> plu_option_i
plu --> plu_option_a
plu_option_g --> plu_option_a
Canonical execution order is fixed in RPAPOS_CATALOG_ENTITIES (packages/global/enums/rpapos.enums.ts).
Summary table
| Entity | RPApos API | Sink | Import type / path | Primary FlowPOS tables |
|---|---|---|---|---|
moneda | Moneda | RestSink | — | currency, business_currency |
unidad_medida | UnidadMedida | RestSink | — | unit_of_measure, business_unit_of_measure |
plu_grupo | PLU/Grupo | HandlerSink | category | category |
sku_grupo | Producto/Grupo | HandlerSink | category | category |
produccion_grupo | Produccion/Grupo | HandlerSink | category | category |
bodega | Bodega | HandlerSink | location | location, address fields |
proveedor | Proveedor | HandlerSink | supplier | supplier domain tables |
area | area | RestSink | — | dining_area |
persona | Persona | RestSink | — | customer |
sku | SKU | HandlerSink | product | product (is_raw_material=true) |
plu | PLU/Maestro | HandlerSink | product | product (is_raw_material=false) |
usuario | Usuario | HandlerSink | employee | employee |
mesa | per-area Mesa/{id} | RestSink | — | dining_table |
batch_maestro | BatchMaestro | RestSink | — | product_recipe |
plu_option_group | SOAP Catalogo_4 Producto_Grupo | RestSink | plu (optional) | product_modifier_group |
plu_option_item | SOAP Producto_Grupo_Detalle / Manager API viw_Producto_Grupo_Detalle_1 (+ viw_Producto_Atributo_1 for labels) | RestSink | plu_option_group, plu (optional) | product_modifier |
plu_option_group_assignment | SOAP Producto_Grupo_Relacion / Manager API viw_Producto_Grupo_Relacion_1 | RestSink | plu, plu_option_group | product_modifier_group_assignment |
precio | PLU/Precio (REST) / viw_PLU_Precio_1 | — | — | Extract/archive only (no FlowPOS load yet) |
plu_option_attribute | viw_Producto_Atributo_1 (Manager API) | — | — | Extract/archive only (destination table TBD) |
Every successful row should also write rpapos_id_map for idempotent re-sync.
Full FlowPOS table index (catalog, orders, pricing, marketplace, RPApos source names): Menus & Modifier Groups — All related tables.
RestSink details
Moneda → currency
- Match by
currency_codeglobally; link to business viabusiness_currency.
UnidadMedida → unit_of_measure
- Match by name / RPApos name / abbreviation via
findUomIdFirstMatch. - Link via
business_unit_of_measure.
Area → dining_area
Location resolution priority:
- Planner
targetLocationId rpapos_id_mapforbodega→location- Oldest location created by
import_type=location - Oldest location for business
Upsert key: (location_id, name); updates location_id on re-sync when mapping changes.
Mesa → dining_table
- Resolves
area_idfromrpapos_id_map(entity_type=area, external id from row). - Fallback: first dining area at target location (or business-wide).
- Upsert:
(area_id, table_number); id map keyed by RPA mesa external id.
Persona → customer
- Upsert by
customer_codewithin business.
BatchMaestro → product_recipe
- Resolves parent PLU and ingredient SKU via
rpapos_id_map(plu,sku). - Resolves UoM via id map or first business UoM.
- Unique per
(parent_product_id, ingredient_product_id).
PluOptionGroup → product_modifier_group
Source: SOAP Catalogo_4 pTabla=Producto_Grupo. Requires registered SOAP token.
- Upsert keyed by
rpapos_id_map(entity_type=plu_option_group, external_id=<group id>). - Wire PK is usually
Producto_Grupo(notId) on tenant DBs; legacyIdstill accepted. auto_promptalwaysfalse.IdTipoGrupostored in raw blob only.
PluOptionItem → product_modifier
Source: SOAP Catalogo_4 pTabla=Producto_Grupo_Detalle, or Manager API viw_Producto_Grupo_Detalle_1 when credentials are present.
- Upsert keyed by
rpapos_id_map(entity_type=plu_option_item, external_id=<detail id>). - Wire PK is usually
Producto_Grupo_Detalle; group FK isProducto_Grupo(legacyId/Id_Grupostill accepted). modifier_group_idresolved via id map (plu_option_group,Producto_Grupovalue) — hard fail if id_map empty.linked_product_idresolved via id map (plu,Codigo_PLU, or numericProducto) — soft fail (NULL) with warning if unresolved.- Detail rows often have no label column. Manager API: orchestrator joins
viw_Producto_Atributo_1onProducto_Atributoto copyDescripcionandCodigo_PLUonto each detalle row before transform. Without that join, names fall back to linked PLU product name, then to"{group} — opción {orden}". - When
linked_product_idis set,quantity_per_modifieris forced to1(check constraint).
viw_Producto_Grupo_Relacion_1is not modifier items — it only links sellable PLUs to modifier groups (product_modifier_group_assignment). Option labels always come from detalle + attribute master (or linked PLU name).
PluOptionGroupAssignment → product_modifier_group_assignment
Source: SOAP Catalogo_4 pTabla=Producto_Grupo_Relacion. Requires registered SOAP token. No REST equivalent.
product_idresolved via id map (plu,Codigo_PLU/Id_PLU) — hard fail if missing.modifier_group_idresolved via id map (plu_option_group,Producto_Grupo/Id_Grupo) — hard fail if missing.- Unique constraint:
(product_id, modifier_group_id). - Pre-extraction guard: if
pluid_map is empty for the business, run fails withPLU_IDMAP_EMPTY.
HandlerSink details
Uses the same handlers as CSV import (apps/backend/src/data-import/application/handlers/).
Product (PLU / SKU)
- PLU: sellable product; category and UoM resolved by name; optional category id map when
PLU_Grupo_Nombremissing on wire. - SKU: raw material flag; orchestrator may pre-create categories from
SKU_Grupo_Nombrebefore handler runs.
Category groups
plu_grupo, sku_grupo, produccion_grupo all map to import type category with different transformer field mappings.
Bodega → location
Creates FlowPOS locations/warehouses; id map enables later dining area placement.
Usuario → employee
Employee import handler; may reference locations by name.
Proveedor → supplier
Standard supplier handler.
Metadata on rows
Transformers attach __rpapos (and related fields) for id mapping:
{
name: "Product name",
sku: "PLU-001",
__rpapos: {
externalId: "12345",
entityType: "plu"
}
}
IdMapWriterService reads this after sink success to populate rpapos_id_map.
Product images (PLU only)
Optional post-sync step (not a catalog entity type). Matching uses rpapos_id_map where entity_type = plu and external_id equals RPApos Codigo_PLU from SOAP Producto_U_M. Images are stored on product.image_url (GCS). Does not create new products — PLU must be imported first (or use a prior id map for images-only runs).
Quick start vs full catalog
| Entity | Quick start | Everything |
|---|---|---|
| moneda | ✓ | ✓ |
| unidad_medida | ✓ | ✓ |
| plu_grupo | ✓ | ✓ |
| sku_grupo | ✓ | ✓ |
| produccion_grupo | ✓ | |
| bodega | ✓ | |
| proveedor | ✓ | ✓ |
| area | ✓ | ✓ |
| persona | ✓ | |
| sku | ✓ | |
| plu | ✓ | ✓ |
| usuario | ✓ | ✓ |
| mesa | ✓ | ✓ |
| batch_maestro | ✓ | |
| plu_option_group | ✓ | ✓ |
| plu_option_item | ✓ | ✓ |
| plu_option_group_assignment | ✓ | ✓ |
Transformers (source)
| Entity | Transformer file |
|---|---|
| moneda | moneda.transformer.ts |
| unidad_medida | unidad-medida.transformer.ts |
| plu_grupo | plu-grupo.transformer.ts |
| sku_grupo | sku-grupo.transformer.ts |
| produccion_grupo | produccion-grupo.transformer.ts |
| bodega | bodega.transformer.ts |
| proveedor | proveedor.transformer.ts |
| area | area.transformer.ts |
| persona | persona-cliente.transformer.ts |
| sku | sku.transformer.ts |
| plu | plu.transformer.ts |
| usuario | usuario.transformer.ts |
| mesa | mesa.transformer.ts |
| batch_maestro | batch-maestro.transformer.ts |
| plu_option_group | plu-option-group.transformer.ts |
| plu_option_item | plu-option-item.transformer.ts |
| plu_option_group_assignment | plu-option-group-assignment.transformer.ts |
Payload types: apps/backend/src/rpapos/domain/types/rpapos-payloads.types.ts