CedarPointCedarPoint
System Design Thinking · Session 03

Architect it
before you
build it.

How to move from a vague brief to a scalable architecture — by finding your requirements and constraints first. Today we do it live.

60 minutes Interactive — you design it CedarPoint Technical Team
00
Why we're here

This one is different.

No slides walking you through a finished answer. I give you a problem that doesn't exist yet — and we design it together, live, on the board.

The real skill

Before a single line of schema or code, you need your requirements and constraints. Skip that step and you build the wrong thing — faster.

You do the work

You pull the answer out through questions, tradeoffs and pushback — the same way a real spec forces you to.

Not about the feature

The subject is CedarAccess. The lesson is the thinking. It transfers to every module you'll ever build.

01
The brief · nothing more

"A gym chain has 4 branches. Each branch has fingerprint access control. Design how access decisions and data sync across branches."

That's the whole thing. No constraints given yet. Before anyone touches a whiteboard — what do you need to know?

02
Part 1 · Ask before you build

Pull the requirements out.

I only answer what you ask. Nobody hands you constraints in real life — you interrogate the problem until it gives them up. Questions worth reaching:

QWhat happens when a branch loses internet?
QCan a member from Branch A walk into Branch B?
QIf the central server is down — does the door fail open, or fail secure?
QHow fast must a door unlock after a scan?
QDoes an expiry at 11:59pm have to lock someone out at exactly 11:59pm — or is "eventually" fine?
03
Part 2 · The ones that decide everything

Constraints don't limit you —
they remove the wrong options.

01

Never fail open

A door opening because the network dropped is never acceptable. This alone kills any design where the door waits on the cloud at scan time.

02

Sync is eventual, not instant

The business needs "correct within a bounded window," not real-time consistency across branches. A far easier problem — once you admit it.

03

The hardware is fixed

ZKTeco readers over TCP/IP, a local bridge per branch. Not up for debate — the design works with it, not around it.

04

Local-first is forced, not chosen

Lebanon's power and connectivity reality makes this decision for you. Environment is a first-class input — same as it was for TrackMe and Pointverse.

04
Part 3 · Your turn on the board

Now — design it.

Given all of that: local bridge per branch, fail-secure, eventual sync, cloud owns membership. Show me the shape. Steer with these:

where

Where is the decision made?

Locally or centrally — and why? If a scan waits on the cloud, what breaks the moment the line drops?

what

What must the bridge know in advance?

If it hasn't reached the cloud in 6 hours, how does it still approve the right people?

conflict

Two branches, one member, both offline

Both mark the same member "checked in." When they reconnect — is that even a conflict?

scope

What truly needs real time?

Separate the "must be right now" from the "can wait." Most of it can wait.

05
The shape you just re-derived

Local authority + async reconciliation.

At the branch

Local Bridge

  • Caches valid members & fingerprints
  • Approves the scan locally — door never waits
  • Fast & fail-secure by design
  • Queues entry events while offline
refresh on interval
+ on reconnect
Source of truth

Cloud

  • Authoritative membership state
  • Active / expired / frozen
  • Receives queued events (append-only)
  • Local cache = read-replica

Same shape as POS systems, ATMs, and airline kiosks: local authority for the low-latency high-stakes call, async reconciliation for everything else. Events are append-only — so there's barely a conflict to resolve.

06
Part 4 · Compare to the real plan

Where did your design diverge?

Here's how CedarAccess is actually planned. Tell me where you matched it — and where you went a different, still-valid way.

FrontendNext.js
MobileExpo
BackendNestJS
DatabaseSupabase / PostgreSQL
BridgeNode.js · offline-first · ZKTeco TCP/IP
QueueBullMQ + Redis · both directions
DeployCloud-default · on-prem option
WhyOn-prem = same codebase — it was local-first from day one
07
Part 5 · What you keep

Five things to carry forward.

Requirements before architecture

Draw boxes before you know the constraints and you'll design the wrong system — faster.

Ask how it should fail, not just how it should work

Fail-secure vs fail-open decided half of this design on its own.

Not all data needs the same consistency

Membership: right eventually. A door decision: right now, locally. Treating everything as "sync instantly" is the common overcorrection.

Environment is a constraint, not an inconvenience

Power and connectivity are first-class inputs — not a workaround you bolt on later.

The pattern repeats

Local authority + async reconciliation shows up everywhere. See it once, recognize it forever.

08
Next module you touch

Before you open Prisma — ask these same questions first. That's the skill from today.

CRM · Finance · whatever's next Find the constraints. Then architect.
01 / 10

All slides · click to jump