Why this exists. I'm building this POC in three layers — data → Temporal → UI — and the riskiest, least-settled part is the flows themselves (Emily's own note: "assume my flows are WRONG, I'll send the real process"). This document + the clickable demo are meant to surface my current understanding before I build deep against it, so you can correct course cheaply. If a box, an arrow, or a role is wrong, that's the most useful thing you can tell me.

0 · Read first — the one correction that changes the design

Toys Commercial / Commercial Lead does not operate inside this tool.

My earlier design (docs/temporal_workflow_design.md, local_website_plan.md) modelled a Commercial Lead approval gate inside the New-SKU workflow — a person who logs in and clicks approve. The 2026-06-12 meeting says that's wrong. Commercial approval happens offline, in the commercial team's own process; the merchant team obtains it and attaches the approval record; the Data Team verifies that attachment as part of its single review. There is no commercial login, no commercial signal, no commercial timer in the workflow.

00:04:53 — Brodie: Does the commercial team also approve customizations? Is that something we think about?
00:05:02 — Emily: Yeah, but … before we create a [SKU-spec], the commercial team will send approval and the merchant team will ask commercial team approval, so they need send the commercial approval records to data team. Once we review, OK, they got the approval, then we can [proceed].
00:05:24 — Brodie: Okay, so that's not something that this website would handle — you'd just upload the approval link, and you guys [Data Team] would check that.

And on what "Standard vs Customized" even means — the commercial team's role is upstream and external:

00:09:14 — Emily: Standard means commercial team approval — a standard list, like for Toys we had the July set and December set, and the commercial team will send their development list to NPD, and [NPD] will base on this list to provide the spreadsheet to us.
STD vs CUS gives the same single Data-Team approvalWhere commercial approval lives
STD (standard): commercial pre-approves a development list offline → NPD/PM batch-upload those specs via the STD template. Outside the tool. Captured as an uploaded approval link/record on the submission. The Data Team's single review includes a checklist item: "commercial approval attached?" — not a separate workflow stage.
CUS (customized): CUS PM / M&O / Sales / SP submit a customization request (based on a standard spec); commercial sign-off obtained offline and attached.

Net effect on the workflows: I've deleted the commercial_lead_decision signal and the upstream CL branch entirely. There is exactly one approval stage — the Data Team — for every flow, which is what Emily confirmed in the questionnaire (Part B Q1–3). The STD/CUS distinction only changes how the request arrives and what must be attached, not who approves in the tool.

1 · Who actually uses the tool

Three buckets. Only the first bucket fires workflow signals.

① Active — these roles operate in the tool (fire signals)

RoleWhat they do in the toolSignals they fire
PM / NPD PMSubmit STD new-product specs (batch via STD template, or single); provide initial product info. Data Team then completes the record.submit_new (STD), batch upload
Merchandising (M&O)Submit customized SKU-SPEC requests (e.g. new case-pack from STD 111-S001); request edits / retirement.submit_new (CUS), submit_edit, submit_retire
CUS PM / Sales / SPSubmit customer-specific (CUS) spec requests, based on a standard spec.submit_new (CUS)
Factory (incl. outsourced)Fill final mass-production dimensions (inner/outer/master shipper, pallet, weights, case pack). Picks the SKU — cannot free-type. Submits own dimension edits.factory_dimensions_submitted, submit_edit (own dims)
Data Team the engine roomThe single approval stage. Review → approve / reject-with-reason / edit-and-approve. Creates & completes the master spec (assigns SKU# / SKU-SPEC#). Runs cascade-with-exclude. Decides retire path + overrides guards. Triggers / confirms SAP sync. Manages dropdowns & promotes suggested option values.review_decision, spec_set, cascade_confirmed, retire_decision, guard_override, sap_sync_requested

② Read-only — in the tool, but no workflow gate

RoleWhy they're in the tool
Designer / EcommerceReads SKU# + barcode to produce packaging artwork (AW); supplies images / renderings. Emily corrected my earlier draft: the Designer does NOT set codes. No signal.
Sales / LendingRead-only consumers of approved specs. (Note: Sales/SP also appear as CUS submitters in the June-12 flow — flagged as a question in §7.)

③ External — do not operate in the tool

PartyRealityTool involvement
Commercial Team / Commercial Lead (incl. Toys Commercial)Approves the STD development list (Toys July/December sets) and customizations in their own offline process.None. Approval is uploaded as a record/link and verified by the Data Team. No login, no signal, no timer.
Legal / LicensingSigns licensor contracts; with Commercial, defines committed / permitted markets.None today. Data Team records permitted markets manually (future: link licensor ID from SAP).
SAPDownstream system of record for material numbers.Integration only (an activity, not a human) — returns the Material No. Website stays the source of truth.

2 · Why Temporal (in plain English, for non-engineers)

The website is great at a single click: submit a form, edit a cell, approve a record. It is bad at the thing in between — a spec that is born from a request, waits on the Data Team, waits on a Factory in another timezone, gets rejected and resubmitted, then finally syncs to SAP — over days, touched by several people, where any step can stall.

Temporal is the tool for exactly that. Each flow becomes one durable workflow that:

The website starts a workflow and signals it (every approve/reject/submit click is a signal). The workflow calls back into the website's API and SAP via activities. The permission matrix still decides who may fire which signal — Temporal sequences already-authorized actions, it doesn't replace login/authz.

3 · The signal contract — the seam between website and Temporal

This is the most important table for the build: it is the interface all three layers agree on. The clickable demo simulates exactly these signals. Pin this early and the data/Temporal/UI layers can be built against it independently.

human signal (a button on the website) system activity (Temporal acts; no human) durable timer
SignalFired byFrom which pageCarriesEffect
submit_newPM, M&O, CUS PM, Sales/SPNew SKU form / Batch UploadSTD|CUS, payload, commercial_approval_ref (CUS)Starts NewSpecWorkflow
submit_editFactory, M&O, Data TeamSKU Detail / Batch Editchanged fields + before/afterStarts EditSpecWorkflow
submit_retireM&O, NPDSKU Detailspec id + reasonStarts RetireSpecWorkflow
submit_batch_uploadNPD / PMBatch UploadExcel file (N rows)Starts BatchUploadWorkflow
review_decisionData TeamReview Queueapprove | reject + required reason | edit-and-approveThe single approval stage
spec_setData TeamReview / SKU Detailassigned SKU# / SKU-SPEC#, completed fieldsData Team creates/completes the record
factory_dimensions_submittedFactoryBatch Edit / SKU Detailcartons, pallet, weights, CBMAdvances New/Edit past the factory wait
cascade_confirmedData TeamCascade Confirm modalwhich sibling specs to include/exclude (tick-boxes)Applies a shared-field change across specs
retire_decision / guard_overrideData TeamReview Queueretire path; override reasonDrives soft-delete + SAP freeze
sap_sync_requestedData TeamReview / Adminspec id(s)Manual "Sync now" (if SAP sync is manual — Jarry Q)
notify_role · send_sla_alert · sync_to_sap · compute_affected_specs · run_retire_guard · write_change_logsystem (activities)Side-effects: email, SAP push, cascade math, audit. Retried with named policies.

4 · The workflows

Six things genuinely deserve a durable workflow; a few more are candidates I'd argue against (§4.8). Diagram legend:

start human signal system activity decision reject / back to submitter terminal

4.1 · NewSpecWorkflow — ideation → SAP sync core

The richest flow, and the one Emily drew on 12 Jun. Note: the submitter raises a request; the Data Team creates & completes the master record ("Data team turn to Create / revise SPEC"). STD/CUS only changes how it arrives + what's attached — same single approval.

Spec requestNew product enters the system → New or Update?
STD or CUS spec?
STD
signal · PM / NPDsubmit_new(STD) — batch-upload via STD Spec template (commercial-approved dev list)
CUS
signal · CUS PM / M&O / Sales / SPsubmit_new(CUS) — request based on a standard spec, + commercial_approval_ref attached
▼ both converge
systemnotify_role(data_team) + start SLA timer
signal · Data Teamreview_decision — verify completeness + commercial approval attached
reject + reason
systemnotify_role(submitter) email → submitter revises & resubmits (same durable record)
▼ approve
signal · Data Teamspec_set — create/complete record, assign SKU# / SKU-SPEC#
systemStatus → Needs dimensions; notify_role(factory) + SLA timer
signal · Factoryfactory_dimensions_submitted — cartons, pallet, weights, CBM
If need Sync to SAP? (per-spec gate Emily drew)
no
systemnotify_role(submitter) "spec request done" (email)
▼ yes
system · activitysync_to_sap → if material exists: update master; else create → Material No. flows back
Approved → Ready for SAP → Synced · Live / Ready to Order

4.2 · EditSpecWorkflow — change an existing spec core

The headline is cascade-with-exclude (Emily Part B Q7): when a SKU-level shared field changes, it must propagate to all that SKU's specs, with a confirm screen to tick off exceptions. This is the single biggest thing Airtable could not do.

signal · Factory / M&O / Data Teamsubmit_edit — picks SKU, submits field change(s)
Data Team direct-edit? (Data Team may bypass approval — Q6)
no — needs review
systemStatus → Needs Review; notify_role(data_team) + SLA
signal · Data Teamreview_decision — approve / reject + reason
▼ approved (or bypassed)
Changed field is SKU-level (shared)?
yes — cascade
system · activitycompute_affected_specs — list every sibling spec on this SKU
signal · Data Teamcascade_confirmed — tick-boxes to exclude exceptions
systemapply change → write_change_logsync_to_sap (affected records)
Synced

4.3 · RetireSpecWorkflow — retire / delete core

Never a hard delete. Soft lifecycle status + SAP view-freeze, behind a guard (don't orphan sibling specs / open orders / on-hand stock).

signal · M&O / NPDsubmit_retire — pick spec + reason
systemStatus → Needs Review; notify_role(data_team) + SLA
signal · Data Teamretire_decision — approve (+ retire path) / reject
system · activityrun_retire_guard — sibling specs? open orders? MA stock?
guard fails
signal · Data Teamguard_override (with reason) — or abort
systemlifecycle: Phase Out → Pending Deletion → Deleted; apply_sap_view_freeze (03/Z1 Blocked, not hard delete)
Soft-deleted + SAP frozen

4.4 · BatchUploadWorkflow — many new specs at once batch

Emily was firm: NPD won't enter records one-by-one ("they won't buy this idea"). A workflow that validates a whole Excel, reports row-by-row, lets the Data Team accept the valid rows, then fans out one child NewSpecWorkflow per accepted row — a natural Temporal pattern (durable validation + parent/child + partial accept).

signal · NPD / PMsubmit_batch_upload — STD Spec template, N rows
system · activityvalidate rows → row-level report (valid / errors / dup UPC-SKU)
signal · Data Teamaccept valid rows (reject/return the rest)
systemfan-out: start a child NewSpecWorkflow for each accepted row
N children running; batch closes when all resolve

4.5 · BatchEditWorkflow — edit many specs as one change batch

"The Airtable gap" Emily named: select many rows in a grid, change a field (e.g. case-pack / outer dimension), submit as one change request, reviewed once, applied across rows — with per-SKU cascade where the field is shared. (June-12: "batch update, batch create … only need to change the case pack, outer dimension.")

signal · Factory / Data Teamsubmit_edit (batch) — multi-select rows + field change
systemone change request; notify_role(data_team) + SLA
signal · Data Teamreview_decision — approve / reject + reason
signal · Data Teamcascade_confirmed — per affected SKU (if shared field)
systemapply to all rows → write_change_logsync_to_sap
Synced

4.6 · SAP sync — integration activity / Jarry-dependent

Emily's flowchart has an explicit "If need Sync to SAP?" gate, then "if material exists → update master, else → create" and material-number-back + notify. Two shapes, decided by Jarry:

I'll build it as a stubbed activity first (returns a fake Material No.) so nothing blocks on SAP access; the conditional structure is already known, only the mechanics (T-code ZMMR008, auth) are open.

4.7 · The shared spine (lives inside every flow — not separate workflows)

PatternWhat it is
Human-in-the-loop waitnotify_role → park on a signal → react. The one piece of code reused everywhere.
SLA timerA durable timer on every human wait. On breach → send_sla_alert to Data Team (email), keep waiting, re-alert. (Emily Part B Q11.)
Reject-with-reason loopReject (reason required) returns to the submitter to revise & resubmit on the same durable record — not a new ticket.
Audit logThe workflow's event history is the change log. write_change_log mirrors it into the website DB for the UI.

4.8 · Candidates I'd argue against making workflows scope guard

Listed so we can decide deliberately, not by accident. Default: plain CRUD / scheduled job, not Temporal.

ThingMy callWhy
Scheduled assortment activation (version + effective date)MaybeA durable timer that flips a version live on a future date is a legit Temporal use — if effective-dating actually matters. Else a scheduled job.
Barcode-pool low-stock alertNoA periodic threshold check, not a long-running, human-in-loop process.
Suggested option-value approvalNo (fold in)A lightweight approval item in Admin, or part of the main review — not its own workflow.
Barcode assignment, BOM edits, permitted-market edits, viewing/searchNoPure CRUD against the website DB. Temporal would add cost and latency for nothing.

5 · Build approach — and my honest critique of it

My plan: data layer → Temporal layer → UI layer. Here's where I think that's right, and where I'd amend it.

The order is right for construction.

Orchestration needs persistent state to act on; the UI needs the orchestration's signal contract to call. Building bottom-up avoids rebuilding the foundation. Keep it.

But separate "validate the design" from "the build order" — that's the fail-fast win.

The riskiest part of this project isn't any one layer — it's whether the flows are right at all. Emily literally said "assume my flows are wrong, I'll send the real process," that process doc hasn't landed yet, and the Commercial correction shows the design already drifted from reality. If I build a full data layer before the flows are confirmed, I risk polishing a foundation a flow change reshapes.

Two things to chase in parallel — they carry the most rework risk: (1) Emily's real end-to-end process-flow doc, and (2) 30 minutes with Jarry on SAP sync (auto vs manual, and is the write-back truly material-number-only). Don't block on them; do flag that deep work against guesses there is the most likely thing to be thrown away.

6 · Assumptions I'm making (correct me)

7 · Open questions for Emily / Jarry

  1. Commercial approval mechanics (Emily): confirm it's an uploaded record/link the Data Team checks — and is it ever required for STD, or only CUS?
  2. SAP sync (Jarry): auto-on-approve or manual "Sync now"? Is the write-back truly material-number-only? What fires "if need sync = no"?
  3. Factory ↔ SKU link (Emily): how do we know which factory to notify for a given SKU? (Decides who notify_role(factory) targets.)
  4. Retire guard data (Emily/Jarry): where do "open orders" and "on-hand MA stock" come from, so the guard can check them?
  5. Cascade field set (Emily): the promised Excel of which SKU-level fields cascade on a shared-value change — still coming?
  6. Sales/SP role (Emily): the grid says Sales = read-only, but the 12-Jun flow shows Sales/SP submitting CUS requests. Which is it?
  7. Batch granularity (Emily): for batch upload, does the Data Team approve the whole batch at once, or row-by-row?
  8. The real process-flow doc (Emily): the one you said you'd send — does it differ from what I've drawn here?

Sources: Emily's questionnaire "Master Data — What I Need From You" (Parts A–F, role + permission grids); the 2026-06-12 meeting recording (verbatim transcript + flowchart frames); Field Dictionary "Process Steps" tab (Brodie's draft, flagged by Emily as "assume wrong"); docs/local_website_plan.md. The earlier docs/temporal_workflow_design.md is superseded by §0 on the Commercial-Lead point.