Busflow Docs

Internal documentation portal

Skip to content

Frontend Architecture

Core Strategy & Tech Stack

Monorepo architecture (pnpm workspaces / Turborepo) sharing logic and UI across distinct user touchpoints.

  • Nuxt 3 (Nitro): B2C/marketing apps requiring SEO, fast TTFB, edge rendering, hybrid routing.
  • Quasar Framework: B2B/operations apps requiring heavy client-side state, complex layouts, PWA/native targets.
  • Slidev: Markdown-based presentation hub for fast, AI-friendly slide generation using Vue components.
  • Styling: Tailwind CSS + ShadCN-vue. We bypass Quasar's default UI for a unified custom design system.

Core Product (apps/)

The SaaS product frontends reflect our Domain-Driven Design (DDD) boundaries. For internal staff, we employ an App Shell / Microfrontend Composition strategy to enforce strict technical isolation while delivering a seamless, unified User Experience.

Unified Internal Portal (App Shell)

  • workspace: The central internal application layer. It serves as a cross-domain App Shell (Saga Orchestrator) that composes UI widgets from the Backoffice, Commerce, Operations, and Communications contexts using layout slots. To the user, it provides a single, cohesive experience; technically, it mounts distinct, decoupled domain microfrontends.

Domain-Specific Public Apps (Commerce & Operations)

  • booking-widget: Embeddable B2C checkout widget (Nuxt). Handles seat selection, payment, and upsells. Can run as a standalone SPA or <script> embed.
  • passenger: Standalone post-booking portal (Nuxt via Magic Link). Manages digital tickets, balance payments, live tracking, and booking modifications.
  • driver: Operations App (PWA/Capacitor). Aggressive offline caching, simplified driver UX.

Brand, Marketing & Tooling (studio/)

Non-product apps for building, selling, and showcasing busflow.

  • landing: Short public page (busflow.de). SSG/edge rendering, optimized for conversions. (Nuxt)
  • marketing: Public marketing site (busflow.de). SEO-optimized, SSG/edge rendering. (Nuxt)
  • presentations: Centralized presentation hub on pitch.getbusflow.com. (Slidev)
  • histoire: Visual component workshop for ui-core and ui-domain. (Histoire)
  • docs-hub: Internal documentation portal for the Busflow monorepo. (VitePress)

App-Internal Structure (Feature-Sliced Design)

Apps organize code by business capability, not by technical type. Each app follows a layered Feature-Sliced Design (FSD) with a strict top-down import rule: pages → widgets → features → entities → shared. Cross-feature communication flows through the store or events, never via direct import.

  • app/: App shell — router, layouts, global providers, plugin registration.
  • pages/: Route-level views. Orchestrate widgets and features, no direct business logic.
  • widgets/: Large, self-contained UI blocks composed of multiple features (e.g. DispatcherCalendar, BookingOverview). Own layout logic, but no unique business rules.
  • features/: One folder per user-facing use case (e.g. ai-document-parsing, trip-scheduler). Each feature encapsulates its own ui/, model/, api/, and a public index.ts.
  • entities/: Domain object representations with UI bindings (e.g. tour/, booking/, vehicle/). Reusable across features within the same app.
  • shared/: App-internal utilities, constants, and helpers. No business logic, no feature awareness.

Shared Packages (packages/)

Consumed as raw source files to preserve HMR and tree-shaking.

UI & Design

  • ui-core: Generic ShadCN/Tailwind components. Strictly presentational, no API awareness. Exports raw .vue/.ts via index.ts. "sideEffects": false, vue as peerDependency.
  • ui-domain: Heavy domain components (seat map, PDF viewer). Isolated to prevent dependency leaks.
  • config-tailwind: Global design tokens. Consumers must configure content paths to scan ../../packages/ui-core/src/**/*.{vue,js,ts}.

Domain & Types

  • types: Single source of truth for TypeScript interfaces and Zod/Valibot schemas (Tour, Booking, Passenger, Ticket). Schemas validate at runtime; the system infers types via z.infer<>. We prefer Valibot over Zod for tree-shakeable, minimal bundle size.
  • core: Pure, isomorphic utility functions (date formatting, duration calculation, price formatting). No Vue, no DOM, no API calls — runs identically in Node.js (backend validation) and the browser (real-time UI warnings). Designed for 100% test coverage with Vitest.

Domain Packages (packages/[pillar]/*)

Isolated domain logic consumed by both frontend apps and the NestJS backend. We group these packages by Bounded Context (e.g., packages/commerce/wallet, packages/backoffice/pricing).

See App-Internal Structure & Service Packages for the complete list and architecture of domain packages.

Connectivity & Tooling

  • api-client: Shared API interfaces, DTOs, fetching logic. Cross-app type safety.
  • config-tooling: Shared ESLint, Prettier, TypeScript configs.

Internal documentation — Busflow