Skip to content

Instantly share code, notes, and snippets.

@eNeRGy164
Created January 25, 2026 16:34
Show Gist options
  • Select an option

  • Save eNeRGy164/90f63e78d3e528f7b8490538a6781b5f to your computer and use it in GitHub Desktop.

Select an option

Save eNeRGy164/90f63e78d3e528f7b8490538a6781b5f to your computer and use it in GitHub Desktop.
An example of an arc42 architecture document for Pitstop, a fictitious garage management system. Includes goals, constraints, context, building blocks (with PlantUML), runtime scenarios (sequence/activity), deployment with config-driven behavior (e.g., ConnectivityMode), ISO/IEC 25010 quality overview + scenarios, simple ADR, risks, and glossary.

Pitstop - Architecture Documentation

Pitstop logo

Pitstop is the garage’s operational brain: it synchronizes planning, creates/updates work orders, and keeps the admin overview and workshop view consistent in near real-time.

1. Introduction & Goals

Most garages use a planning tool for appointments and a separate admin/workshop system for execution. When jobs change (delay, extra work, parts missing), updates are handled manually, causing schedule drift, wrong customer expectations, and inefficient workshop utilization.

Pitstop solves this by providing a single operational source of truth for work orders and status, and synchronizing planning + workshop execution.

1.1 Requirements overview

The most important requirements:

  • Import appointments from one or more Planning Services.
  • Convert appointments into Work Orders (jobs/tasks, estimates, required skills, bay assignment).
  • Provide an Admin Overview (today’s workload, lateness, bay utilization, priorities).
  • Provide a Workshop View (per bay/technician task list with fast status updates and notes).
  • Push status changes back to planning (delays, ready-for-pickup, reschedule proposals).
  • Track parts dependency (e.g., “Waiting for Parts”) and use it to block/advance work.

Explicit non-goals:

  • Pitstop is not the planning product.
  • Pitstop is not inventory management (it references parts status, doesn’t manage stock).
  • Pitstop is not billing/accounting (it can export outcomes, doesn’t own invoicing).

1.2 Quality goals

Top quality goals (measurable):

Priority Quality Scenario (short) Acceptance criteria (example)
1 Consistency Admin + Workshop must show the same job state Status updates visible in all UIs within ≤ 2 seconds
2 Availability Workshop continues during flaky internet Workshop View works in degraded mode; updates sync when online
3 Modifiability Add a new planning integration New integration in ≤ 2 days without changing core domain logic
4 Auditability Resolve disputes and analyze throughput Every change includes who/when/why, immutable history
5 Usability Workshop updates must be fast “Glove-friendly” UX: minimal steps, optimized for speed

1.3 Stakeholders

Stakeholder Expectations
Garage Owner / Manager Throughput, predictable planning, fewer no-shows, visibility
Service Advisor (front desk) Reliable customer promises, quick rescheduling
Workshop Foreman Clear priorities, balanced bays, fewer interruptions
Mechanics Simple task list, fast updates, less admin burden
Customer Accurate ETA, proactive updates on delays
Planning Vendor(s) Stable API usage, predictable traffic, clean sync semantics
IT/Ops Deployable, monitorable, secure, low maintenance

2. Architecture Constraints

Non-negotiables that shape the design space:

Constraint Type Rationale Impact
Must integrate with Planning Service(s) Integration Existing ecosystem reality API contracts, sync strategy, mapping rules
Near real-time UI updates UX/Operational Workshop coordination Push updates (WebSocket) or efficient polling
Degraded-mode operation Operational Garage networks can be unreliable Local cache/queue, retry, conflict handling
Containerized deployment Platform Standard ops model Registry, base images, runtime policy
Automated CI + tests Process Fast feedback & reliability Pipeline ownership + test environments
GDPR / minimal personal data Compliance Customer data Data minimization, retention rules, audit controls
Deviations recorded as ADRs Governance Prevent silent divergence ADR workflow (see Chapter 9)

3. Context & Scope

Pitstop sits between:

  • Planning (appointments and promises),
  • Admin (coordination and customer communication),
  • Workshop execution (reality: progress, delays, extra work), and keeps them synchronized.
@startuml
skinparam shadowing false
skinparam componentStyle rectangle


actor "Service Advisor" as Advisor
actor "Workshop Foreman" as Foreman
actor Mechanic
actor Customer

rectangle "Planning Service" as Planning
rectangle Pitstop as "Pitstop" #OrangeRed
rectangle "Admin Overview" as AdminUI
rectangle "Workshop View" as WorkshopUI
rectangle "Notification Service\n(optional)" as Notify

Customer -> Advisor : appointment\nquestions/updates
Advisor --> Planning : create/adjust\nappointment
Planning --> Pitstop : appointments\n(+changes)
Pitstop --> Planning : status updates\n(reschedule proposals)

Advisor --> AdminUI : coordinate\ncommunicate
Foreman --> AdminUI : priorities\nbay allocation
Mechanic --> WorkshopUI : progress\nnotes

AdminUI --> Pitstop : assign/prioritize\nwork orders
WorkshopUI --> Pitstop : status updates\n(findings, parts)
Pitstop --> Notify : send customer\nnotifications
Notify -> Customer : SMS/email
@enduml

3.1 Business Context

Business context summary

Actor/System Responsibility Exchanges with Pitstop
Customer Brings car, receives updates ETA updates (via advisor/portal)
Service Advisor Manages appointment & expectations Priority changes, notes, customer communication
Workshop Foreman Orchestrates execution Assignments, reprioritization
Mechanic Performs work Status updates, findings, time spent
Planning Service Owns schedule/time slots Appointment import, reschedule suggestions
Notifications (optional) Contact customers SMS/email updates

3.2 Technical Context

Pitstop exposes UIs and integrates with planning via APIs and/or events.

@startuml
skinparam shadowing false
skinparam componentStyle rectangle

rectangle "Planning Service" as Planning
rectangle "Pitstop Backend" as Backend #orangered
rectangle "Admin Overview UI" as AdminUI
rectangle "Workshop View UI" as WorkshopUI
rectangle "Notification Service\n(optional)" as Notify

Planning --> Backend : REST: Appointments\n(+ optional Webhooks)
Backend --> Planning : REST: Status Updates\n(Delay, Ready, Reschedule)

AdminUI --> Backend : HTTPS: Work Orders,\nAssignments, Priorities
Backend --> AdminUI : HTTPS: Dashboard Data

WorkshopUI <--> Backend : WebSocket: Live board\nStatus + Notes

Backend --> Notify : REST: Send SMS/email
@enduml

Interfaces

Peer Interface Direction Protocol/Format Notes
Planning Service Appointments API Inbound REST/JSON Full import + incremental sync
Planning Service (optional) Webhooks Inbound HTTP/JSON Push appointment changes
Pitstop → Planning Status updates Outbound REST/JSON Delay, ready, reschedule proposal
Admin Overview UI Work Orders API Bidirectional HTTPS/JSON RBAC, dashboards
Workshop View UI Live Updates Bidirectional WebSocket/JSON Low latency, optimized payloads
Notification Service (optional) Notifications API Outbound REST/JSON Customer updates

Example payloads

Appointment imported from planning:

{
  "appointmentId": "A-10293",
  "plate": "12-AB-34",
  "start": "2026-01-12T09:00:00+01:00",
  "service": "OilChange",
  "customerRef": "C-4451"
}

Workshop update from a mechanic:

{
  "workOrderId": "WO-7781",
  "status": "WaitingForParts",
  "note": "Brake pads not in stock",
  "updatedBy": "mechanic-17",
  "updatedAt": "2026-01-12T10:41:00+01:00"
}

Scope boundary

@startuml
skinparam shadowing false
skinparam componentStyle rectangle

rectangle "Outside Pitstop" {
  rectangle "Planning Service"
  rectangle "Notification Service\n(optional)"
  rectangle "Inventory/Parts System\n(optional)"
}

rectangle "Pitstop (inside boundary)" {
  rectangle "Work Order Domain"
  rectangle "Sync & Integration Layer"
  rectangle "Admin Overview UI"
  rectangle "Workshop View UI"
}

"Planning Service" --> "Sync & Integration Layer" : appointments
"Sync & Integration Layer" --> "Planning Service" : status updates
"Work Order Domain" --> "Admin Overview UI" : dashboards
"Work Order Domain" --> "Workshop View UI" : task board
"Sync & Integration Layer" --> "Notification Service\n(optional)" : notify
"Work Order Domain" --> "Inventory/Parts System\n(optional)" : parts status reference
@enduml

4. Solution Strategy

Pitstop is designed as an operational “source of truth” for work orders and status, with near real-time synchronization between planning and workshop execution.

Core decisions (with rationale)

  • Modular monolith backend (initially)
    Keep deployment simple and change-friendly while the domain stabilizes.
    Modules are strict (no “grab-bag services”) and communicate via explicit interfaces.

  • Adapter-based integrations (Planning, Notifications, Parts status)
    Each external system sits behind a port/adapter boundary to protect domain logic and keep new integrations fast (Quality goal: ≤ 2 days).

  • Near real-time updates via push
    Workshop and admin need shared truth quickly (≤ 2 seconds).
    Use WebSocket/SSE where possible; fall back to efficient polling.

  • Degraded-mode workshop operation
    Workshop UI supports local queueing and later sync when connectivity returns.

  • Audit-first changes for work order state
    Every status change and important edits record who/when/why (immutable history), enabling dispute resolution and throughput analysis.

5. Building block view

5.1 White-box overall system

Overview (Level 1) — main building blocks and dependencies.

@startuml
skinparam shadowing false
skinparam componentStyle rectangle

rectangle "Planning Service(s)" as Planning
rectangle "Notification Service\n(optional)" as Notify
rectangle "Parts Status Source\n(optional)" as Parts

package "Pitstop (overall system)" #orangered {
  rectangle "Admin Overview UI" as AdminUI
  rectangle "Workshop View UI\n(degraded mode capable)" as WorkshopUI
  rectangle "Pitstop Backend" as Backend
  rectangle "Sync & Integration Layer" as Sync
  rectangle "Audit/Event Log" as Audit
  database "Pitstop DB" as DB
}

Planning --> Sync : appointments\n(+changes)
Sync --> Planning : status updates\n(reschedule proposals)

AdminUI --> Backend : HTTPS/JSON\nwork orders, planning views
WorkshopUI --> Backend : WebSocket/JSON\nlive board + updates

Backend --> DB : read/write
Backend --> Audit : append events
Sync --> Backend : mapped changes\n(commands/events)
Backend --> Sync : integration events

Backend --> Parts : query parts status\n(reference only)
Backend --> Notify : send updates\n(optional)
Notify --> AdminUI : delivery status\n(optional)

@enduml

Black-boxes (Level 1)

Block Responsibility Key Interfaces
Admin Overview UI Dashboard, coordination, customer comms support HTTPS/JSON to Backend
Workshop View UI Bay/task board, fast updates, degraded mode WebSocket/JSON to Backend
Backend Core domain + APIs + orchestration HTTPS/JSON + WS + internal module interfaces
Sync & Integration Mapping + sync strategy per planning vendor REST/JSON, webhooks, retry
Audit/Event Log Immutable history for accountability + analytics Append/read APIs
DB Operational persistence SQL (implementation-specific)

5.2 Level 2 — Pitstop Backend

@startuml
skinparam shadowing false
skinparam componentStyle rectangle

package "Pitstop Backend (white-box)" {
  rectangle "API Layer\n(REST + WS)" as Api
  rectangle "AuthN/AuthZ\n(RBAC)" as Auth

  package "Modules (black-boxes)" {
    rectangle "Work Order Module" as WorkOrders
    rectangle "Workshop Module" as Workshop
    rectangle "Admin Module" as Admin
    rectangle "Customer/Vehicle Module" as Customer
    rectangle "Reporting Read Models" as Reporting
  }

  package "Integration Ports" {
    rectangle "Planning Port" as PlanningPort
    rectangle "Notification Port" as NotifyPort
    rectangle "Parts Status Port" as PartsPort
  }

  rectangle "Audit Writer" as AuditWriter
  database "Pitstop DB" as DB
}

Api --> Auth
Api --> WorkOrders
Api --> Workshop
Api --> Admin
Api --> Customer
Api --> Reporting

WorkOrders --> AuditWriter
Workshop --> AuditWriter
Admin --> AuditWriter
AuditWriter --> DB

WorkOrders --> PlanningPort
Workshop --> PlanningPort
Admin --> NotifyPort
WorkOrders --> PartsPort

@enduml

Notes

  • Modules contain domain rules; ports isolate vendor protocols/mapping.
  • Reporting read models can be optimized independently (avoid OLTP pain).

6. Runtime view

6.1 Scenario: Create/update order on appointment import

Why this scenario matters

  • It hits the core value: planning ↔ execution sync.
  • It exercises consistency, auditability, and integration boundaries.
@startuml
hide footbox
skinparam shadowing false

participant "Planning Service" as Planning
participant "Sync Adapter" as Sync
participant "Backend API" as Api
participant "Work Order Module" as WOD
database "Pitstop DB" as DB
participant "Audit/Event Log" as Audit
participant "Workshop View UI" as UI

== Import appointment ==
Planning -> Sync ++ : appointmentChanged(appointment)
Sync -> Api --++ : upsertAppointment(mapped)

Api -> WOD --++ : UpsertWorkOrderFromAppointment(cmd)
WOD -> DB : load/update work order
WOD -> Audit : appendEvent(WorkOrderUpserted)
WOD --> Api --++ : result(workOrderId, state)

Api -> UI -- : pushUpdate(workOrder summary)\n(WS ≤ 2s)

== Workshop progress ==
UI -> Api ++ : updateStatus(WO-7781, WaitingForParts, note)
Api -> WOD --++ : ChangeStatus(cmd)
WOD -> DB : persist new state
WOD -> Audit : appendEvent(StatusChanged)

WOD -> Sync --++ : integrationEvent(StatusChanged)
Sync -> Planning -- : statusUpdate(delay/ready/reschedule)
@enduml

Failure / exception notes

  • Planning API unavailable → Sync queues outbound updates with retry + backoff.
  • Duplicate appointment updates → idempotency key (appointmentId + version/timestamp).
  • Conflicting edits → “last-write-wins” only for safe fields; status changes may require rules (e.g., foreman override).

6.2 Scenario: Degraded-mode workshop updates (offline → sync later)

Intent

  • Mechanic keeps working even if Wi-Fi is spotty.
  • Updates are queued locally and reconciled when online.
@startuml
skinparam shadowing false

|Workshop View UI|
start
:Mechanic updates status + note;
:Store update in local queue;
if (Online?) then (yes)
  :Send update to Backend;
else (no)
  :Show "Queued" indicator;
endif

|Backend|
if (Update received?) then (yes)
  :Validate permissions + state rules;
  :Persist + append audit event;
  :Broadcast to other clients;
endif

|Workshop View UI|
if (Connection restored?) then (yes)
  :Replay queued updates;
  :Handle conflicts (merge rules);
endif
stop
@enduml

Conflict handling rule of thumb

  • Notes append (safe).
  • Status changes validate allowed transitions; reject invalid transitions with a clear “needs foreman review” message.

7. Deployment view

Documented runtime configuration (deployment-owned)

Pitstop behavior differs per garage/network reliability. These settings are owned by Ops and are part of the deployment definition.

Key setting: ConnectivityMode

  • OnlineFirst (default): normal operation, real-time updates preferred
  • OfflineFirst: prioritize local queueing + aggressive retries (workshop-heavy garages / flaky Wi-Fi)

Where configured

  • Container env var Pitstop__ConnectivityMode or appsettings.{Environment}.json
// appsettings.Production.json
{
  "Pitstop": {
    "ConnectivityMode": "OfflineFirst",
    "Realtime": {
      "Transport": "WebSocket",
      "FallbackToPollingSeconds": 5
    },
    "Sync": {
      "RetryPolicy": "ExponentialBackoff",
      "MaxRetries": 10
    }
  }
}

7.1 Single garage (containerized)

@startuml
skinparam shadowing false

node "On-prem Host" #lightgreen {
  node "Container Runtime" #white {
    artifact "Admin UI\n(container)" as AdminUI
    artifact "Workshop UI\n(container)" as WorkshopUI
    artifact "Pitstop Backend\n(container)" as Backend
  }
  database "Pitstop DB" as DB
}

cloud "External Systems" #lightblue {
  node "Planning Service(s)" as Planning
  node "Notification Service\n(optional)" as Notify
}

AdminUI --> Backend : HTTPS
WorkshopUI --> Backend : WebSocket/HTTPS
Backend --> DB : SQL
Backend --> Planning : REST/webhooks
Backend --> Notify : REST

@enduml

7.2 Multi-site (chain) — high-level variant

  • Central DB + audit store; site-level caches for workshop responsiveness.
  • Reporting can run off read replicas.

Operational notes

  • Monitoring: request latency, WS connection health, sync queue depth, retry rate.
  • Backups: DB daily + audit log retention policy.
  • Security: network segmentation; outbound allowlist to planning/PSP endpoints.

8. Crosscutting concepts

8.1 Identity & access (RBAC)

Implementation

  • Auth: JWT bearer tokens.
  • Authorization: policy-based checks, mapped from roles/claims.

Claims (example)

  • role: Mechanic, Foreman, ServiceAdvisor
  • garageId: used for tenant/site scoping
  • permissions: optional fine-grained list for exceptions (e.g. discount approval)

Enforcement

  • API endpoints require policies like:

    • WorkOrders.Read, WorkOrders.UpdateStatus, Planning.Sync.Write
  • Workshop actions use server-side authorization too (don’t trust the UI).

Example policy mapping

  • Mechanic → can update status for assigned work orders
  • Foreman → can override conflicts + reprioritize bays

8.2 Real-time updates — transport + payload strategy

Implementation

  • Workshop UI uses WebSocket (or SignalR-like hub semantics).
  • Admin UI typically uses HTTPS + incremental refresh (lighter).
  • Both consume the same “work order changed” message format.

Config-driven behavior

  • Controlled by Pitstop:Realtime:Transport and FallbackToPollingSeconds.
  • If WS fails: client polls every N seconds and shows a small “reconnecting” banner.

Payload shape (example)

{
  "type": "WorkOrderChanged",
  "workOrderId": "WO-7781",
  "version": 42,
  "changedFields": ["status", "notePreview", "updatedAt"],
  "status": "WaitingForParts",
  "updatedAt": "2026-01-12T10:41:00+01:00"
}

8.3 Degraded-mode workshop operation — local queue + idempotency

Implementation

  • Workshop UI stores updates in a local outbox queue (IndexedDB / local storage abstraction).
  • Each queued item includes an idempotency key to avoid double-apply.

Queue item (example)

{
  "idempotencyKey": "WO-7781:42:mechanic-17:10:41:12",
  "workOrderId": "WO-7781",
  "command": "ChangeStatus",
  "payload": { "status": "WaitingForParts", "note": "Brake pads not in stock" },
  "queuedAt": "2026-01-12T10:41:00+01:00"
}

Replay rules

  • On reconnect: replay in order, stop on hard conflicts, show resolution UI.
  • Notes are append-only → safe merge.
  • Status changes validated by state machine → reject invalid transitions.

Config hook

  • If Pitstop:ConnectivityMode = OfflineFirst, the UI always queues first and sends async.
  • If OnlineFirst, UI sends immediately and only queues on failure.

8.4 Auditability — append-only event log + read model

Implementation

  • Every significant change writes an audit event (append-only table or event store).
  • Read model derived for dashboards/analytics.

Audit event schema (example)

{
  "eventId": "evt-9b1c",
  "aggregateType": "WorkOrder",
  "aggregateId": "WO-7781",
  "eventType": "StatusChanged",
  "occurredAt": "2026-01-12T10:41:00+01:00",
  "actor": { "userId": "mechanic-17", "role": "Mechanic" },
  "reason": "WaitingForParts",
  "data": {
    "from": "InProgress",
    "to": "WaitingForParts",
    "note": "Brake pads not in stock"
  },
  "correlationId": "corr-2f8d"
}

Why this feels “real”

  • This supports: disputes, compliance export, and throughput analysis without guessing.

8.5 Integrations — retry, backoff, and “don’t spam the vendor”

Implementation

  • Sync adapter uses:
    • retry with exponential backoff (MaxRetries)
    • circuit breaker when vendor returns repeated 5xx/timeout
    • dead-letter queue after retry budget exhausted

User-facing behavior

  • Admin UI shows: “Planning sync delayed (vendor outage). Updates queued.”

Config

{
  "Pitstop": {
    "Sync": {
      "MaxRetries": 10,
      "InitialBackoffSeconds": 2,
      "CircuitBreaker": { "FailureThreshold": 5, "OpenSeconds": 30 }
    }
  }
}

8.6 Observability — logs, metrics, and the one graph ops will actually watch

Implementation

  • Structured logs with correlationId, workOrderId, garageId.
  • Metrics:
    • sync_queue_depth
    • ws_connected_clients
    • status_update_latency_ms (p95)
    • integration_failures_total

Alert example

  • sync_queue_depth > 100 for 10 minutes → vendor down or credentials broken.

9. Architecture decisions (ADRs)

ADR-001: Modular monolith backend (initially)

  • Status: Accepted
  • Date: 2026-01-24

Context

Pitstop needs to ship quickly, integrate with multiple planning vendors, and evolve domain rules fast. The system must remain easy to deploy for small garages and still be maintainable for larger chains.

Decision

Build the backend as a modular monolith:

  • One deployable backend
  • Clear internal module boundaries (Work Orders, Workshop, Scheduling Sync, Audit)
  • Integrations behind ports/adapters

Consequences

  • ✅ Easier deployment and debugging (one runtime)
  • ✅ Faster iteration while domain is still moving
  • ✅ Module boundaries prepare for future extraction if needed
  • ⚠️ Requires discipline to prevent “big ball of mud” (enforce boundaries, tests, and ADRs)

10. Quality

10.1 Quality Requirements Overview

Functional suitability

  • Correct state transitions for work orders (no impossible statuses).
  • Planning sync semantics: appointment changes map predictably to work order updates.

Performance efficiency

  • Fast dashboards and workshop board (see 10.2 targets).
  • Efficient payloads for real-time updates (send deltas, not full objects).

Compatibility

  • Interoperability with multiple Planning Service vendors via adapters.
  • Nice-to-have: support both pull (poll/import) and push (webhooks) sync modes per vendor.

Usability

  • “Glove-friendly” workshop UX: minimal taps and readable UI in harsh environments.
  • Nice-to-have: accessibility baseline (keyboard navigation for Admin UI, readable contrast modes).

Reliability

  • Degraded-mode operation for workshop during flaky internet.
  • Sync backlog does not break core operations; queued updates recover after outage.
  • Nice-to-have: multi-node backend option for chains (active/passive or rolling update strategy).

Security

  • Role-based access control (RBAC) with site scoping (garageId).
  • Secure audit trail; prevent tampering with history.
  • Nice-to-have: step-up auth for finance-sensitive actions (discounts, write-offs).

Maintainability

  • New planning integration without changing core work order rules (adapter boundary).
  • Clear module ownership (Work Orders vs Workshop vs Integration vs Reporting).
  • Nice-to-have: automated contract tests for vendor APIs + recorded fixtures.

Portability

  • Containerized deployment (on-prem friendly).
  • Config-driven behavior per garage (e.g., ConnectivityMode in Chapter 7).
  • Nice-to-have: “single-host installer” packaging for small garages.

Accountability / traceability

  • Every significant change records who/when/why and is immutable.
  • Support export of work order timelines for disputes and compliance.

Data minimization

  • Store only necessary customer data; define retention + deletion policy.
  • Nice-to-have: pseudonymized analytics view for reporting.

10.2 Quality Scenarios

Scenario-based, testable requirements. Use these as acceptance criteria and monitoring targets.

Availability / Reliability

Scenario Stimulus Response Metric/Target
Wi-Fi outage 15 min disconnect Workshop continues; updates queued 99% actions succeed offline
Reconnect Network returns Queue replays + sync completes drained within ≤ 60s
Planning outage Vendor down Outbound updates queued + retried workshop not blocked

Modifiability / Maintainability

Scenario Stimulus Response Metric/Target
Add new planning vendor New API/mapping Add adapter; domain unchanged ≤ 2 days, core untouched
Add new status ReadyForPickup Update state machine + UI mapping localized change + tests
Change KPI definition “lateness” formula changes Update read model only no write-path impact

Consistency

Scenario Stimulus Response Metric/Target
Status update appears everywhere Mechanic sets WaitingForParts Admin + Workshop UIs converge ≤ 2s end-to-end (p95)
Duplicate planning updates Planning sends same appointment twice System processes once (idempotent) 0 duplicate work orders
Conflict edit Foreman reprioritizes while mechanic updates Deterministic resolution + visible warning Conflict surfaced; no silent loss

Auditability / traceability (Top goal from 1.2)

Scenario Stimulus Response Metric/Target
Customer dispute “You promised 16:00” Export full timeline ≤ 60s export
Sensitive change discount/write-off Stored with reason + actor 100% completeness
Throughput analysis cycle time per bay derive from events no manual stitching

Usability (Top goal from 1.2)

Scenario Stimulus Response Metric/Target
Glove-friendly update mechanic changes status minimal interactions ≤ 3 taps, ≤ 5s
Foreman reprioritizes drag/drop visible everywhere reflected in ≤ 2s
Advisor handles reschedule planning change arrives clear delta shown “what changed” view

Security

Scenario Stimulus Response Metric/Target
Cross-garage access attempt user tries other garageId denied 100% blocked
Token leaked token reuse from unknown device revoke/expire quickly short TTL + refresh
Audit tampering attempt try to edit history prevented + logged immutable storage

Observability (ops can sleep)

Scenario Stimulus Response Metric/Target
Sync backlog grows vendor slow/down alert + diagnosis signal sync_queue_depth alert
WS instability disconnect spike fallback works + alert no data loss
Latency regression new release p95 tracked thresholds + release marker

11. Risks and technical debt

Risks are phrased as “what could hurt us” + “what we’ll do about it”.

Risk / debt item Why it matters Mitigation / decision
Integration ambiguity per Planning Vendor Each vendor has different semantics (cancellations, reschedules, no-shows), causing inconsistent work orders Define a vendor mapping spec + contract tests; keep vendor-specific logic in adapters
Offline sync conflicts Workshop can update while foreman/admin also edits → conflict resolution can become messy Keep conflict rules simple (append notes; validate status transitions); provide “needs foreman review” path
Backlog growth in sync queue Vendor outage or slow API can pile up updates, delaying customer comms Monitor sync_queue_depth; circuit breaker; dead-letter queue + ops playbook
WebSocket instability in harsh networks Real-time UX can degrade unpredictably in garages Configurable fallback to polling (Realtime:FallbackToPollingSeconds); reconnect UX; track disconnect rates
Audit log volume / reporting load Auditability creates data; dashboards can overload OLTP queries Use read models; partition audit table; retention policies; optional replica for reporting

Known technical debt (intentional for v1)

  • Single backend instance per garage (no HA) → acceptable for v1; revisit for chains.
  • Minimal conflict resolution UI → acceptable initially; prioritize based on observed conflicts.

12. Glossary

Term Meaning
Appointment A planned time slot in the Planning Service
Work Order (WO) The operational “job” in Pitstop: tasks, status, notes, parts dependency, assignment
Task / Job A unit of work within a work order (e.g., Oil change, Replace pads)
Bay Physical workplace in the workshop (where cars are worked on)
Foreman Workshop lead responsible for prioritization and bay allocation
Degraded mode Workshop continues with limited connectivity (local queue + later sync)
Outbox (local) Client-side queue storing commands while offline to replay later
Idempotency key A unique key to ensure repeated messages are processed only once
Audit event Immutable record of a meaningful change (who/when/why/what)
Read model Projection optimized for dashboards/reporting (separate from write model)
Planning Vendor External planning system providing appointments and receiving status updates
ConnectivityMode Deployment setting that tunes online-first vs offline-first behavior
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment