Meet Upshift
A fictional European bicycle maker, and the company behind every example and exercise on this site.
Upshift designs, paints and assembles road and gravel bikes, and sells them through dealers, retail chains and web shops across Europe. It isn’t a real company, and none of its data comes from one. But it has the problems a real one has: late suppliers, a busy paint shop, a hub that may close and customers who change their minds.

Upshift at a glance
- plants, in Eindhoven and Bydgoszcz
- 2
- distribution hubs, from Venlo to Basel
- 5
- products, 133 of them bikes
- 204
- customers in 9 countries
- 52
- suppliers in 13 countries
- 30
- carriers, 1 of them by rail
- 8
The products
What Upshift makes
Two ranges of bikes, most models in a regular and an e-bike version (the “-E”), in several frame sizes and 8 colour codes. That makes 133 bike variants, plus the parts and gear a dealer sells alongside them.
Road
Aero 1, Aero 2, Aero 2-E, Strada and Strada-E
Gravel
Terra, Terra-E, Ridge, Ridge-E, Trail and Trail-E
Spares and accessories
41 spares, from batteries and wheelsets to chains, and 30 accessories, from helmets to locks.
The supply chain
How it operates
Goods flow one way through the company, and every step has its own data.
- 30suppliers
- 2plants
- 5hubs
- 52customers
Buy
85 bought-in components come from 30 suppliers: motors from Japan, batteries from Taiwan and groupsets from Italy, with most other parts from across Europe. Supplier agreements set the lead times, minimum quantities and delivery terms.
Make
Every frame is painted in Bydgoszcz, on two paint lines where the order of colours decides how much time goes on changeovers. Each bike model is assembled at one of the two plants. Eindhoven also fits e-bike batteries, and both plants run quality control and packing.
Store and move
Upshift runs its hub in Venlo itself; logistics partners run the other four. Northampton and Basel are customs warehouses, because the UK and Switzerland sit outside the EU. 21 transport lanes connect it all, served by 8 carriers, 6 of them approved for the dangerous goods that e-bike batteries are.
Sell and serve
The 52 customers are 31 dealers, 7 retail chains, 5 distributors, 5 teams and rental companies and 4 web shops. Each has an agreed delivery time of 2 to 10 days, and customer service keeps a register of complaints, questions and requests.
Plan
Demand planners forecast every bike each month, one and three months ahead. Each hub has stocking policies with service targets, and asks the plants for replenishment. A network study weighs scenarios for the future, including closing the Basel hub.
The team
Who works there
A small supply chain team, most of it in Eindhoven. A buyer, a production planner and the quality lead work at the Bydgoszcz plant, and the warehouse leads and customer service at the Venlo and Kassel hubs. When an exercise talks about “the buyer” or “the planner”, it means one of these roles.
- Supply chain director
- Demand planner
- Supply planner
- Two production planners
- Transport planner
- Three buyers
- Two plant managers
- Quality lead
- Two warehouse leads
- Two customer service agents
- Key account manager
- IT and data
The data model
How its data fits together
Upshift’s data is one synthetic dataset of 49 tables in 8 areas, all keyed to each other. This is its structure, not the data itself. The dates in the data follow a date you choose, so the company always looks current. Amounts are in euro, and some of the mess is deliberate: a few countries are spelled two ways, and a few forecasts appear twice, as they would in a real extract.
Every table
Time and people2 tables
calendarOne row per day from the start of the year before last to six months after the anchor. The only table that knows about weekdays and holidays.date- date · key
working_day- bool
holiday- text · optional · Dutch public holidays
iso_week- text
fiscal_period- text · YYYY-MM
relative_day- int · days from the anchor; negative is history
company_settingsA single row naming the anchor date, snapshot date, revision and seed the dataset was generated with.anchor_date- date · links to calendar
snapshot_date- date · links to calendar
dataset_revision- text
seed- int
company_name- text
currency- text
Master data13 tables
peopleEmployees referenced as owners, buyers and approvers.person_id- id · key
name- text
role- enum
location_id- id · links to locations
email- text
manager_id- id · links to people · optional
productsThe 204 catalogue records of the books: finished bikes, spares and accessories, in the columns of the original product catalogue.sku- id · key
description- text
category- enum · road, gravel, spare, accessory
drive- enum · optional · regular, ebike; blank for spares and accessories
model- text
frame_size- text · optional
colour- text · optional · WHT, SND, GRY, CHR, RED, OLV, NVY, BLK
plant_of_manufacture- id · links to locations
unit_cost- money
list_price- money
weight_kg- decimal
contains_battery- flag · Y or N
hs_code- text
country_of_origin- text
abc_class- enum · optional · derived from the last calendar year of orders
status- enum · active, phase-out
bikes_per_pallet- int
componentsThe 85 bought-in components with their supplier, cost, lead time and order rules.component_sku- id · key
description- text
supplier_id- id · links to suppliers
unit_cost- money
lead_time_weeks_std- decimal
moq- int
order_multiple- int
is_dangerous_goods- flag
bill_of_materialsWhich components go into each bike and how many; 3,720 rows for 133 bike parents.parent_sku- id · key · links to products
component_sku- id · key · links to components
quantity- decimal · powder coat is 0.1 per frame
suppliersThe 30 component suppliers.supplier_id- id · key
name- text
country- text
category- text
payment_terms- text
incoterm- text
contact_email- text
supplier_agreementsAgreed lead times, quantities and delivery conditions per supplier, with the clauses used to render agreement documents.agreement_id- id · key
supplier_id- id · links to suppliers
valid_from- date
valid_to- date · optional
standard_lead_time_weeks- decimal
expedite_lead_time_weeks- decimal · optional
moq_override- int · optional
order_confirmation_days- int
delivery_condition- text
late_delivery_penalty_pct- decimal
product_scope- text
clauses- json
locationsThe two plants (NL01 Eindhoven, PL02 Bydgoszcz) and five hubs, in the columns of the original location master.location_id- id · key
type- enum · plant, hub
name- text
city- text
country- text
operated_by- text
pallet_capacity- int
handling_cost_per_pallet- money
fixed_cost_per_month- money
customs_warehouse- flag
customersThe 52 customers of the books, defects included (UK and Deutschland as countries), served from a default hub or plant.customer_id- id · key
name- text
segment- enum · dealer, retail_chain, teams_rental, distributor, ecommerce
country- text
city- text
postcode- text
delivery_days_agreed- int
served_from_hub- id · links to locations
penalty_per_late_day- money
carriersThe 8 carriers with capacity, tariff, dangerous-goods approval and cut-off time.carrier_id- id · key
name- text
mode- enum · road, rail
countries_served- list
truck_capacity_pallets- int
cost_per_km- money
min_charge- money
dg_certified- flag
cutoff_time- text
lanesThe 21 transport lanes: plant to hub, hub to customer country and plant direct.from_location- id · key · links to locations
to_location_or_country- text · key
tier- enum · key · plant_to_hub, hub_to_customer, plant_direct
mode- enum · key
cost_per_pallet- money
transit_days- int
carrier- id · key · links to carriers
co2_kg_per_pallet- decimal
distance_km- int
dispatch_routesHub-to-country routes a carrier may run for dispatch planning, with the dangerous-goods approval profile.route_id- id · key
carrier_id- id · key · links to carriers
origin- id · links to locations
destination_country- text
distance_km- int
transit_working_days- int
eligible- flag
approval_profile- text
scope- text
fleetTrucks each carrier makes available per day.carrier_id- id · key · links to carriers
trucks_available- int
document_versionsThe procedure register: which version of a procedure is valid on a date, including one deliberately overlapping interval.document_id- id · key
procedure_id- id
title- text
version- int
operational_scope- text
effective_from- date
effective_to- date · optional
supersedes- text · optional
source_type- text
Demand and fulfilment6 tables
order_linesCustomer order lines in the columns of the original sales-order extract. An order_id groups the lines entered together and can, as in the source, occasionally cover more than one customer.order_id- id · key
line_id- int · key
customer_id- id · links to customers
sku- id · links to products
order_date- date
requested_date- date
confirmed_date- date · optional
shipped_date- date · optional
quantity- int
unit_price- money
ship_from_location- id · links to locations
status- enum · open, confirmed, backordered, shipped, cancelled
shipment_id- id · links to shipments · optional
cancel_reason- text · optional
forecastsMonthly company-level forecast per finished-bike sku, issued one and three months ahead. Contains a few duplicate keys, as the source did.sku- id · links to products
month- text
forecast_qty- int
forecast_version- text · ISO YYYY-MM issue month
shipmentsWhat left a location for one customer order on one trip.shipment_id- id · key
order_id- id · links to order_lines
customer_id- id · links to customers
from_location- id · links to locations
ship_date- date
recorded_arrival_date- date · optional
pallets- int
contains_dg- flag
trip_id- id · links to trips
status- enum · awaiting dispatch, dispatched, delivered
tripsTruck and rail departures in the columns of the original trip extract, for plant-to-hub transfers and hub-to-customer deliveries.trip_id- id · key
carrier_id- id · links to carriers
tier- enum
from_location- id · links to locations
departure_date- date
to_location_or_country- text
stops- int · optional
pallets_loaded- int
pallet_capacity- int
cost- money
distance_km- int
on_time- flag
status- enum · planned, departed, arrived, cancelled
planned_arrival- date
actual_arrival- date · optional
dispatch_requestsLoads waiting to be planned onto trips in the next working days.request_id- id · key
dispatch_date- date
route_id- id · links to dispatch_routes
origin- id · links to locations
destination_country- text
pallets- int
contains_dg- flag
ready_time- text
latest_delivery_date- date
may_split- flag
shipment_id- id · links to shipments · optional
customer_casesComplaints, enquiries and requests in the columns of the case register.case_id- id · key
customer_id- id · links to customers
order_id- id · links to order_lines · optional
category- enum
opened_on- date
recorded_status- enum
status_as_of- date
owner_role- text
thread_first- text · optional
thread_last- text · optional
status_note- text
Supply4 tables
purchase_ordersOne component per purchase order, in the columns of the original purchase-order extract.po_id- id · key
supplier_id- id · links to suppliers
component_sku- id · links to components
order_date- date
promised_date- date
received_date- date · optional · date of the last receipt
quantity- int
received_quantity- int
unit_cost- money
status- enum · open, confirmed, partially-received, received, cancelled
deliver_to_location- id · links to locations
agreement_id- id · links to supplier_agreements
buyer_id- id · links to people
receiptsGoods received against purchase orders, including short and late receipts.receipt_id- id · key
po_id- id · links to purchase_orders
component_sku- id · links to components
received_date- date
received_quantity- int
location_id- id · links to locations
quality_status- enum
discrepancy_note- text · optional
supplier_eventsDelay notices, short shipments, holds and recovery offers that supporting material narrates.event_id- id · key
supplier_id- id · links to suppliers
po_id- id · links to purchase_orders
event_date- date
event_type- enum
new_promised_date- date · optional
quantity_affected- int · optional
recovery_option- json · optional
purchase_requestsBuyer requests waiting to become purchase orders.request_id- id · key
component_sku- id · links to components
supplier_id- id · links to suppliers
request_date- date
quantity- int
required_date- date
supply_option- enum
buyer_note- text
status- enum
po_id- id · links to purchase_orders · optional
Inventory4 tables
stock_ledgerEvery stock movement of products and components. Snapshots are sums of this table.movement_id- id · key
movement_date- date
location_id- id · links to locations
item_sku- id · a products.sku or components.component_sku
movement_type- enum
quantity- int · signed
reference_type- enum
reference_id- text
stock_snapshotsStock positions at month ends and on the snapshot date, derived from the ledger, in the columns of the hub-stock extract.snapshot_date- date · key
location_id- id · key · links to locations
sku_or_component- id · key
on_hand- int
in_transit- int
on_order- int
allocated- int
quality_hold- int
unit_cost- money · optional
stocking_policiesWhich items are stocked where, with service targets and reorder parameters.sku_or_component- id · key
location_id- id · key · links to locations
stocked- bool
policy_type- enum
service_target_pct- decimal
safety_stock_qty- int
reorder_point_qty- int
order_up_to_qty- int
review_period_days- int
last_reviewed_on- date
replenishment_requestsHub-to-plant replenishment proposals and their approval.request_id- id · key
requested_on- date
hub_id- id · links to locations
plant_id- id · links to locations
sku- id · links to products
quantity- int
requested_date- date
priority- int
status- enum
approver_id- id · links to people · optional
converted_to- text · optional
Production11 tables
resourcesAnything at a plant that work is scheduled on: the PL02 paint lines, assembly lines, battery fitting, QC and packing.resource_id- id · key
plant_id- id · links to locations
resource_type- enum · paint, assembly, battery-fit, qc, packing
name- text
models_allowed- text · all, ebike, regular or a model list
units_per_hour- decimal
hours_per_shift- decimal
shifts_per_day- int
setup_minutes_default- int
dangerous_goods_capable- flag
status- enum
routingsHow a bike is made: one default routing and alternatives, tried by priority. Every routing paints at PL02 and assembles at the product plant.routing_id- id · key
material_sku- id · links to products
plant_id- id · links to locations
routing_role- enum · default, alternative
priority- int
valid_from- date
valid_to- date · optional
lot_size_min- int
lot_size_max- int
description- text
routing_stepsThe ordered operations of a routing, each on one resource.routing_id- id · key · links to routings
step_no- int · key
operation- enum
resource_id- id · links to resources
setup_minutes- int
run_minutes_per_unit- decimal
consumes_components- bool
predecessor_step- int · optional
production_ordersQuantities of a bike to make, with the routing actually chosen.production_order_id- id · key
sku- id · links to products
plant_id- id · links to locations
routing_id- id · links to routings
quantity- int
planned_start- date
planned_end- date
actual_end- date · optional
status- enum · planned, waiting-components, running, done
demand_reference- text · optional · an order_id when made to order
operationsOne row per routing step of a production order: the schedule every resource shares.operation_id- id · key
production_order_id- id · links to production_orders
routing_id- id · links to routings
step_no- int
resource_id- id · links to resources
planned_start- datetime
planned_end- datetime
actual_start- datetime · optional
actual_end- datetime · optional
quantity- int
status- enum
replanned_from- id · links to operations · optional
paint_batchesThe paint-line view of operations in the columns of the weekly paint schedule.batch_id- id · key
operation_id- id · links to operations
line_id- id · links to resources
day- date
shift- int
position- int
sku- id · links to products
model- text
frame_material- enum · aluminium, carbon
colour- text
finish- enum · gloss, matte
quantity- int
due_for- id · consuming plant
approval- text · optional
week- text
status- enum
paint_rulesThe PL02 paint shop sequencing procedure as structured rules.rule_id- id · key
line_id- id · links to resources · optional
rule_type- enum
from_value- text · optional
to_value- text · optional
penalty_minutes- int
hard- bool
description- text
paint_changeoversColour changeover minutes between every pair of colour codes.line_type- text · key
from_value- text · key
to_value- text · key
changeover_minutes- int
coloursColour codes with their light-to-dark rank.code- id · key
rank- int
name- text
capacity_calendarAvailable and planned hours per resource, day and shift.resource_id- id · key · links to resources
date- date · key · links to calendar
shift- int · key
available_hours- decimal
planned_hours- decimal
reason- text · optional
resource_incidentsOutages and reductions on a resource.event_id- id · key
resource_id- id · links to resources
start- datetime
end- datetime
scope- text
cause- text
Network design5 tables
demand_zonesRegions of customer demand for the network design exercises, aggregated from order lines.zone_id- id · key
name- text
country- text
centroid_lat- decimal
centroid_lon- decimal
annual_demand_pallets- int
seasonality_profile_id- id · links to seasonality_profiles
seasonality_profilesMonthly demand indices per profile.profile_id- id · key
month- int · key
index- decimal
candidate_sitesExisting hubs and possible new sites for the network study.site_id- id · key
location_id- id · links to locations · optional
name- text
country- text
latitude- decimal
longitude- decimal
site_type- enum · existing, candidate
fixed_cost_per_year- money
capacity_pallets- int
opening_lead_months- int
scenariosNamed what-if assumption sets, including the Basel closure proposal.scenario_id- id · key
name- text
description- text
created_on- date
assumption_set- json
scenario_flowsPlanned product flows from a source to a zone under a scenario.scenario_id- id · key · links to scenarios
from_location- id · key · links to locations
to_zone- id · key · links to demand_zones
model- text · key
pallets- int
mode- enum
cost- money
Operations monitoring4 tables
incidentsOperational incidents on the systems the company runs, including its AI assistants.incident_id- id · key
opened_at- datetime
closed_at- datetime · optional
system- enum
severity- enum
category- text
affected_location- id · links to locations · optional
owner_id- id · links to people
resolution_code- text · optional
agent_runsOne row per request handled by a company AI assistant.run_id- id · key
agent_id- text
started_at- datetime
status- enum · succeeded, failed, stopped
request_type- text
human_answer_review- text
agent_callsOne row per tool-call attempt of an assistant run, including retries.call_id- id · key
run_id- id · links to agent_runs
tool_name- text
started_at- datetime
ended_at- datetime · optional
status- enum · succeeded, failed, timed_out
retry_of_call_id- id · links to agent_calls · optional
source_revision- text
error_code- text · optional
initiativesThe AI initiative portfolio and its evidence status.initiative_id- id · key
title- text
business_team- text
owner_id- id · links to people · optional
stage- enum
evidence_status- enum
last_reviewed_on- date
Read it, then try it
The blog posts use Upshift in small examples you can paste into a chat. The dataset and the exercises let you do the same work at the scale of the whole company. Both are free with an account. Accounts are by invitation for now: join the waiting list from the sign-in screen and I’ll send you one.