Concepts
Record types#
mutation { definePlatformRecordType(input: {
key: "shipment", name: "Shipment",
schema: { type: "object", required: ["reference"], properties: { reference: { type: "string" } } },
states: ["booked", "delivered", "cancelled"], initialState: "booked",
displayTemplate: "Shipment {{data.reference}}"
}) { version } }
Changing the schema, states or transitions creates a new version; an identical call returns the current one. transitions ({ "booked": ["delivered"] }) restricts which moves are allowed.
Records#
upsertCustomRecord creates or updates a record by (company, type, externalId). data is validated against the type. A change of status or data bumps revision; the record keeps its history, the bookings it caused (effects) and its runs. deleteCustomRecord only works for a record without bookings.
Flow templates#
A template is YAML or JSON:
apiVersion: finbaze.com/flows/v1
kind: FlowTemplate
metadata: { key: shipment-invoicing, version: 1, recordType: shipment }
chart: rgs
ledgers: { carrier_costs: "<ledger code>", accrued_costs: "<ledger code>" }
on:
- transition: { to: delivered }
onDataChange: rebook # ignore (default) | rebook | fail
steps:
- id: invoice
create_sales_invoice:
relation: "= steps.customer.id"
date: "= $date(record.data.deliveredAt, 'Europe/Amsterdam')"
currency: "= record.data.currency"
finalise: true
lines:
- forEach: "= record.data.lanes"
as: lane
name: "Transport {{ lane.from }} - {{ lane.to }}"
priceMinor: "= lane.revenueMinor"
taxCode: NL_2012_HIGH
"{{ path }}"interpolates text. A string starting with=is a JSONata expression with typed results. Functions you can define yourself and$evalare not available.- Helpers:
$lookup(table, ctx),$net(grossMinor, taxCode),$vatRate(taxCode),$date(timestamp, zone),$euCountry(code). - Steps:
upsert_relation,upsert_project,create_sales_invoice,create_purchase_invoice,create_journal_entry,reverseandfail. Objects get the idflow:<template>:<record>:<step>, so running a trigger again changes nothing. - A
reversestep credits the invoices and mirrors the journal entries that a step of an earlier run created. It uses what that run recorded, never the current template.
testFlowTemplate plans what a template would do for sample records without writing anything. activateFlowTemplate checks that the ledgers named in ledgers exist in your companies' charts.
Runs#
A run is one transaction: if a step fails, nothing of the run is kept and the run is failed with the step, code and path. Runs of one record go in order, so a failed run holds the later ones back until you retryFlowRun. Events: flow_run.succeeded and flow_run.failed.