Skip to content

rocketdeploy-dev/showcase-kiosk-web-application

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

Reference architecture notice

This repository is a reference architecture showcase extracted from a real, production system.
It focuses on architectural decisions, execution boundaries, and operational patterns — not on business-specific logic or a ready-to-deploy application.

The full system context, constraints, and outcomes are described in the corresponding case study:
👉 https://rocketdeploy.dev/en/case-studies/kiosk-web-application

Overview

The Kiosk Application is a single-page, touch-first client intended for unattended public use, where reliability, determinism, and controlled execution are critical. It is built as a standalone front-end that initializes core providers at bootstrap, renders route-based screens, and communicates with external services via HTTP requests.

The application emphasizes linear navigation, short-lived sessions, and explicit failure boundaries. These characteristics are intentional and reflect the constraints of kiosk environments, where recovery paths must be simple and the system must continuously return to a known, safe state.

This document intentionally omits business rules, validation semantics, and domain-specific outcomes.


Technology choices

  • Language: TypeScript — selected to keep component contracts explicit and reduce runtime defects in a long-running, unattended UI environment where recovery paths must be predictable.
  • Framework: Angular (standalone APIs) — chosen for its structured dependency injection, first-class routing, and deterministic component lifecycle, which align well with kiosk constraints and clear architectural boundaries.
  • State & reactivity model — synchronous UI state is handled using lightweight, deterministic signals, while asynchronous interactions (HTTP calls, polling, health checks) use reactive streams to support cancellation, retries, and explicit error propagation.
  • Browser execution model — the application is designed to run without server-side rendering or dynamic code loading, favoring predictable startup behavior and controlled runtime characteristics.

System context

The system consists of a client interface running in a kiosk context and one or more external services responsible for validation, status resolution, and health signaling. The client is the primary execution environment, while external services own all authoritative decisions.

The client also integrates a localization subsystem that dynamically loads language resources at runtime and persists the selected locale across sessions.


Start here (reading map)

  1. Bootstrap & initialization: Start with the application bootstrap that enables production mode, wires providers, and initializes translation loading and inactivity configuration.
  2. Routing & screen map: Review the route configuration that defines the navigation contract and per-screen inactivity behavior.
  3. Shell & composition: Inspect the root shell and shared layout components that wrap routed screens and cross-cutting UI concerns.
  4. User flows: Trace the code-entry screens, the waiting/polling screen, and the terminal outcome screens.
  5. State handling: Review client-side session storage and in-memory services used for transient state handoff.
  6. Integration boundaries: Identify HTTP requests for health checks, code submission, status polling, and localization resource loading.

Architecture at a glance

  • Framework: Component-based SPA using standalone components and a centralized provider configuration.
  • Navigation: Declarative routing with deterministic, linear flows designed to minimize recovery complexity.
  • State: Combination of in-memory services for transient state and browser storage for short-lived session values.
  • Integration: HTTP client used exclusively at defined boundaries for external service calls and localization loading.
  • Kiosk concerns: Global inactivity monitoring, periodic health checks, and explicit readiness/heartbeat signaling to the host container.

Navigation and session handling are intentionally restrictive to ensure the application can always converge back to a known start state without manual intervention.


Architecture boundaries

  • Inside the client: UI composition, navigation control, session and inactivity handling, localization, and HTTP orchestration.
  • Outside the client: All validation, decision-making, and outcome computation are delegated to external services.
  • Host boundary: The client may notify a parent container of readiness and liveness via explicit signals, but does not manage host runtime behavior.

The client is treated as an untrusted execution environment and is not responsible for enforcing business invariants.


Module / component map

  • Application shell: Root component responsible for layout composition, inactivity warning overlay, and health/heartbeat orchestration.
  • Routing layer: Declarative route definitions mapping screens to paths and associating inactivity policies.
  • Interaction screens: Touch-oriented screens for initial selection, code entry, waiting/polling, and terminal outcomes.
  • Shared UI primitives: Header shell and timed-redirect components that enforce consistent layout and reset behavior.
  • Inactivity subsystem: Service and overlay that listen for user interaction events and trigger resets on expiry.
  • Localization subsystem: Translation service and HTTP loader that fetch language resources and persist locale selection.
  • Transient status store: In-memory service that temporarily captures status details for consumption by subsequent screens.

Backend or external integrations

  • Code submission: The client submits user-entered codes and request types to an external service using a kiosk authorization header.
  • Status polling: The client periodically queries an external service to resolve submitted codes into terminal outcomes.
  • Health monitoring: The client checks an external health endpoint on a fixed interval to determine availability.
  • Localization resources: Language assets are loaded via HTTP based on the active locale.

All integrations are strictly outbound and mediated through a single HTTP abstraction.


Execution flows (generic, role-based)

Visitor flow: submit a code

  1. Visitor selects an action from the start screen.
  2. Visitor enters a numeric code using the on-screen keypad.
  3. Client validates completeness, stores the code in session storage, and submits it to an external service.
  4. Client navigates to a waiting screen that polls for resolution.
  5. Client transitions to a success, invalid, or error screen and automatically resets to the start screen after a fixed delay.

Visitor flow: idle reset

  1. Inactivity tracking is enabled on most screens and listens for touch, mouse, and keyboard events.
  2. A warning overlay appears shortly before the inactivity timeout.
  3. If no interaction occurs, the client clears transient state and navigates back to the start screen.

Operator / host flow: readiness and heartbeat

  1. On initialization, the client begins health checks against an external service.
  2. When the service is healthy, the client emits a one-time readiness signal and periodic heartbeat messages to the host container.
  3. If health checks fail, heartbeat signaling is suspended until health is restored.

State & data management

  • Transient UI state: Component-local state controls keypad input, timers, and visual feedback.
  • Session storage: The last submitted code is stored briefly to bridge the entry and waiting screens.
  • In-memory service state: Status details are held temporarily and cleared after consumption.
  • Localization preference: The selected language is stored in browser storage and rehydrated on startup.

No durable or privileged data is stored on the client.


Reliability & failure handling

  • Health-aware behavior: External availability gates readiness and heartbeat signaling.
  • Polling limits: Status polling is bounded; exceeding limits results in a controlled error path.
  • Error routing: Integration failures route the user to an error screen with an automatic reset.
  • Inactivity safety: Idle resets prevent stale or abandoned sessions from persisting.

Failure handling is explicit and converges toward a safe, known entry state.


Security model (high-level)

  • Threat model: The client is treated as an untrusted surface running in a public environment.
  • Client-to-service authentication: Requests include a kiosk authorization header sourced from runtime configuration.
  • Minimal trust: All validation and decision-making are delegated to external services.
  • Local storage limits: Only short-lived, non-sensitive values (code, locale) are persisted locally.

No long-term credentials or secrets are embedded in the client.


Key engineering decisions & trade-offs

  • Standalone component architecture
    Why: Centralizes configuration and reduces module overhead.
    Trade-off: Requires explicit imports and disciplined structure.

  • Deterministic, route-driven navigation
    Why: Simplifies recovery and reduces edge cases in unattended environments.
    Trade-off: Less flexibility for non-linear flows.

  • Polling instead of push-based updates
    Why: Predictable behavior across constrained or embedded runtimes.
    Trade-off: Increased latency and network usage.

  • Timed redirects for terminal states
    Why: Ensures the kiosk quickly returns to a usable state.
    Trade-off: Limits time for user review of outcomes.


How to evaluate this codebase (for reviewers)

  • Start with the bootstrap sequence to understand provider wiring and initialization order.
  • Review route definitions to see how navigation and inactivity policies are enforced.
  • Trace HTTP interactions to confirm clear integration boundaries and error handling.
  • Inspect state handoffs between screens via session storage and in-memory services.
  • Pay particular attention to kiosk-specific logic: idle resets, warnings, and host signaling.

Business semantics and domain-specific rules are intentionally excluded.


Current state & evolution

The current implementation is a focused kiosk SPA with a minimal, deterministic flow:

start → action selection → code entry → waiting → outcome → reset

The codebase is structured around clear boundaries and shared primitives, making it suitable for incremental extensions (additional flows, locales, or integrations) without destabilizing the core execution model.


Closing note

This document presents a neutral, anonymized architectural view of a kiosk-oriented SPA.
It highlights execution flow, boundary enforcement, and operational constraints typical of unattended, public-facing systems.

If you’re dealing with similar challenges — kiosk interfaces, constrained runtimes, or systems that must reliably recover without human intervention — feel free to reach out:

👉 https://rocketdeploy.dev/en/contact

Releases

No releases published

Packages

No packages published