Skip to content

calServer v2 — Frontend Architecture

Tech Stack

Component Technology Purpose
Framework Nuxt 4, Vue 3, TypeScript Meta-framework, SPA mode (ssr: false)
UI components PrimeVue 4 Menus, dialogs, forms, tables
Data grid TableMaster (own component on PrimeVue DataTable) Server-side tables with filters, views, export
State Pinia 3 Auth, translations, accessibility, notifications
Styling Tailwind CSS 3 Utility-first CSS
Charts Chart.js 4 Dashboard widgets
Live updates Pusher (optional) Grids reload on changes
HTTP $fetch (ofetch) via useApi Communication with API v2
Tests Vitest, Playwright Unit, end-to-end and screenshot tests
Runtime Node 22 (container node:22-alpine) Nitro server delivers the SPA

Project Structure

frontend-v2/
├── app.vue, error.vue        # Root and error page
├── nuxt.config.ts            # Nuxt configuration
├── theme.ts                  # PrimeVue theme
├── components/               # Components, grouped by domain in subfolders
│   └── table-master/         # TableMaster and its filter, column and export dialogs
├── composables/              # useApi, useDataTable, useLoadState, useLiveUpdates, ...
├── layouts/                  # default (app), portal (customer portal), print
├── middleware/               # Auth, permissions, setup, breadcrumbs
├── pages/                    # Routes, one file or folder per area
├── plugins/                  # PrimeVue defaults, accessibility, tooltips
├── stores/                   # Pinia stores
├── utils/                    # Pure helpers, tested on their own
├── e2e/                      # Playwright tests
└── tests/                    # Vitest tests

Components resolve by file name only (pathPrefix: false); the subfolders are for order.

TableMaster

TableMaster.vue is the central data grid of every list. Its logic lives in the composable useDataTable:

  • Dynamic columns from the API's field configuration
  • Server-side: pagination, sorting and filters run through the API. The frontend sends abstract filter descriptors, never SQL fragments; the API translates them for MySQL, PostgreSQL or SQL Server.
  • Saved views with column selection, widths and filters; advanced filters with groups and conditions
  • Export to XLSX, PDF or CSV straight from the grid

Live Updates

When a Pusher key is set, useLiveUpdates subscribes to the channel calserver.<area> and reloads the grid on .resource.created, .resource.updated and .resource.deleted. Without a key the feature stays off and the UI works without real-time refresh.

Development

cd frontend-v2

npm ci              # install dependencies
npm run dev         # dev server (port 3000)
npm run lint        # ESLint
npm run typecheck   # TypeScript strict
npm run test        # Vitest
npm run build       # production build

Environment Variables

Variable Description Example
NUXT_PUBLIC_API_BASE API v2 base URL https://example.com/api/v2
NUXT_PUBLIC_APP_VERSION Deployed image tag, fallback for the version shown at login v5.64.802
NUXT_PUBLIC_PUSHER_KEY Pusher app key (optional) abc123
NUXT_PUBLIC_PUSHER_CLUSTER Pusher cluster eu