Documentation Index

Fetch the complete documentation index at: https://docs.aifabrix.ai/llms.txt

Use this file to discover all available pages before exploring further.

Build a static entity

Prev Next

Outcome

When you finish this guide, you have a minimal static external system and business entity — validated, uploaded, and ready to supply dimension or join data for ABAC and records search.

Static datasources hold reference rows your CRM or ERP does not provide — country mappings, department codes, or cross-system keys. They use the same recordStorage contract as vendor-backed datasources so dimensions, protection, and records search treat static rows like any other governed records.

Prerequisites

  • Builder CLI login (aifabrix auth status)
  • Static data for dimensions understood
  • Dimension catalog keys planned (create catalog entries before cross-system ABAC if new keys are required)
  • Integration folder writable under your workstation layout

Where it lives

Artifact Location
Application manifest integration/<systemKey>/application.yaml
Static system JSON integration/<systemKey>/<systemKey>-system.json
Static datasource JSON integration/<systemKey>/<systemKey>-datasource-<name>.json
Deploy manifest Generated via aifabrix json <systemKey>

Use type: custom on the external system for static reference data not backed by a vendor OpenAPI spec.

How to set

  1. Create external integration scaffold:
aifabrix create <systemKey> --type external
  1. Author system JSON — custom system for static mappings (api key or platform auth per your environment template).

  2. Add datasource JSON — minimal valid shape:

{
  "key": "case-region-mapping",
  "displayName": "Case Region Mapping",
  "systemKey": "static-reference",
  "entityType": "recordStorage",
  "resourceType": "region-mapping",
  "primaryKey": ["externalId"],
  "labelKey": ["caseId"],
  "enabled": true,
  "metadataSchema": {
    "type": "object",
    "properties": {
      "externalId": { "type": "string", "index": true },
      "caseId": { "type": "string", "index": true, "filter": true },
      "country": { "type": "string", "index": true, "filter": true }
    }
  },
  "fieldMappings": {
    "attributes": {
      "externalId": { "expression": "{{raw.externalId}}", "description": "Stable row key" },
      "caseId": { "expression": "{{raw.caseId}}", "description": "CRM case identifier" },
      "country": { "expression": "{{raw.country}}", "description": "Country for ABAC dimension" }
    }
  },
  "dimensions": {
    "country": { "type": "local", "field": "country" }
  }
}
  1. List business entity in application manifest — run repair if file lists drift:
aifabrix repair <systemKey> --dry-run
aifabrix repair <systemKey>
  1. Validate structure:
aifabrix validate <systemKey>
  1. Upload when ready:
aifabrix upload <systemKey> --probe
aifabrix upload <systemKey>
  1. Load rows with datasource load — after the business entity is published on the dataplane, import JSON or NDJSON fixtures through bulk record sync (aifabrix datasource load <datasourceKey> --app <systemKey>; use --dry-run first, --file to override the default path):
aifabrix datasource upload reference-countries --app <systemKey>
aifabrix datasource load reference-countries --app <systemKey> --dry-run
aifabrix datasource load reference-countries --app <systemKey> -v

By default, fixture files live under integration/.data/ as {systemKey}-data-{entitySuffix}.json (for example static-reference-data-countries.json for business entity key reference-countries). Override with --file ./path/to/rows.json.

  1. Declare cross-system joins — set foreignKeys on CRM or ERP datasources so countryCode (or your normalized field) references the static country catalog. See Cross-system relationships.

  2. Reference in ABAC on protected datasources — cross-system expressions join vendor records to static rows and filter on shared dimension keys. See Dimensions and access model.

  3. Re-run governance certification when static mappings change visibility for subject-scoped test users — dimension outcomes shift immediately after row updates.

Defaults and examples

ISO country catalog (join key across CRM, ERP, and document systems)

SAP, Salesforce, HubSpot, and other vendors represent country differently — full names, numeric codes, picklist IDs, or optional fields. For ABAC and records search, normalize on a single static catalog keyed by ISO 3166-1 alpha-2 (two-letter codes such as FI, DE, US).

Source for codes Notes
ISO 3166-1 Authoritative standard — use alpha-2 as the canonical join key
Your master data team Often already maintains an approved country list for ERP/CRM
Dev fixtures Start with a small subset; expand to the full catalog under change control
Do

Do: normalize vendor country fields to ISO alpha-2 in CRM field mappings (or a mapping static datasource) before joining to the country catalog.

Don't

Don't: join CRM picklist IDs directly to static ISO rows without a translation table — codes will not match across systems.

Country catalog datasource (minimal manifest excerpt):

{
  "key": "reference-countries",
  "displayName": "ISO country catalog",
  "systemKey": "static-reference",
  "entityType": "recordStorage",
  "resourceType": "country",
  "primaryKey": ["countryCode"],
  "labelKey": ["name"],
  "enabled": true,
  "metadataSchema": {
    "type": "object",
    "properties": {
      "countryCode": {
        "type": "string",
        "index": true,
        "filter": true,
        "description": "ISO 3166-1 alpha-2 code"
      },
      "name": { "type": "string", "index": true, "filter": true }
    }
  },
  "fieldMappings": {
    "attributes": {
      "countryCode": { "expression": "{{raw.countryCode}} | toUpper | trim" },
      "name": { "expression": "{{raw.name}} | trim" }
    }
  },
  "dimensions": {
    "country": { "type": "local", "field": "countryCode" }
  }
}

Fixture file (integration/.data/static-reference-data-countries.json):

[
  { "countryCode": "FI", "name": "Finland" },
  { "countryCode": "DE", "name": "Germany" },
  { "countryCode": "SE", "name": "Sweden" },
  { "countryCode": "US", "name": "United States" }
]

Load after publish:

aifabrix datasource load reference-countries --app static-reference --dry-run
aifabrix datasource load reference-countries --app static-reference -v

Then declare a foreign key on your CRM customer datasource so metadata.countryCode references reference-countries.countryCode. Records search and ABAC can join customers, documents, and the shared country dimension through the same code.

Export governed rows for diff or backup:

aifabrix datasource export reference-countries --app static-reference --limit 500 -v

Use export after load to confirm rows landed — see Validate loaded data in the dataplane.

Case-to-country mapping (when CRM has no country field)

Field Typical value
entityType recordStorage for row-oriented mappings
resourceType Catalog key describing mapping purpose (country, region-mapping, …)
primaryKey Stable row key (countryCode for ISO catalog, externalId for mappings)
dimensions Bind static metadata paths to catalog keys

Use the case-region JSON in step 3 when the vendor system lacks country entirely and you map business keys to countries in a separate static datasource.

When to repair

After adding or renaming business entity files:

aifabrix repair <systemKey> --expose --rbac
aifabrix json <systemKey>

Validate loaded data in the dataplane

After datasource load, confirm what the platform stores by exporting through governed records search — not a database admin dump:

aifabrix datasource export reference-countries --app <systemKey> --limit 500 -v
aifabrix datasource export reference-countries --app <systemKey> --format ndjson --filter '{"countryCode":{"eq":"FI"}}'

Compare export output to your fixture file (row counts, keys, dimension fields). For subject-scoped proof, run export with the same Bearer token you use for verify-governance or records-search checks — not only the integrator token used to load rows.

Do

Do: treat datasource export as “what Records Search returns for your principal.” Use -v to see ABAC exclusion counts when rows exist in storage but not in the export file.

Don't

Don't: assume export lists every physical row. Export uses the governed search path (record:search permission) with ABAC and dimension projection applied — the same visibility rules as the dataplane UI and records search APIs. This is not a platform-admin or direct-database service.

How access rights apply (load vs export)

Both commands run with your deployment token (Bearer/API key or application token from client credentials). Neither bypasses platform RBAC.

Command Permission What your token controls
datasource load external-data-source:sync Whether you may write fixture rows through bulk sync. Without sync scope, the command is denied.
datasource export record:search Which rows you may read back through governed search. With protection and dimension grants active, you may receive only the subset your principal is allowed to see — even if load inserted more rows under a broader sync token.
Don't

Load vs read scope: An integrator token that can sync all countries may still fail to export all countries when logged in as a subject-scoped test user. Validate governance with the subject token, or compare verify-governance / records-search results — not export alone under a privileged sync account.

Validate

aifabrix validate <systemKey>
aifabrix datasource validate reference-countries --app <systemKey>
aifabrix datasource load reference-countries --app <systemKey> --dry-run
aifabrix datasource load reference-countries --app <systemKey> -v
aifabrix datasource export reference-countries --app <systemKey> --limit 500 -v
aifabrix datasource validate case-region-mapping --app <systemKey>

Run subject-scoped verify-governance when static rows participate in protection-backed datasources. Confirm records search returns expected scope for a test subject after mapping loads.

Common mistakes

Mistake Fix
Business Entity not in application.yaml repair syncs file lists
Missing dimension bindings Add dimensions object on static datasource
Wrong load file path Default: integration/.data/{systemKey}-data-{suffix}.json; use --file to override
Export shows fewer rows than loaded Expected under subject-scoped tokens — export is governed read, not admin dump
Stale mapping data Operational process for bulk reloads via datasource load
Skipping upload Static rows exist only after publish
Huge files in static JSON Use bulk load — do not embed all rows in manifest

Limits

Bulk load uses the external-data-source:sync permission (bulk sync API). Export uses record:search (governed records search with ABAC). Row limits and batch sizes vary by deployment — confirm with your operator before large loads.

Changing static mapping rows changes ABAC outcomes immediately after sync. Treat updates as production access changes — not informal spreadsheet edits. datasource export under a restricted principal may show zero rows while storage still holds data excluded by ABAC — use -v and subject-scoped tokens when validating protection.