Tenant Frontend
The Tenant Frontend is a unified Vue 3 Single-Page Application (SPA) that provides the user interface for all tenant services. It communicates with each backend microservice via REST APIs and receives real-time updates via WebSockets.
Architecture
Browser
│
▼
Tenant Frontend (Vue 3 + TypeScript)
│
├──▶ Webshop API (:8010)
├──▶ Warehouse API (:8011)
├──▶ CRM API (:8012)
├──▶ Analytics API (:8014)
├──▶ Webhook API (:8013)
├──▶ WS Proxy (:8015) [WebSocket]
└──▶ Identity API (:8000) [Auth]
Tech Stack
| Component | Technology |
|---|---|
| Framework | Vue 3 + Composition API |
| Language | TypeScript |
| Build Tool | Vite |
| Routing | Vue Router |
| State Management | Pinia |
| HTTP Client | Axios (auto-generated from OpenAPI) |
| Real-time | Laravel Echo + Pusher.js |
| UI Framework | Vuetify / Custom components |
Key Features
Module-Based Architecture
The frontend is organized into modules, each corresponding to a backend service:
| Module | Backend | Features |
|---|---|---|
| Shop | Webshop | Product catalog, cart, orders, checkout |
| Warehouse | Warehouse | Stock levels, receiving, transfers |
| Customers | CRM | Customer list, profiles, segments |
| Campaigns | CRM | Email campaigns, templates |
| Analytics | Analytics | Dashboards, reports, charts |
| Integrations | Webhook | Webhook config, delivery logs |
| Settings | All | Tenant config, user preferences |
Authentication Flow
- User navigates to
{tenant}.vecton.hu - Frontend checks for valid token in local storage
- If no token: redirect to Identity login page
- Identity authenticates user and redirects back with token
- Frontend stores token and includes it in all API requests
API Client Generation
TypeScript API clients are auto-generated from OpenAPI specifications:
# Regenerate API clients from backend OpenAPI specs
cd tenant/tenant-frontend
npm run api-sync
This ensures type-safe API calls and catches breaking changes at build time.
Real-Time Updates
The frontend connects to the WS Proxy for live updates:
- Order status changes appear instantly
- Stock levels update in real-time
- Notifications are pushed without polling
- Dashboard metrics refresh automatically
Project Structure
tenant-frontend/
├── src/
│ ├── modules/
│ │ ├── shop/ # Webshop UI
│ │ ├── warehouse/ # Warehouse UI
│ │ ├── customers/ # CRM - customers
│ │ ├── campaigns/ # CRM - email campaigns
│ │ ├── analytics/ # Dashboards and reports
│ │ ├── integrations/ # Webhook configuration
│ │ └── settings/ # Tenant settings
│ ├── composables/ # Shared Vue composables
│ ├── components/ # Shared UI components
│ ├── stores/ # Pinia stores
│ ├── api/ # Auto-generated API clients
│ ├── router/ # Vue Router config
│ └── App.vue
├── public/
├── package.json
└── vite.config.ts
Configuration
| Variable | Description | Default |
|---|---|---|
VITE_API_URL | Webshop API base URL | http://localhost:8010/api |
VITE_IDENTITY_URL | Identity service URL | http://localhost:8000 |
VITE_WS_HOST | WebSocket host | localhost |
VITE_WS_PORT | WebSocket port | 8015 |
Development
cd tenant/tenant-frontend
# Install dependencies
npm install
# Start dev server (hot reload)
npm run dev -- --port 5175
# Build for production
npm run build
# Type check
npm run type-check
# Lint
npm run lint
Deployment
In production, the frontend is built as a static site and served by Nginx:
# Build stage
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
The Nginx configuration handles SPA routing (all paths to index.html) and serves static assets with proper cache headers.