Skip to content
Get Started

Lesson 3 - Shape the Data Model

We will take the starter ApprovalRequest entity from the Playground’s Request Approval example and reshape it around your business process (or HarborFlow’s process). Keep editing in the same Editor tab you used in Lesson 2.

In the HarborFlow story, this is where Taylor can start defining the real entity that the team works with: a customer exception request.

Rename the main entity to match the real workflow - like one of these following examples:

  • ApprovalRequestVendorRequest
  • ApprovalRequestAccessRequest
  • ApprovalRequestHiringRequest
  • ApprovalRequestContractReview

We’ll use this name to drive everything else in the blueprint.

For HarborFlow, the change is:

  • ApprovalRequestExceptionRequest

Keep only fields that someone will actually use in the first version. It’s very easy to include too much data.

The starter entity was modeling a purchasing approval, so some of its fields do not carry over cleanly:

  • amount does not apply to an exception request — remove it
  • category becomes exceptionType — keep it as an Enum, just with HarborFlow’s own values
  • managerId assumed a pre-assigned approver — HarborFlow’s ops team reviews as a pool, so remove it
  • requesterId becomes submittedBy — keep it as a Ref to TeamMember, since the Playground’s starting example already ships that entity. That gives you a real relationship for free instead of a placeholder text field.
  • add customerName as a new Text field — the customer experiencing the exception is external to HarborFlow, so there is no entity to reference yet. A plain text field is the right call here, in contrast to submittedBy, which points at an internal team member you already have a record for.

For HarborFlow, Taylor might end up with fields like:

  • customerName
  • submittedBy
  • exceptionType
  • priority
  • justification
  • status

One concrete version of that change looks like this:

[[entities]]
name = "ExceptionRequest"
fields = [
{ name = "id", type = "ULID", primary_key = true },
{ name = "title", type = "Text", required = true },
{ name = "customerName", type = "Text", required = true },
{ name = "submittedBy", type = "Ref", ref = "TeamMember.id" },
{ name = "exceptionType", type = "Enum", values = ["shipping_delay", "pricing_adjustment", "custom_terms", "other"], default = "other" },
{ name = "priority", type = "Enum", values = ["low", "medium", "high"], default = "medium" },
{ name = "justification", type = "LongText" },
{ name = "status", type = "Enum", values = ["submitted", "reviewing", "approved", "rejected", "completed"], default = "submitted" },
{ name = "createdAt", type = "DateTime", default = "now" }
]

The bundled example also ships an ApprovalAudit entity for tracking who did what to a request. You can leave the audit feature itself alone, but update its requestId reference so validation still passes after the rename:

{ name = "requestId", type = "Ref", ref = "ExceptionRequest.id", required = true }

Once you rename the entity, update every page that referenced ApprovalRequest — its queries, its form, and its detail page — to use ExceptionRequest instead. Also update any workflow step that still references ApprovalRequest. The Playground’s Validation tab will flag references still pointing at the old name, so use it as a checklist rather than re-reading the whole file by hand.

The bundled example splits its home page into a dashboard (/) and a separate request list (/requests). To keep things simple and match the rest of this course, delete the dashboard page and rename /requests to / so it becomes your one list page. You can always reintroduce a dashboard later once there is more than one thing worth summarizing.

The status values should mirror the real operating sequence.

For example:

status = { type = "Enum", values = ["submitted", "reviewing", "approved", "rejected", "completed"], default = "submitted" }

The important rule is that the statuses should reflect real business transitions, not placeholder words carried over from a different process.

For the HarborFlow narrative, the first useful set is:

  • submitted
  • reviewing
  • approved
  • rejected
  • completed

Every field and status should sound like something the team would say in Slack, Teams, email, or meetings.

That means:

  • prefer business language over technical language
  • avoid generic labels if there is a more precise term
  • remove ambiguity where two fields sound almost the same

You want the blueprint to feel like a natural extension of your team’s existing process, not something where you have to change the way everyone works.

For the blueprint - ask some of these questions as a quick review:

  • if a teammate saw this entity, would they immediately recognize it?
  • does the status progression match how the work really moves?
  • are any fields missing that block a reviewer from making a decision?
  • are any fields present just because the starter example invented them?

By the end of this lesson, you should have:

  • a renamed primary entity
  • a cleaner set of fields, including a real Ref relationship where one makes sense
  • statuses that match the workflow
  • one consolidated list page instead of a separate dashboard
  • a vocabulary aligned to the actual team

If you need syntax help while making those edits, use the Blueprint Reference.

In this lesson, you are mainly editing the entity section:

  • rename ApprovalRequest to ExceptionRequest
  • replace purchasing-specific fields with HarborFlow-specific fields
  • replace placeholder statuses with the real operating states
  • update page queries and forms so they reference ExceptionRequest
  • delete the separate dashboard page and consolidate on / as the list page

This is mostly an entity refactor with a few matching page updates.

Use lesson-3-blueprint.toml if you want a complete, working file after the entity rename, field cleanup, audit-reference update, and page consolidation.

The checkpoint should validate cleanly:

Terminal window
zebric validate --blueprint lesson-3-blueprint.toml
  • Entities: the main focus is field design, naming, relations, and status modeling
  • Pages: page definitions must stay aligned with the renamed entity
  • Blueprints: you are refining a working blueprint instead of regenerating it from scratch

Continue to Lesson 4 - Improve Intake and Review Pages.