The situation
The customer record started small. Then sales wanted a segment, support wanted an entitlement, finance wanted a billing contact per entity, and legal wanted the signed agreement reference. Each addition is a migration, an API change and front-end work, so the queue never empties — and the teams that could not wait keep their own spreadsheet, which is where the real data now lives.
These are illustrative scenarios showing how the products are used, not customer case studies.
Build-versus-buy lens
What this helps you decide
Use the example to find where product configuration ends and custom code begins — and whether the boundary leaves your team with less infrastructure to own.
- Model fit
- Can the record shape evolve without coordinating a migration, API and UI release?
- Workflow fit
- Can approvals, exceptions and deadlines move out of application code without losing control?
- Integration fit
- Can your existing APIs become reusable steps with retries, throttling and visible run history?
- Control fit
- Can your team reconstruct model changes, workflow runs and human decisions later?
What gets modeled
The structure as it would actually be defined — sections that repeat are marked.
- Customerrecord type
- Identitysection
Legal name, registration, country
- Contactsrepeating section
- Rolechoice
Billing, technical, legal
- Emailtext
Validated as an address
- Entitiesrepeating section
A customer is often several legal entities
- Entity nametext
- Billing contactchoice
Chosen from this record’s contacts
- Segmentchoice
Sales owns the list
How it gets built
In the order somebody would actually do it. Each step names the capability it rests on, so it can be checked against the product pages.
Model the customer as the several things it is
A customer has contacts and often several legal entities, both of which repeat, and a billing contact belongs to an entity rather than to the customer. Getting that shape right is what stops each team needing a field of their own to work around it.
What it uses: Sections that nest and repeat to any depth
Add the next field without a release
A new field is a change to the working draft, analyzed against the live version first: breaking, migration-required, or untouched. The queue empties because adding a field stops being a project.
What it uses: One working draft per schema, with impact analysis before publish
Let each team own its own list
Segment reads live from the list sales owns; contact roles read from theirs. Nobody files a ticket to add a segment, and the form, the validation and the API all see it on the next read rather than at the next deploy.
What it uses: Live option sources
Catch the same customer twice
Duplicate rules are defined on the schema — registration number exactly, with a similarity threshold for the near misses that differ by a suffix or a space. The rules are versioned with the schema rather than living wherever the last import ran.
What it uses: Duplicate detection with a similarity threshold
Make it findable
Full-text search across the record type, weighted so a legal name matters more than a note, with language-aware stemming. The spreadsheet existed partly because finding anything was hard.
What it uses: Full-text search with per-field weighting
Give every system one contract
The record type is published with its own REST URL space and an API description generated from the model, plus a schema description per version. Billing, support and the warehouse read the same definition rather than three interpretations of it.
What it uses: Its own API on publish, described by a generated API description
Keep who changed what
History is enabled on the schema, so every write keeps a snapshot and any retained point can be restored. When two teams disagree about who changed a billing contact, that is a lookup.
What it uses: Snapshot per write, restore to any retained point
Numbers used above, and where they come from
Every figure on this site is counted from the product itself. Nothing here is a performance or customer claim, because there is no measurement to cite for one.
- field types
- 9field typesCounted from egav/backend/app/api/v1/egav/schemas/entity_type_attribute.py — DataType
- places a choice list can come from
- 5places a choice list can come fromCounted from egav/backend/app/api/v1/egav/schemas/entity_type_attribute.py — OptionSourceType (file is reserved and not counted)
- ways a field can be presented
- 43ways a field can be presentedCounted from egav/backend/app/api/v1/egav/schemas/ui_configuration.py — WidgetType
What changes
One more field stops being a release, the shadow-sm spreadsheets lose their reason to exist, and every system that reads a customer reads the same definition.
Written for Teams with data that keeps changing shape.