Product-level design. Produced through 3 rounds of adversarial peer review.
VRPS is organized as a simple hierarchy. Everything flows from the top down. Ownership and authorization are always explicit — never inferred.
Customer
└── Property
├── Units (residential units, retail spaces, offices)
│ └── Managers (people who manage the unit)
│ └── Lot Access (which lots this unit can issue passes for)
└── Lots (physical parking areas)
└── Pass Types (what kind of passes exist here)
└── Offers (how passes are made available)
└── Passes (a consumer's actual pass)
Consumer (the person parking) sits outside this hierarchy — they hold passes, own vehicles, and interact with lots. They are not part of the ownership tree.
Enforcement is an observer — it reads the tree (is this plate authorized?) but never modifies it.
The top-level organization. A property management company, a real estate group, a building owner. Everything belongs to a customer. Billing happens at this level.
Examples: Acme Property Management, Harbor Group, Downtown Parking LLC
A distinct physical location. A building, a complex, a campus. Belongs to one customer. A customer can have many properties.
Properties have their own branding (logo, colors) that appears on the lot landing page and consumer-facing materials.
Examples: Harbor View Apartments, The Meridian Office Complex, 400 Main Street
A physical parking area. Belongs to one property. A property can have many lots.
Each lot has a capacity, a mode (public / private / both), and a unique QR code that never changes once printed. Passes are always issued for a specific lot.
Examples: Harbor View Main Lot, P2 Underground, Visitor Surface Lot
Peer Lots: A lot can be made accessible to units from another property — for example, a shared surface lot between two adjacent buildings. The lot still belongs to one property (its owner). Access is granted explicitly, not inherited.
A named group of passes within a property. This is the operational unit that property managers work with day-to-day.
In residential buildings, a unit is literally an apartment unit — Unit 4B, Unit 12A. In commercial properties, it might be a retail tenant, an office suite, or a parking membership. In mixed-use properties, it's whatever the operator defines.
Units have:
- A name (e.g., "Unit 4B", "Retail Suite 101", "Visitor Account")
- A maximum number of concurrent active passes
- One or more managers (the people authorized to issue passes for it)
- Explicit access to one or more lots (declared, not assumed)
A unit in one property can be granted access to a peer lot from another property — that access is explicit and audited.
A person authorized to manage a unit. They can issue passes, view pass activity, and manage vehicles for their unit. A manager is a platform user (has a login). A unit can have multiple managers; a manager can manage multiple units.
Defines what kind of pass exists at a lot. This has two layers:
- Pass Type (called a "family" technically) — the named product. "Monthly Resident Pass", "Visitor Day Pass", "Employee Annual". This is what operators name and manage. It belongs to a lot.
- Terms (called a "template" technically) — the specific rules: rate, duration, seasonal restrictions. When a pass type's rate changes, new terms are created. Existing passes keep the terms they were issued under. Terms are immutable once a pass has been issued against them.
Operators manage pass types. The terms are the implementation detail.
How a consumer gets access to a pass. An offer is a standing authorization attached to a pass type. There are four kinds:
| Offer Type | How it works |
|---|---|
| Open | Any consumer at the lot can claim a pass. No code needed. Used for public lots. |
| Claim Code | Consumer enters a code to claim a pass. The manager distributes the code. Codes can be rotated. |
| Group | A block of passes with a share link and a capacity cap. Used for events, bulk resident move-ins, etc. |
| Direct | A manager issues a pass directly to a specific consumer. No code needed. |
Offers can have:
- A capacity limit (e.g., only 20 passes from this offer)
- A validity window (valid from / valid until)
- An expiry date
- A host consumer (for group offers — the person who shares the link)
When an offer is fully claimed, it is automatically marked exhausted. Operators can revoke an offer at any time.
The actual parking authorization held by a consumer. A pass is issued when a consumer claims an offer. At the moment of issuance, the current terms (rate, duration) are locked onto the pass — they do not change if the pass type's terms are later updated.
A pass belongs to:
- A consumer (the person parking)
- A vehicle (the plate that will be parking)
- A lot (where they're authorized to park)
- A unit (if issued via a unit's offer)
Pass statuses: active → expiring soon → expired. Can also be revoked, suspended, or abandoned.
The person parking. Not an operator — consumers are residents, visitors, employees. They have:
- One or more identity methods (phone, email) — either can be used to look them up
- One or more vehicles
- A history of passes
Consumers are identified by phone or email. Either works — no single method is required.
A specific plate registered to a consumer. A consumer can have multiple vehicles and designate one as their default. When a pass is issued, it is linked to a specific vehicle. Enforcement looks up the plate to check authorization.
A third-party patrol company. Scoped to one or more properties (and optionally specific lots within those properties). Officers look up plates and log scan events and violations. They cannot issue or modify passes.
Every entity has exactly one parent. A lot belongs to one property. A property belongs to one customer. Authorization always flows up the tree — you own something if you own its ancestor. There are no shortcuts or parallel paths.
A lot is owned by one property. But it can be made accessible to units from another property — a shared lot between two adjacent buildings, for example. This is an explicit access grant (audited, reversible), not a change of ownership. The lot's parent property never changes.
Previously, passes could be acquired three different ways (direct issuance, claim codes, group share links), each with its own data model and behavior. These are now unified under a single "offer" concept with four typed variants. One model, one audit trail, one UI pattern.
Operators manage pass types (the named product). The underlying terms (rate, duration) are versioned and immutable once used. If you change the rate, new terms are created. Old passes are unaffected. This gives operators flexibility while protecting consumers from retroactive changes.
A unit doesn't automatically get access to all lots in its property. Access is declared via an explicit assignment. This makes it possible to have a unit that covers a peer lot from another property, and makes authorization auditable — you can always see exactly which lots a unit can issue passes for.
The people who park (consumers) are an entirely different entity from the people who manage properties and units (operators). They have different identity models, different auth flows, and different data. They don't share a users table.
- Full role-based permissions: operators currently have a simple role set. Granular per-action permissions are a future iteration.
- Cross-customer operators: a manager who manages units across multiple customers' properties. Supported in the future via a junction table.
- Availability engine peer lot support: the real-time capacity engine needs an update before peer lots go live. The schema supports it; the engine logic follows.
- Consumer merge tooling: UI for merging two consumer records that turn out to be the same person.
- Full billing engine: the financial data model is in place (transactions, payouts). The application logic for invoicing and reconciliation is a separate workstream.
| Entity | Belongs To | Key Attributes |
|---|---|---|
| Customer | — | Name, billing info, Stripe account |
| Property | Customer | Name, address, timezone, branding |
| Lot | Property | Name, capacity, mode, QR slug |
| Unit | Property | Name, max passes, lot access |
| Manager | Unit | User, status |
| Pass Type | Lot | Name, description |
| Terms | Pass Type | Rate, duration, seasonal rules (immutable once used) |
| Offer | Lot + Pass Type | Type, code, capacity, validity window |
| Pass | Consumer + Vehicle + Lot | Status, start/end, terms snapshot |
| Consumer | — | Identity methods (phone/email), vehicles |
| Vehicle | Consumer | Plate, state, default flag |
| Enforcement Company | — | Name, property/lot scope |