Cimplify

Entities and activities

The second half of the model. Building blocks describe what changes hands when a customer pays. Entities describe what the sale is about, and activities are what you remember about it over time. This is how a business gains a memory.

The mental model answers "what changes hands when a customer pays?" This page answers the two questions that come after it:

  1. What is the sale about? A repair is about a car. A grooming is about a pet. A refill is about a patient. A bag of coffee is about nothing in particular.
  2. What do you remember about it? The odometer reading, the vaccine given, the note that the customer approved the work, the reminder that service is due.

Get these two right and a plain point of sale becomes software that remembers: the mechanic sees the car's history before touching it, the vet sees the weight trend, the pharmacist sees the last refill. That memory is the whole game. It drives repeat business, it powers reminders, and it is what makes the same platform feel purpose built for a garage, a clinic, or a rental yard without a line of vertical code.

Read this as a decision guide, not a feature list. When you (or an agent) meet a new business or an unusual order, walk the procedure and the ladder. The worked examples show the answers; the procedure shows how to get there.

Two words, precisely

Entity. A thing an order can be about that has a life of its own: a vehicle, a pet, a device, a rental kayak, a rented unit, a prescription. It persists between orders and accumulates a history. Entities are minted in a lightweight registry; each one has a type (vehicle, pet, ...), a label ("Toyota Corolla"), some fields (plate, year), and a single parent that says who or what it belongs to.

Activity. Anything you record. A note, a measurement, a checklist result, a reminder, a status change, a link. Every activity attaches to exactly one thing: an order, a customer, or an entity. Activities are typed (a reading knows it is a number with a unit; a reminder knows it has a due date), which is what lets the platform chart them, flag them, and act on them.

The rest of this page is about two decisions: what to model as an entity (and how heavily), and where each activity should attach.

The one rule for where activities go

An activity attaches to whatever it is actually a fact about. Not where it was captured, not who was standing there, what it is true of.

What you are recordingIt is a fact about...Attach to
Staff note ("customer approved the rotor skim"), status change, payment, discount, refund reasonthis transactionthe order
Brake pad thickness, odometer, pet weight, blood pressure, inspection result, dispensed quantitythe thing being servicedthe entity (or the customer, see the ladder)
Allergies, colour formula, preferred contact, lifetime value, which unit they rentthe personthe customer

The trap, and it is the single most common modelling mistake, is putting a fact about the subject onto the order. A "brake pad 2.0mm" reading recorded on order #1042 dies with #1042. Next visit is a different order, the car shows no history, and the entire reason the car is an entity is gone. A reading is never about the order. It is about the car, captured during the order. It lives on the car, stamped with the order it came from, so it shows on this order and is still there at the next service.

If you find yourself attaching a measurement of the subject to an order, stop. That fact belongs on the subject (the entity, or the customer). Orders hold what is true of the transaction only: notes, status, money.

The ladder: choosing how much to model

Not everything a sale is "about" needs to be a full entity. The model is a ladder, and you pick the lowest rung that carries what you need. Reaching for a heavy entity when a light one will do is the second most common mistake.

RungShapeThe subject...Lives onTypical verticals
0No subject...does not existnothingretail, food, restaurant
1Context on the customer...is the customer, or is a simple fact about themthe customer (fields + activities)salon, gym, property (which unit + complaints), personal training
2A customer's owned entity...is a distinct thing the customer owns, with its own historyan entity, parent = the customerauto (vehicle), vet (pet), device repair, dental (patient)
3A business or landlord owned entity...is a thing the business or a third party owns, used across many customersan entity, parent = the business, a location, or another entityrentals (the kayak), shared assets, landlord centric property (the unit)

The test for which rung

Ask, in order:

  1. Is the order about a specific thing at all? No, retail. Rung 0. Done.
  2. Does that thing need a life across visits or across customers?
    • No, it is just context on this person (their hair formula, which unit they rent). Rung 1. Record it as fields and activities on the customer. Do not mint an entity.
    • Yes, it accumulates a history that must outlive a single order. Go on.
  3. Who owns it?
    • The paying customer owns it (their car, their pet, their phone). Rung 2. Mint an entity, parent it on the customer.
    • The business owns it, or a third party does, and it is shared across customers (a rental van, a landlord's unit). Rung 3. Mint an entity, parent it on the business, a location, or the owner.

subject_entity_type on a service is really choosing the rung. null = rung 0, "customer" = rung 1, a synthetic type like "vehicle" = rung 2 or 3 depending on who you parent it under. One field, the whole ladder.

What an activity can be

Activities are typed. The type is what lets the platform treat a measurement as a number to chart, a reminder as something to fire, a checklist as pass or fail. The common kinds:

KindWhat it isExampleUsually attaches to
NoteFree text for the team"Customer nervous around clippers"order (transaction note) or customer (durable trait)
FieldA pinned, single value that is the current truthAllergies: penicillin; Plate: GR-4821-24customer or entity
ReadingA number (or money, or date) with a unit, kept as a seriesOdometer 84,120 km; Weight 38 kg; BP 138/88the entity (or customer at rung 1)
CheckA structured pass/fail or multi point result12 point inspection: 2 advisoriesthe entity, stamped with the order
ReminderA future dated prompt, often SMSService due at 94,120 kmthe entity (so it survives the order)
ReferenceA link from one record to anotherThis order is about vehicle Xthe order (points at the entity)
Automation eventSomething a pack did on its own"Refill reminder sent"wherever the pack acted

A field and a reading look similar but differ in intent: a field is the current value (you overwrite it), a reading is a point in a series (you keep them all). Odometer is a reading (you want the trend). Allergies is a field (you want the latest truth). When in doubt: if you would ever plot it or want the previous value, it is a reading.

Declaring a reading's shape

A reading is only as useful as what the pack declares about it. On the reading's schema, each field can carry a few annotations that tell the platform how to show it and, later, how to aggregate it. They are optional and additive; nothing breaks without them, but a reading that declares them charts cleanly and rolls up correctly.

AnnotationOnSays
x-unita fieldIts unit label, e.g. mmHg, km
x-ordera fieldWhere it sits in the display order
x-iconthe readingWhich icon represents it
x-metrica fieldThis is the number to chart and roll up (one per reading)
x-aggregatea fieldHow it rolls up over time: avg, sum, or last

Blood pressure declares systolic as the metric, averaged, in mmHg; the platform then trends it, and when a report later asks "average BP over 90 days" it can answer without anyone re-instrumenting the pack. Declare the metric once on the definition and it applies to every reading already recorded, which is what keeps the reporting layer something that can be generated later rather than built up front.

How an order learns what it is about

Nobody decides "attach the pet to this order and the car to that one" by hand. The service declares its subject, and everything follows.

The declaration

Every product or service carries an optional subject_entity_type. Packs ship it; merchants can set it on their own services.

Auto Care Pack                     Vet Pack
  entity type: vehicle               entity type: pet
  Brake service → vehicle            Grooming    → pet
  Oil change    → vehicle            Vaccination → pet

Barber (rung 1)                    Retail
  Haircut → customer                 Coca-Cola 1.5L → (nothing)

The value must be a registered entity type (or customer, or blank). That constraint is the bridge: a service can only be "about" something the platform knows how to model.

Capture, at whichever point comes first

Usually at checkout: you have already picked the customer, you add "Brake service", the cart reads its subject_entity_type, sees it needs a vehicle, and resolves it:

  • Customer has one vehicle, attach it silently.
  • Customer has several, ask "which vehicle?"
  • Customer has none, offer "add vehicle" inline (plate, year), then attach.
  • No line item declares a subject, ask nothing, attach nothing. (The retail order.)

But checkout is not the only capture point. A drop off, a booking, or a quote can set the link earlier, before there is even a payment. The rule is simply: the link is written whenever the subject first becomes known.

The order carries a lightweight reference to the entity. The entity is not re-parented onto the order (that would silo it, the same trap as a reading). The car stays owned by its owner; each order that touches it holds a pointer. Readings taken during the order carry the reverse stamp (which order they came from), so the order can show "what was recorded here" and the car keeps the reading forever.

The separation that makes the whole thing hold: subject is not who transacts

This is the load bearing idea, and the vertical that proves it is the pharmacy.

When your mother takes you to the hospital, they record against you, not your mother. The customer on the order is the patient. Your mother is not the customer, she is not in the record as anything, she simply hands over the money. The prescription, the dispensing log, the interaction check all attach to the patient, because the patient is who the order is for.

So there are two independent axes, and confusing them invents problems that do not exist:

  • Who the order is against (the customer / patient / owner). This owns the subject and is what records attach to.
  • Who tenders the payment (cash from a relative, a card, an insurer). This is a payment concern, tracked as payment, not as the customer.

Once these are separate, a whole class of apparent edge cases dissolves:

  • Caregiver pickup (someone collects a prescription for a relative): order is against the patient, the relative is just tender. No problem.
  • Insurance job (the insurer pays to fix the policyholder's car): order is against the policyholder, who owns the car; the insurer is a payer, handled in payments and settlement, not in the entity.
  • A friend drops off and pays for your car: the order is against the car's owner. You identify the owner as the customer, exactly as a pharmacy identifies the patient.

Never bind "customer" to "whoever walked in or paid". The customer is who the record is true of. Identifying that person (patient lookup, owner lookup) is a capture discipline, and it is the same discipline in every vertical.

Ownership and the parent tree

Every entity has exactly one parent, and the parent can be almost anything: a customer, the business, a location, or another entity. That single pointer, allowed to point anywhere, is what makes the model bend to reality.

  • Customer owned (rung 2): a vehicle's parent is its owner.
  • Business or third party owned (rung 3): a rental van's parent is the business; a landlord's unit's parent is the landlord.
  • Nested (a tree): a wheel under a vehicle under a customer; a boiler under a property under a landlord. The tree is how "equipment at an address that a landlord owns" models cleanly without a special case.
  • Unowned: a stray brought to a vet has no owner yet, the parent can be null (or the business), and be re-pointed if it is adopted.
  • Re-parenting: a car is sold, a pet is adopted, ownership moves. The single pointer is updated. History stays with the entity.

One parent, pointable anywhere, is deliberately simple. If a business ever genuinely needs many owners for one thing (co-owned asset), that becomes a later relationship on top; single parent migrates into it cleanly, the reverse would lose information.

The procedure

For a human or an agent looking at any order, business, or "how do I record this?" question, walk this. First match wins.

Step 1, is there a subject? Look at the line items. Does any product or service declare a subject_entity_type? If none do, the order is rung 0. Record only transaction facts (notes, status, payment) on the order. Stop.

Step 2, what rung is the subject? Apply the test. Is it context on the person (rung 1), a thing they own (rung 2), or a thing the business or a third party owns (rung 3)?

Step 3, identify the subject, not the payer. The customer on the order is who it is about (the patient, the owner). Whoever pays or presents is payment, not the customer. At rung 2 or 3, resolve the entity from the customer's (or business's) entities of that type: one attaches silently, several prompt, none create.

Step 4, place each activity by what it is true of. Transaction facts (notes, status, money) to the order. Measurements and checks of the subject to the entity (or the customer at rung 1), stamped with the order. Durable traits of the person to the customer.

Step 5, let the pack do the rest. Reminders (service due, vaccine due, refill due) live on the entity so they survive the order and fire on schedule. That is the repeat business engine, and it comes for free once the readings are on the entity.

Worked examples

Each shows the subject, its rung, and where things land.

Auto repair (rung 2)

Subject: the vehicle, owned by the customer. Order: "Brake service" declares vehicle, checkout attaches the customer's Corolla. Readings (brake pad 2.0mm, odometer 84,120) go on the Corolla, stamped with the order. Note "customer approved rotor skim" goes on the order. Next visit: the Corolla shows its brake history and the "service due" reminder has already fired. The payoff is entirely because the reading lived on the car.

Vet (rung 2)

Subject: the pet. "Grooming" and "Vaccination" declare pet; a two pet household prompts for which. Weight and vaccine go on the pet; "nervous around clippers" is a durable trait, so it also goes on the pet, not the order. Vaccine schedule and reminders live on the pet.

Pharmacy (rung 2, with policy)

Subject: the patient (and often a prescription entity under them). The order is against the patient regardless of who collects or pays. Dispensed quantity, refills remaining, interaction checks attach to the prescription. A relative paying is tender; an insurer is a payer. On top of the generic model, pharmacy adds a policy layer (controlled substance logging, record access control, retention), because a prescription carries legal weight a vehicle does not.

Salon / barber (rung 1)

Subject: the customer themselves. subject_entity_type = "customer". No separate entity. Colour formula and hair notes are fields and activities on the customer. The haircut is the order.

Property management (rung 1, or rung 3)

Two valid shapes, pick by need:

  • Tenant centric (rung 1): the customer is the tenant. "Unit 4B", lease end, and complaints are fields and activities on the tenant. Monthly rent is the order. Nothing new to build; it is activities on the customer. Right when you only need to know each tenant's unit and log their complaints.
  • Landlord centric (rung 3): the customer is the landlord (the property manager's client). The unit is an entity owned by the landlord, referenced by rent orders, and it accumulates maintenance history across tenants. Right only when the unit needs a life independent of who rents it.

Rentals (rung 3)

Subject: your asset (the kayak, the drill). The entity is business owned. Each rental order references it; condition checks and damage notes go on the asset, building a utilization and wear history across every renter. What looked like an ownership problem (the customer does not own the thing) is the feature: per asset history.

HVAC / field service (rung 2, nested)

Subject: equipment at a property. The boiler's parent is the property; the property's parent is the customer. "Filter due", "last serviced", warranty window live on the equipment. The tree carries "a landlord's equipment across ten addresses" with no special case.

Device repair (rung 2)

Subject: the device, owned by the customer. Like auto. A trade in is the one twist: the device becomes your stock, so its parent moves from the customer to the business (rung 2 to rung 3) at the moment of trade in.

Gym (rung 1)

Subject: the member (the customer). Check ins, class packs, and progress are activities on the customer; the membership itself is an access grant. No separate entity needed.

Restaurant / retail (rung 0)

No subject. The model correctly does nothing: no prompt at checkout, no entity, no card. Notes, status, and payment on the order, and that is all. Emptiness here is correct, not a gap.

Anti-patterns

The recurring mistakes, and the fix for each.

  • Parenting the subject on the order. It silos the thing to one sale and destroys the history. Fix: parent on the owner (customer, business, location); let the order reference it.
  • Putting readings on the order. Same silo, one level down. Fix: readings go on the entity (or customer), stamped with the order.
  • Modelling everything as an entity. Reaching for rung 2 when rung 1 will do adds a phantom object. Fix: if the subject is the person or a simple fact about them, keep it on the customer.
  • Binding "customer" to who paid or walked in. Invents ownership problems that do not exist. Fix: the customer is who the record is against; payment is a separate axis.
  • Letting quantity imply the subject. "Brake service x2" is not "two vehicles". Fix: assign the subject per line, explicitly; quantity is just quantity.
  • Free text where a type belongs. A note that says "odometer 84120" is invisible to charts, reminders, and Reesa. Fix: record it as a reading so the platform can act on it.
  • Over modelling retail. A coffee shop does not need entities. Fix: rung 0, move on.

Quick reference

The ladder

0  no subject                         retail, food
1  context on the customer            salon, gym, tenant + unit + complaints
2  a customer's owned entity          vehicle, pet, device, patient
3  a business/third-party entity       rental asset, landlord's unit, shared kit

Where activities attach

transaction fact (note, status, money)   → order
measurement/check of the subject          → entity (stamped with the order)   [rung 2/3]
                                          → customer                          [rung 1]
durable trait of the person               → customer
a reminder about the subject              → entity (so it outlives the order)
a link to the subject                     → order (references the entity)

The two axes to keep separate

who the order is against  = the customer / patient / owner  → owns the subject, holds the records
who tenders the payment   = cash, card, relative, insurer   → a payment concern, not the customer

Where this is still hardening

Per line multiplicity is now solved. One order can be about several subjects, each line can name its own (a fleet invoice attributes and subtotals per vehicle), and the reference is a reconciled set rather than a single pointer. Picking which line is about which subject is still an explicit choice, not something quantity can imply, but the model and the surfaces for it exist.

Two layers are deliberately scoped, not yet built:

  • Per type policy. A prescription or patient carries obligations (controlled substance logs, record access, retention) that a vehicle does not. That is an additive policy layer on the generic registry, delivered by the vertical's pack, not something the base engine assumes.
  • Analytics across subjects. One subject's history is instant; aggregate questions ("average odometer across the fleet", "revenue per vehicle") are not yet a first-class query. The reading metadata above is deliberately rich enough that a reporting layer can be generated from it later, but that layer is not built.

Everything else on this page is the stable model: a subject declared by the service, an entity owned by whoever actually owns it, activities placed by what they are true of, and a memory that compounds across every visit.

On this page