Busflow Docs

Internal documentation portal

Skip to content

App-Internal Structure & Service Packages โ€‹

Concrete conventions for Feature-Sliced Design (FSD) inside apps and the shared service packages defined in the Frontend Architecture.

Feature-Sliced Design (FSD) โ€‹

Folder Layout per App โ€‹

Every Quasar/Nuxt app under apps/ follows this internal structure. Features are grouped by Bounded Context to enforce DDD isolation while keeping the workspace as a single cohesive app shell.

text
apps/workspace/src/
โ”œโ”€โ”€ app/              # App shell: router, layouts, global providers, plugin registration
โ”œโ”€โ”€ pages/            # Route-level views โ€” orchestrate widgets/features, no direct business logic
โ”œโ”€โ”€ widgets/          # Large, self-contained UI blocks composed of multiple features
โ”œโ”€โ”€ features/         # Grouped by Bounded Context
โ”‚   โ”œโ”€โ”€ backoffice/           # Context: Backoffice (Catalog & Planning)
โ”‚   โ”‚   โ”œโ”€โ”€ tours/            # [v0.1] Tour Templates, Departures, BoardingPoints
โ”‚   โ”‚   โ”œโ”€โ”€ pricing/          # [v0.1] CostingSheet โ†’ PriceMatrix generation
โ”‚   โ”‚   โ”œโ”€โ”€ operator-settings/ # [v0.1] Tenant config, Mollie keys, branding
โ”‚   โ”‚   โ”œโ”€โ”€ fleet/            # [v0.2] Vehicle inventory, TรœV/SP tracking
โ”‚   โ”‚   โ”œโ”€โ”€ staff/            # [v0.2] Crew management, qualifications
โ”‚   โ”‚   โ”œโ”€โ”€ dispatch/         # [v0.2] Manual driver/vehicle assignment
โ”‚   โ”‚   โ”œโ”€โ”€ ai-document-parsing/ # [v0.2] Magic Upload โ€” PDF โ†’ structured tour
โ”‚   โ”‚   โ””โ”€โ”€ margin-calculator/   # [v0.2] Dynamic break-even & cost ingestion
โ”‚   โ”œโ”€โ”€ commerce/             # Context: Commerce (Sales & Fulfillment)
โ”‚   โ”‚   โ”œโ”€โ”€ bookings/         # [v0.1] Incoming orders, passenger lists, refunds
โ”‚   โ”‚   โ””โ”€โ”€ yield-manager/    # [v0.2] Dynamic pricing overrides
โ”‚   โ”œโ”€โ”€ operations/           # Context: Operations (Fleet Execution) โ€” [v0.2]+
โ”‚   โ”‚   โ””โ”€โ”€ (deferred)
โ”‚   โ””โ”€โ”€ communications/       # Context: Communications (Messaging) โ€” [v0.2]+
โ”‚       โ””โ”€โ”€ (deferred)
โ”œโ”€โ”€ entities/         # Domain objects with UI representations
โ”‚   โ”œโ”€โ”€ tour/
โ”‚   โ”œโ”€โ”€ booking/
โ”‚   โ””โ”€โ”€ passenger/
โ””โ”€โ”€ shared/           # App-internal utilities (no business logic, no feature awareness)

Per-Slice Anatomy โ€‹

Every features/<context>/<feature>/ folder uses the same internal layout:

text
features/backoffice/tours/
โ”œโ”€โ”€ ui/               # Vue components scoped to this feature
โ”‚   โ”œโ”€โ”€ TourDrawer.vue
โ”‚   โ””โ”€โ”€ TourDetailPopup.vue
โ”œโ”€โ”€ lib/              # Pure helpers scoped to this feature
โ”‚   โ””โ”€โ”€ formatters.ts
โ”œโ”€โ”€ api/              # GraphQL operations scoped to this feature
โ”‚   โ”œโ”€โ”€ queries.ts
โ”‚   โ””โ”€โ”€ mutations.ts
โ”œโ”€โ”€ types.ts          # Local interfaces (feature-scoped, not shared)
โ””โ”€โ”€ index.ts          # Public API โ€” only export what other layers need

Import Rules & Domain Boundaries โ€‹

Strict top-down dependency flow enforces internal boundaries. Violations are caught by ESLint (planned).

text
pages  โ†’  widgets  โ†’  features  โ†’  entities  โ†’  shared
  โ†“          โ†“           โ†“            โ†“           โœ—
  OK         OK          OK           OK       (imports nothing from above)
  • A widget may import from features, entities, and shared โ€” never from another widget.
  • A feature may import from entities and shared, never from another feature.
  • An entity may import from shared only.

State Management & Cross-Domain Composition โ€‹

To achieve our "App Shell / Modular Monolith" without breaking DDD:

  • Zero Domain State Sharing: Features MUST NOT share domain-specific state with each other. For example, a Booking feature cannot read the Pinia state of a Trip feature.
  • Cross-Cutting Application Concerns Only: Global App state (Pinia) is strictly reserved for cross-cutting application concerns (e.g., User Session, JWT/RBAC, multi-tenancy context, layout structure). Domain boundaries must stay completely "clean".
  • UI Composition / Slots: The pages layer (in the App Shell) mounts components using layout slots. This allows a Backoffice page to render a Commerce interface element (like a refund button) seamlessly without the modules knowing about each other.
  • Event Hand-offs: Cross-feature interactions use the Frontend Saga pattern (emitting global intent events) or URL handoffs, instead of direct import coupling.

NOTE

Future โ€” Event Modeling on the Frontend: When the workspace reaches cross-feature widget composition (Dispatch Board, Omnichannel Inbox, Booking Overview), evaluate adopting Event Modeling patterns for the frontend event bus. This introduces typed Commands (user intents), domain Events (confirmed state changes), and Read Models (reactive projections) as the communication contract between features โ€” replacing ad-hoc coupling with a structured, testable flow. Not needed for isolated CRUD features; becomes valuable once multiple widgets must react to the same state change.

All Apps (driver, passenger, booking-widget) โ€‹

All apps now follow the consistent FSD tree structure, including the widgets directory where needed. Below is an illustrative example of the structure using the driver app features as an example:

text
apps/driver/src/
โ”œโ”€โ”€ app/
โ”œโ”€โ”€ pages/
โ”œโ”€โ”€ widgets/
โ”œโ”€โ”€ features/                   # Example features for driver app
โ”‚   โ”œโ”€โ”€ daily-assignments/      # Shift schedule, trip details
โ”‚   โ”œโ”€โ”€ passenger-checkin/      # QR scanner for Wallet passes/PDFs
โ”‚   โ”œโ”€โ”€ missing-passengers/     # Alert dispatcher about no-shows
โ”‚   โ”œโ”€โ”€ bordverkauf/            # Onboard POS (seat-linked food/beverage)
โ”‚   โ”œโ”€โ”€ receipt-scanner/        # AI OCR receipt capture
โ”‚   โ”œโ”€โ”€ vehicle-inspection/     # Digital pre-trip checklist
โ”‚   โ””โ”€โ”€ commercial-routing/     # Heavy-coach navigation
โ”œโ”€โ”€ entities/
โ”‚   โ”œโ”€โ”€ trip/
โ”‚   โ”œโ”€โ”€ passenger/
โ”‚   โ”œโ”€โ”€ vehicle/
โ”‚   โ””โ”€โ”€ expense/
โ””โ”€โ”€ shared/

Note: The passenger and booking-widget apps also follow this identical FSD structure, but their internal features/ and entities/ folders will differ according to their respective domains.


Backend Architecture (NestJS) โ€‹

The backend is built as a Modular Monolith using NestJS. To enforce Domain-Driven Design (DDD) and maintain strict boundaries, the NestJS application is internally structured around the four primary Bounded Contexts (Pillars).

Folder Layout per Pillar โ€‹

text
apps/api/src/
โ”œโ”€โ”€ app.module.ts           # Root module
โ”œโ”€โ”€ shared/                 # Infrastructure, global filters, auth guards, common utilities
โ”œโ”€โ”€ backoffice/             # Bounded Context: Backoffice
โ”‚   โ”œโ”€โ”€ backoffice.module.ts
โ”‚   โ”œโ”€โ”€ features/           # Handlers for Hasura Actions, Event Triggers
โ”‚   โ”‚   โ”œโ”€โ”€ import-tour/    # e.g., NestJS CQRS Command Handler
โ”‚   โ”‚   โ””โ”€โ”€ export-accounting/
โ”‚   โ””โ”€โ”€ index.ts
โ”œโ”€โ”€ commerce/               # Bounded Context: Commerce
โ”‚   โ”œโ”€โ”€ commerce.module.ts
โ”‚   โ””โ”€โ”€ features/
โ”‚       โ””โ”€โ”€ process-checkout/
โ”œโ”€โ”€ operations/             # Bounded Context: Operations
โ”‚   โ”œโ”€โ”€ operations.module.ts
โ”‚   โ””โ”€โ”€ features/
โ”‚       โ””โ”€โ”€ auto-dispatch/
โ””โ”€โ”€ communications/         # Bounded Context: Communications
    โ”œโ”€โ”€ communications.module.ts
    โ””โ”€โ”€ features/
        โ””โ”€โ”€ route-message/

This structure ensures that each backend module directly maps to its corresponding PostgreSQL schema (backoffice, commerce, operations, communications), keeping data access and business logic fully aligned.


Shared Packages: Abgrenzung โ€‹

PackageScopeSide EffectsIsomorphicExample Content
packages/typesValidation schemas + inferred TS typesMinimal (Valibot runtime)โœ…TourSchema, BookingSchema, type Tour = z.infer<โ€ฆ>
packages/corePure utility functionsNoneโœ… Node.js + BrowserformatDate(), calculateDuration(), checkRestTimeViolation()
packages/[pillar]/*Domain logic, grouped by pillarYes (API calls, file generation)VariesWallet pass builder, price calculator
packages/api-clientHTTP/Supabase layerYes (network)Browser onlysupabaseClient, auth token refresh, typed fetch wrappers

packages/types โ€” Schema Example โ€‹

Schemas use Valibot (preferred over Zod for tree-shakeable, minimal bundle size). The system infers TypeScript types from schemas โ€” never defining them separately.

typescript
// packages/types/src/tour.ts
import * as v from 'valibot';

export const TourSchema = v.object({
  id: v.pipe(v.string(), v.uuid()),
  title: v.string(),
  departure: v.date(),
  returnDate: v.date(),
  driverId: v.nullable(v.string()),
  vehicleId: v.nullable(v.string()),
  maxPassengers: v.pipe(v.number(), v.integer(), v.minValue(1)),
});

export type Tour = v.InferOutput<typeof TourSchema>;

packages/core โ€” Isomorphic by Design โ€‹

core functions run identically in Node.js (backend validation, Serverless Functions) and the browser (real-time Dispatcher warnings). No Vue, no DOM, no API calls โ€” only Input โ†’ Calculation โ†’ Output.

typescript
// packages/core/src/compliance.ts
import type { Trip, Driver } from '@busflow/types';

export function checkRestTimeViolation(driver: Driver, newTrip: Trip): RestTimeResult {
  // Pure calculation โ€” no side effects, no API calls
  // Used in workspace (real-time calendar warning) AND backend (final validation)
}

Designed for 100% test coverage with Vitest โ€” pure functions are trivially testable in isolation.


Domain Packages (packages/[pillar]/*) โ€‹

Each domain-specific package is its own module with an independent package.json. To strictly adhere to our bounded contexts, we group these packages by the Pillar they belong to. They encapsulate domain-specific business logic that both frontend apps and the NestJS backend consume.

IMPORTANT

Runtime vs. Capability: A domain package contains the capability (logic, templates, calculations). An app (or backend module) provides the runtime (HTTP endpoint, UI). Example: packages/commerce/wallet generates .pkpass files. The passenger app imports that package and serves the passes via an API endpoint. workspace could import the same package to generate batch exports for group bookings. The logic stays portable.

packages/commerce/wallet โ€‹

Apple/Google Wallet pass generation and lifecycle management.

  • .pkpass / Google Pass JWT template rendering
  • Pass update payloads (gate changes, delays)
  • Consumers: booking-widget (post-checkout "Add to Wallet"), passenger (display & update passes)

packages/communications/notifications โ€‹

Outbound communication abstraction.

  • WhatsApp template builder (via 360dialog / Twilio)
  • Push notification payload composition
  • Channel routing logic (WhatsApp vs. email vs. push)
  • Consumers: workspace (dispatcher sends updates), driver ("Missing Passengers" alert), passenger (live updates)

packages/backoffice/pricing โ€‹

Deterministic price calculation engine (Kalkulations-Engine). This is the mathematical core described in the Domain Model โ€” Costing & Pricing Engine.

The package encapsulates the full pricing pipeline (cost aggregation โ†’ margin application โ†’ FX risk โ†’ DB validation โ†’ tax strategy โ†’ gross price โ†’ price matrix) and exposes it in two modes:

  • Batch / Vorabkalkulation: Invoked asynchronously for an entire season's catalog. Produces CostingSheet records with complete price matrices. On finalization, emits a SeasonPricingFinalized event that pushes all computed gross prices into read-optimized Commerce caches (booking widget, agency portals).
  • Real-time / Charter: Invoked synchronously from the CharterQuote flow. Calculates route-based costs (incl. Leerkilometer) via services/routing, applies B2B margins, and returns a fully costed quote within seconds.

Additional capabilities:

  • Seasonal surcharges + seat category multipliers
  • Upsell/add-on pricing (luggage, insurance)
  • Discount rules (early bird, group, promo codes)
  • FX risk buffer calculation for non-EUR procurement items
  • Tax strategy resolution (standard VAT vs. ยง 25 UStG Margensteuer)
  • Bidirectional yield management: accepts re-calculation requests when occupancy drops below threshold, computes minimum viable price (โ‰ฅ break-even), and publishes PriceOverridePublished events
  • Consumers: booking-widget (checkout totals, cached prices), workspace (tour pricing configuration, margin calculator, yield management UI)

packages/operations/compliance โ€‹

Regulatory validation for fleet operations.

  • EU VO 561/2006 driving-hours checker
  • Rest-period validation & warnings
  • max consecutive driving-day calculation
  • Consumers: workspace (Copilot warnings during scheduling), driver (driving-time display)

packages/backoffice/pdf-parser โ€‹

AI-powered document extraction pipeline.

  • PDF โ†’ structured tour data extraction (via LLM)
  • Confidence scoring per extracted field
  • Side-by-side review data model (original vs. extracted)
  • Consumers: workspace (Magic Upload) โ€” single consumer, isolated for testability and independent iteration

packages/backoffice/accounting โ€‹

Financial reconciliation and export engine.

  • Cash-box reconciliation (POS sales vs. actual cash)
  • Ledger mapping (Eigen- vs. Fremdleistungen, FiBu-Konten)
  • DATEV-compliant CSV export generation
  • Driver expense allocation to tour margins
  • Consumers: workspace (Executive Control / GF View, end-of-month exports)

packages/operations/routing โ€‹

Commercial vehicle routing and navigation data.

  • Heavy-coach route calculation (bridge heights, weight limits, bus-only lanes)
  • Zustiegsstellen pickup-sequence optimization
  • Vehicle-profile-aware re-routing (e.g., 3-axle coach avoids low bridge)
  • Consumers: driver (turn-by-turn navigation), workspace (dispatch route preview)

Package Index โ€‹

PackagePathConsumers
@busflow/typespackages/types/All apps, all packages
@busflow/corepackages/core/All apps, all packages
@busflow/commerce-walletpackages/commerce/wallet/booking-widget, passenger
@busflow/communications-notificationspackages/communications/notifications/workspace, driver, passenger
@busflow/backoffice-pricingpackages/backoffice/pricing/booking-widget, workspace
@busflow/operations-compliancepackages/operations/compliance/workspace, driver
@busflow/backoffice-pdf-parserpackages/backoffice/pdf-parser/workspace
@busflow/backoffice-accountingpackages/backoffice/accounting/workspace
@busflow/operations-routingpackages/operations/routing/driver, workspace

Internal documentation โ€” Busflow