Parking Garage
Tracks the state of a single parking garage: its spots, the cars that occupy them, and the two ways a car enters — a monthly parker's keycard or a temporary visitor's pay-on-exit ticket.
Glossary
Driver— A person who enters and exits using a monthlyAccount'sKeycard. The human behind aCar; not modeled as an entity.Operator— Garage staff or management who openAccounts, issueKeycards, registerCars, designate reservedSpots, and otherwise administer theGarage. A human role, not modeled as an entity.Visitor— A person with noAccountwho enters by taking aTicketand pays at aKioskbefore exit. Not modeled as an entity.
Enums
AccountStatus
The billing standing of an Account.
| Value | Definition |
|---|---|
active | In good standing; its Keycards open the gate. |
suspended | Billing lapsed or administratively held; its Keycards are refused at the gate until reinstated. |
SpotKind
Whether a Spot is open to all entrants or reserved for one Account.
| Value | Definition |
|---|---|
general | Any entrant — monthly or temporary — may occupy this Spot. |
reserved | Assigned to one Account; only that account's Cars may occupy it. |
Entities
Account
The billing entity for monthly parking. An Account owns one or more Keycards (gate access for its drivers) and registers one or more Cars. An Account may additionally pay extra for one or more reserved Spots — any of the account's Cars may use any of its reserved Spots — but an Account need have no reserved Spot at all: its Keycard holders still have gate access and park in general Spots like any visitor. Temporary visitors have no Account — they enter with a Ticket.
Relationships
Keycard— 1:n — owned — One per driver who needs gate access; independent of how many reservedSpots, if any, theAccountholds.Car— 1:n — owned
Attributes
| Name | Type | Description |
|---|---|---|
holderName | string | The customer the account bills to. |
billingEmail | string | |
status | AccountStatus | |
reservedSpotCount | integer | Derived: The number of Spots assigned to this Account. |
Actions
open-account— actorOperatorissue-keycard— actorOperator; preserves keycard-one-account, account-keycard-requiredregister-car— actorOperator; preserves car-one-accountsuspend— actorOperator— Setstatusto suspended; gate access is refused until reinstated.close-account— actorOperator
Invariants
- account-keycard-required — An
Accounthas at least oneKeycard. - account-spots-within-keycards — An
Accountholds no more reservedSpots than it hasKeycards — every reservedSpotneeds aKeycardto use it. AnAccountmay hold zero reservedSpots.
Car
A vehicle registered to a monthly Account, together with its metadata (plate, make, model, and so on). Only monthly parkers' vehicles are tracked as a Car; a temporary visitor's vehicle is captured only as a plate on their Ticket, never as a Car.
Attributes
| Name | Type | Description |
|---|---|---|
plate | string | License plate; how a Car is recognized at the gate. |
make | string | |
model | string | |
color | string |
Invariants
- car-one-account — A
Caris registered to exactly oneAccount.
Garage
A single physical parking structure whose Spots the system tracks. It is the top-level container: every Spot and Kiosk belongs to exactly one Garage. Multi-site operation (several structures under one operator) is intentionally out of scope for now.
Relationships
Spot— 1:n — ownedKiosk— 1:n — owned
Attributes
| Name | Type | Description |
|---|---|---|
name | string | Human-facing name of the structure. |
address | string | |
availableSpots | integer | Derived: The number of Spots in this Garage that have no active Visit. |
Invariants
- garage-capacity — The number of active
Visits in aGaragenever exceeds its number ofSpots.
Keycard
A physical access credential issued to an Account that opens the gate for monthly parkers. A Keycard belongs to exactly one Account and is reused across many Visits. It identifies the account, not a specific Car, and is not bound to any particular Spot — it simply grants gate access for one of the account's drivers.
Attributes
| Name | Type | Description |
|---|---|---|
cardNumber | string | The credential's unique identifier, encoded on the card. |
enabled | boolean | False once deactivated; a disabled Keycard is refused at the gate. |
inUse | boolean | Derived: True while this Keycard has an active Visit — its car is in the Garage. This is the state that enforces anti-passback. |
Actions
deactivate— actorOperator— Setenabledto false, e.g. on a lost card.
Invariants
- keycard-one-account — A
Keycardbelongs to exactly oneAccount. - keycard-one-active-visit — A
Keycardis associated with at most one activeVisitat a time, and may not start a newVisitwhile it already has an active one.
Kiosk
A payment station within a Garage where temporary visitors pay their Ticket before exiting. A Kiosk belongs to one Garage and processes many Ticket payments. Monthly parkers using a Keycard do not interact with a Kiosk.
Attributes
| Name | Type | Description |
|---|---|---|
label | string | Where the Kiosk stands, e.g. "Level 1 elevator lobby". |
Invariants
- kiosk-same-garage — A
Ticketmay be paid only at aKioskin the sameGarageas theTicket'sVisit.
Spot
A single parking space within a Garage. A Spot is either general (any entrant may use it) or reserved — assigned to one monthly Account, whose registered Cars alone may park there. At any moment a Spot is occupied by at most one active Visit.
Relationships
Account— n:1 — referenced — Set only for a reservedSpot: the monthlyAccountit is assigned to. A generalSpothas no assignment.
Attributes
| Name | Type | Description |
|---|---|---|
label | string | Where the Spot is, e.g. "A-114". |
kind | SpotKind | Derived: reserved if an Account is assigned to this Spot, otherwise general. |
occupied | boolean | Derived: True if this Spot currently has an active Visit. |
Actions
designate-reserved— actorOperator; preserves account-spots-within-keycards — Assign thisSpotto anAccount, making it reserved.release-reservation— actorOperator— Unassign theAccount, returning theSpotto general use.
Invariants
- spot-single-occupant — A
Spotholds at most one activeVisitat any moment. - reserved-spot-restricted — A reserved
Spotmay be occupied only by aCarregistered to theAccountit is assigned to.
Ticket
A temporary entry credential issued at the gate to a visitor with no Account. It records the entry time and the captured plate, and is paid at a Kiosk before exit. Each Ticket belongs to exactly one Visit.
Relationships
Kiosk— n:1 — referenced — TheKioskwhere theTicketis paid on exit; unset until paid.
Attributes
| Name | Type | Description |
|---|---|---|
plate | string | The plate captured at the gate; the only record of a visitor's car. |
issuedAt | timestamp | |
amountDue | integer | Fee owed, in the smallest currency unit. Derived: Computed at payment time from the parking duration (issue time to now) and the Garage's rate schedule. |
paidAt | timestamp | When the Ticket was paid; unset until then. |
paid | boolean | Derived: True once paidAt is set. |
Actions
pay— actorVisitor; preserves kiosk-same-garage — Pay the fee at aKiosk, settingpaidAtand unlocking exit.
Invariants
- ticket-paid-before-exit — A
Ticketmust be paid at aKioskbefore itsVisitmay exit theGarage.
Visit
One car's stay in the Garage, from entry to exit, occupying a single Spot. Every Visit is started by exactly one credential — a Keycard (monthly) or a Ticket (temporary), never both. The Visit is the central record tying together the Spot, the entrant, and the entry and exit times.
Relationships
Spot— n:1 — referencedCar— n:1 — referenced — The registeredCar, when the entrant is a monthly parker and the vehicle is identified; absent for temporary visitors.Keycard— n:1 — referenced — Present when entry was byKeycard(monthly).Ticket— 1:1 — owned — Present when entry was byTicket(temporary); created together with theVisit.
Attributes
| Name | Type | Description |
|---|---|---|
entryAt | timestamp | When the car entered and the Visit began. |
exitAt | timestamp | When the car left; unset while the Visit is active. |
active | boolean | Derived: True while exitAt is unset — the car is still in the Garage. |
Actions
enter-with-keycard— actorDriver; preserves visit-one-credential, spot-single-occupant, reserved-spot-restricted, keycard-one-active-visit, garage-capacity — A monthlyDriverswipes aKeycard; aVisitstarts on aSpot.enter-with-ticket— actorVisitor; preserves visit-one-credential, spot-single-occupant, garage-capacity — AVisitortakes aTicketat the gate; aVisitstarts on a generalSpot.exit-monthly— actorDriver; preserves visit-exit-after-entry — ADriverswipes out;exitAtis set and theSpotis freed.exit-temporary— actorVisitor; preserves ticket-paid-before-exit, visit-exit-after-entry — AVisitorexits after paying;exitAtis set and theSpotis freed.
Invariants
- visit-one-credential — Every
Visitis started by exactly one credential — aKeycardor aTicket, never both and never neither. - visit-exit-after-entry — A
Visit's exit time, once set, is at or after its entry time.
Relationships
Scenarios
Monthly parker uses a reserved spot
Actors: Account, Car, Keycard, Spot, Visit
Steps
- A customer holds an
Accountwith a registeredCarand an assigned reservedSpot. - The customer swipes their
Keycardat the gate; the system opens it and starts aVisiton the assignedSpot, with noTicket. - The
Visitrecords theCarand the entry time; the reservedSpotnow holds one activeVisit. - On return, the customer swipes the
Keycardto exit; theVisit's exit time is set and theSpotis freed. NoKioskpayment occurs.
Invariants touched
- visit-one-credential — Every
Visitis started by exactly one credential — aKeycardor aTicket, never both and never neither. - spot-single-occupant — A
Spotholds at most one activeVisitat any moment. - reserved-spot-restricted — A reserved
Spotmay be occupied only by aCarregistered to theAccountit is assigned to. - visit-exit-after-entry — A
Visit's exit time, once set, is at or after its entry time.
Monthly parker without a reserved spot uses a general spot
Actors: Account, Car, Keycard, Spot, Visit
Steps
- A customer holds an
Accountwith aKeycardand a registeredCarbut pays for no reservedSpot. - The customer swipes their
Keycard; the gate opens and aVisitstarts on any free generalSpot, with noTicketand noKioskpayment. - On exit the customer swipes the
Keycardagain; theVisit's exit time is set and the generalSpotis freed.
Invariants touched
- visit-one-credential — Every
Visitis started by exactly one credential — aKeycardor aTicket, never both and never neither. - spot-single-occupant — A
Spotholds at most one activeVisitat any moment. - visit-exit-after-entry — A
Visit's exit time, once set, is at or after its entry time.
A keycard already in use cannot start a second visit
Actors: Keycard, Visit
Steps
- A
Keycardhas an activeVisit— its car is currently in theGarage. - Someone presents the same
Keycardat the entry gate again. - The gate stays shut; the
Keycardcannot start a secondVisitwhile its first is still active — the car must exit first.
Invariants touched
- keycard-one-active-visit — A
Keycardis associated with at most one activeVisitat a time, and may not start a newVisitwhile it already has an active one.
Temporary visitor takes a ticket and pays on exit
Actors: Ticket, Visit, Spot, Kiosk
Steps
- A visitor with no
Accounttakes aTicketat the gate; the system captures the plate and starts aVisiton a generalSpot, with noKeycard. - The visitor parks; the general
Spotholds one activeVisit. - Before leaving, the visitor pays the
Ticketat aKioskin the sameGarage. - With the
Ticketpaid, the exit gate opens; theVisit's exit time is set and theSpotis freed.
Invariants touched
- visit-one-credential — Every
Visitis started by exactly one credential — aKeycardor aTicket, never both and never neither. - ticket-paid-before-exit — A
Ticketmust be paid at aKioskbefore itsVisitmay exit theGarage. - kiosk-same-garage — A
Ticketmay be paid only at aKioskin the sameGarageas theTicket'sVisit. - spot-single-occupant — A
Spotholds at most one activeVisitat any moment. - visit-exit-after-entry — A
Visit's exit time, once set, is at or after its entry time.
Unpaid ticket is refused at exit
Actors: Ticket, Visit, Kiosk
Steps
- A temporary
Visitis active with an unpaidTicket. - The visitor drives to the exit without paying at a
Kiosk. - The system refuses to open the exit gate because the
Ticketis unpaid; theVisitstays active and itsSpotstays occupied.
Invariants touched
- ticket-paid-before-exit — A
Ticketmust be paid at aKioskbefore itsVisitmay exit theGarage.
A car not on the account is denied a reserved spot
Actors: Spot, Account, Car, Visit
Steps
- A reserved
Spotis assigned to anAccount. - A
Carthat is not registered to thatAccountattempts to park in the reservedSpot. - The system denies the
Visit; only aCarregistered to the assignedAccountmay occupy the reservedSpot.
Invariants touched
- reserved-spot-restricted — A reserved
Spotmay be occupied only by aCarregistered to theAccountit is assigned to.
Garage fills up
Actors: Garage, Spot, Visit
Steps
- Every
Spotin theGarageholds an activeVisit. - A new car arrives at the gate.
- The system has no free
Spot, so it does not start a newVisit; the count of activeVisits never exceeds theGarage'sSpotcount.
Invariants touched
- garage-capacity — The number of active
Visits in aGaragenever exceeds its number ofSpots. - spot-single-occupant — A
Spotholds at most one activeVisitat any moment.