LogShip ERP — Technical Documentation
Comprehensive technical reference for the LogShip WMS/ERP web application frontend.
LogShip ERP is a full-featured, enterprise-grade Enterprise Resource Planning and Warehouse Management System (WMS) frontend, built with Nuxt 3 and Vue 3. It manages the full lifecycle of sales orders, procurement, inventory, fulfillment, manufacturing, accounting, and business operations across multiple organisations and tenants.
The backend is powered by iDempiere ERP, with auxiliary services provided by Laravel, Strapi CMS, PostgREST, and Elasticsearch. The frontend proxies all requests through Nuxt server routes, handling token refresh, error classification, and multi-backend orchestration transparently.
LogShip ERP | App ID (mobile): com.logship.mobile | Production URL: https://app.logship.de
Key Statistics
Technology Stack
Core Framework
| Technology | Version | Purpose |
|---|---|---|
| Nuxt.js | 3.17.4 | Vue 3 meta-framework (SSR, file-based routing, auto-imports) |
| Vue.js | 3.5.16 | Reactive UI framework (Composition API) |
| TypeScript | Bundled | Type-safe development |
| Vite | Bundled | Build tooling (ES2022 target, top-level await) |
UI & Styling
| Library | Version | Purpose |
|---|---|---|
| @nuxt/ui | 3.1.3 | Headless UI components for Nuxt |
| @nuxt/ui-pro | 3.1.3 | Premium UI components |
| Bulma | 1.0.4 | CSS framework (no-dark-mode variant) |
| Bulma Extensions | 6.2.7 | Tooltips, badges, responsive tables |
| Alga CSS | 1.0.0-beta-48 | Custom PostCSS utility framework |
| Sass | 1.72.0 | CSS preprocessor |
| tedir-table / select / calendar / dropzone | beta | Custom UI input components |
| @iconify-json/mdi | 1.1.66 | Material Design Icons |
Data Grids & Charts
| Library | Version | Purpose |
|---|---|---|
| AG Grid Community | 31.3.2 | Core data grid |
| AG Grid Enterprise | 33.1.1 | Advanced features (grouping, pivoting, master-detail) |
| ag-grid-vue3 | 33.1.1 | Vue 3 integration for AG Grid |
| @amcharts/amcharts5 | 5.9.12 | Interactive charts & data visualisation |
Document Processing
| Library | Version | Purpose |
|---|---|---|
| jsPDF | 3.0.2 | PDF generation |
| pdfmake | 0.2.20 | PDF creation with layouts |
| pdf-lib | 1.17.1 | PDF manipulation |
| html2canvas | 1.4.1 | HTML to canvas rendering |
| canvg | 4.0.2 | SVG to canvas |
| @tato30/vue-pdf | 1.9.4 | PDF viewer component |
| sharp | 0.33.5 | Server-side image processing |
Barcode, Scanning & OCR
| Library | Version | Purpose |
|---|---|---|
| jsbarcode | 3.11.6 | Barcode generation (labels) |
| @ericblade/quagga2 | 1.10.2 | Camera-based barcode/QR scanning |
| tesseract.js | 7.0.0 | Optical Character Recognition |
Mobile & PWA
| Library | Version | Purpose |
|---|---|---|
| @capacitor/core | 8.0.2 | Native mobile bridge |
| @capacitor/android | 8.0.2 | Android platform support |
| web-push | 3.6.7 | Web Push API (VAPID) |
Backend & Database
| Library | Version | Purpose |
|---|---|---|
| pg | 8.16.3 | PostgreSQL client (iDempiere database) |
| better-sqlite3 | 12.4.1 | SQLite (push subscriptions, local cache) |
| sqlite3 | 5.1.7 | SQLite driver |
| @elastic/elasticsearch | 8.15.0 | Elasticsearch client |
| nodemailer | 7.0.11 | Email sending (SMTP) |
Directory Structure
Configuration
nuxt.config.ts
The central configuration file defines all modules, CSS processing, runtime variables, and build options.
| Setting | Value | Description |
|---|---|---|
| modules | @nuxt/ui, @nuxt/ui-pro, nuxt-lazy-load | Core Nuxt modules |
| imports.dirs | composables, menu/admin, menu/fulfillmentCustomer | Auto-imported composable directories |
| vite.build.target | es2022 | JavaScript target with top-level await |
| ui.icons | ['mdi'] | Material Design Icons via Iconify |
| colorMode.preference | light | Default theme (stored as logship_theme) |
| lazyLoad | images, videos, iframes | Intersection Observer-based lazy loading |
| postcss.plugins | alga-css with tedir-* plugins | Custom PostCSS pipeline |
| fonts.provider | none | Self-hosted fonts (Inter, Inconsolata) |
Runtime Configuration
Environment variables are mapped to runtimeConfig and accessed via useRuntimeConfig():
| Category | Keys | Purpose |
|---|---|---|
| Database | pgHost, pgPort, pgDatabase, pgUser, pgPassword | Direct PostgreSQL access |
| iDempiere | api.url, api.idempieretoken | Main ERP backend API |
| Strapi | api.strapi, api.strapiupload, api.strapitoken | CMS content management |
| PostgREST | api.postgrest | REST API over PostgreSQL |
| Laravel | api.laravel | Custom microservice backend |
| DHL | api.dhlurl, api.dhlkey, api.dhlsecret, api.dhluser, api.dhlpass | DHL Parcel shipping API |
| SendCloud | api.sendcloud, api.sendcloudpublickey, api.sendcloudprivatekey | Multi-carrier shipping |
| Elasticsearch | api.elastic, api.elastickey, api.elasticusername, api.elasticpass | Full-text search engine |
| Public | vapidPublicKey, aggrid, solutionname, doctypeid, etc. | Client-accessible config values |
Data Flow Architecture
All client requests are proxied through Nuxt server routes. The frontend never communicates directly with external APIs. This architecture enables transparent token refresh, error handling, and multi-backend routing.
Request Lifecycle
Every server API endpoint follows a consistent try/catch pattern with automatic token refresh:
export default defineEventHandler(async (event) => {
let data: any = {}
try {
// 1. First attempt with current token
data = await handleFunc(event)
} catch(err) {
try {
// 2. Token expired? Refresh and retry
let authToken = await refreshTokenHelper(event)
data = await handleFunc(event, authToken)
} catch(error) {
// 3. Still failing? Classify and handle error
data = errorHandlingHelper(err, error)
forceLogoutHelper(event, data) // Only logouts on true auth failures
}
}
return data
})
Server Middleware Pipeline
Two server middleware modules run on every request before reaching API routes:
| Middleware | File | Purpose |
|---|---|---|
| auth.ts | server/middleware/auth.ts |
Extracts authentication context from cookies and attaches it to event.context.auth (token, refreshToken, userName, password, clientId, roleId, organizationId, warehouseId, userId, language) |
| fetch.ts | server/middleware/fetch.ts |
Provides event.context.fetch() helper that wraps $fetch with base URL and Bearer token authentication |
Authentication Flow
Login Process
Session Cookies
| Cookie | Content | Purpose |
|---|---|---|
logship_it | JWT access token | Bearer authentication |
logship_rt | Refresh token | Token renewal |
logship_user | User object (JSON) | User identity |
logship_xu | Username (Base64) | Fallback re-authentication |
logship_py | Password (Base64) | Fallback re-authentication |
logship_client_id | AD_Client_ID | Tenant context |
logship_role_id | AD_Role_ID | Role-based access |
logship_organization_id | AD_Org_ID | Organisation isolation |
logship_warehouse_id | M_Warehouse_ID | Warehouse context |
logship_language | Language code | Locale preference |
Token Refresh Strategy
A two-tier refresh mechanism ensures session continuity:
Error Handling & Classification
The system uses intelligent error classification to distinguish between authentication failures (which require logout) and authorization failures (which do not). This logic exists on both frontend (useAuthError.ts) and backend (authErrorHelper.ts).
| Error Type | HTTP Status | Action | User Impact |
|---|---|---|---|
token_expired | 401 | Logout | Redirected to /signin |
token_invalid | 401 | Logout | Redirected to /signin |
proxy_auth | 407 | Logout | Redirected to /signin |
authorization | 403 | No Logout | Permission denied message |
validation | 400 | No Logout | Validation error shown |
server_error | 5xx | No Logout | Error message shown |
Pages & Routing
Nuxt's file-based routing generates 463 routes from 18 main modules. Most resources follow a standard CRUD pattern:
/[module]/[resource]/ → index.vue (List/Grid view) /[module]/[resource]/create → create.vue (Create form) /[module]/[resource]/add → add.vue (Alternative create) /[module]/[resource]/[id] → [id]/view.vue (Read-only detail) /[module]/[resource]/[id]/edit → [id]/edit.vue (Edit form) /[module]/[resource]/[id]/duplicate → [id]/duplicate.vue (Clone) /[module]/[resource]/[id]/print → [id]/print.vue (Print/PDF)
Module Route Summary
| Module | Base Route | Pages | Sub-Resources |
|---|---|---|---|
| Materials | /materials | 93 | products, stock, warehouses, locators, price lists, shippers, promotions, discount schemas, freight |
| Settings | /settings | 60 | document types/groups/sequences/status, taxes, charges, activities, order sources, locations, currencies |
| Sales | /sales | 59 | orders, invoices, shipments, payments, returns, fulfillment orders, customer RMA, channels, campaigns |
| Procurements | /procurements | 40 | orders, receipts, returns, invoices, payments, vendor RMA |
| Partners | /partners | 39 | partners, groups, greetings, dunnings, payment terms, jobs, remunerations |
| Requests | /requests | 37 | requests, types, status, categories, groups, resolutions, standard responses |
| Users | /users | 31 | users, roles, organisations, tenants, leads, external users |
| Accountings | /accountings | 16 | journals, calendars, schemas, elements |
| Manufacturings | /manufacturings | 16 | productions, product BOM, part types, quality tests |
| Fulfillment | /fulfillment | 14 | customers, stocks, invoices, pricing rules, Shopify/PlentyOne stocks |
| Admin | /admin | 12 | countries, currencies, regions, users, print colours |
| Assets | /assets | 10 | assets, asset groups |
| Projects | /projects | 10 | projects, project types |
| Mobile | /mobile | 10 | inventory, movement, return, commission, product, labels, shipments |
| Root | / | 10 | dashboard, signin, register, tracking, locator-labels, generate-shipments/invoices |
| Accounts | /accounts | 2 | profile, security |
| Organisations | /organizations | 2 | list, create |
| Integrations | /integrations | 2 | integration management |
Public Routes (No Authentication)
| Route | Layout | Purpose |
|---|---|---|
/signin | new-auth | User login |
/register | auth | User registration |
/forgot-password | auth | Password recovery |
/select-role | new-auth | Role/org/warehouse selection |
/tracking | tracking | Public shipment tracking (query: ?no=&zip=) |
Layouts
app.vue
Main application layout with NavBar, SideBar, TabBar, and FooterSection. Used by most authenticated pages.
admin.vue
Admin-specific layout with NavBarAdmin, SideBarAdmin. Dedicated navigation for system administration.
new-dash.vue
Modern dashboard layout with NewSideBar, TopMegaBar, MainNavigationMenu, and NewTabBar. Horizontal flex design.
auth.vue / new-auth.vue
Centred authentication layouts for login, registration, and password recovery flows.
mobile.vue
Mobile-optimised layout with orientation detection, portrait lock for phones, and 48px minimum touch targets.
org.vue
Organisation management layout with NavBarOrg and SideBarOrg for organisation-specific navigation.
tracking.vue
Minimal public-facing layout for the shipment tracking page. No authentication required.
Middleware
| Name | File | Behaviour |
|---|---|---|
| auth | middleware/auth.ts |
Checks /api/idempiere-auth/authenticated. Guest paths bypass: /signin, /select-role, /login, /register, /verify-email, /forgot-password, /reset-password. Mobile pages allow fallback on network errors if cookie exists. Redirects to /signin on failure. |
| guest | middleware/guest.ts |
Redirects authenticated users away from guest-only pages. Checks for valid cookie and redirects to /. |
| org | middleware/org.ts |
Ensures user has selected an organisation. Currently disabled. Would redirect to /organizations. |
Components
Component Inventory by Domain
| Directory | Count | Purpose |
|---|---|---|
| materials/ | 111 | Products, inventories, warehouses, price lists, shippers |
| AgGrid/ | 68 | Custom cell renderers, filters, editors for AG Grid |
| sales/ | 54 | Campaigns, channels, invoices, orders |
| partners/ | 50 | Partner management, contact forms |
| procurements/ | 37 | Purchase orders, procurement management |
| settings/ | 30 | Configuration and settings forms |
| admin/ | 29 | User, role, organisation, tenant management |
| requests/ | 20 | Request/ticket management |
| RMAs/ | 16 | Return Merchandise Authorisation |
| fulfillment/ | 10 | Fulfillment operations |
| manufacturings/ | 8 | Manufacturing orders |
| accountings/ | 8 | Accounting/journal components |
| integrations/ | 7 | Third-party integration UI |
| Charts/ | 5 | AmCharts data visualisation |
| assets/ | 5 | Asset management |
| (root level) | 48 | Reusable application-wide components |
Key Root-Level Components
Data Display
| Component | Description |
|---|---|
AgGrid.vue | Main AG Grid wrapper with enterprise features, column definitions, filtering |
AgGridServer.vue | Server-side paginated AG Grid with remote data source |
AgGridCustom.vue | Custom AG Grid variant for specialised use cases |
PaginationBox.vue | Reusable pagination controls |
Navigation
| Component | Description |
|---|---|
NavBar.vue / NewNavBar.vue | Top navigation bars |
SideBar.vue / NewSideBar.vue / BaseSideBar.vue | Sidebar navigation |
TabBar.vue / NewTabBar.vue | Tab-based navigation (with localStorage persistence) |
BreadCrumb.vue / NewBreadCrumb.vue | Breadcrumb trails |
MainNavigationMenu.vue | Main mega-menu navigation system |
Modals & Dialogs
| Component | Description |
|---|---|
AddressModal.vue | Address entry/selection modal |
AttachmentModal.vue | File attachment management |
SearchModal.vue | Global search interface |
ConfirmBox.vue | Confirmation dialog |
PrintPreview.vue / BatchPrintPreview.vue | Print preview before output |
Inputs & Utilities
| Component | Description |
|---|---|
ComboBox.vue | Searchable dropdown/select with filtering |
BarcodeScanner.vue | Camera-based barcode scanning interface |
ImageMagnifierGlass.vue | Image zoom/magnification |
ContextMenu.vue | Right-click context menu |
AlertBox.vue / AlertAction.vue | Alert and error display |
ThemeToggle.vue | Dark/light mode toggle |
Component Patterns
All components use the Vue 3 Composition API with <script setup lang="ts">:
<script setup lang="ts">
interface Props {
modelValue?: any
options?: any[]
placeholder?: string
}
interface Emits {
(e: 'update:modelValue', value: any): void
(e: 'change', value: any): void
}
const props = withDefaults(defineProps<Props>(), { ... })
const emit = defineEmits<Emits>()
</script>
Naming Convention for Domain Components
| Pattern | Example | Purpose |
|---|---|---|
[Entity]Form.vue | CampaignForm.vue | Create/edit form |
[Entity]DetailRecord.vue | InvoiceDetailRecord.vue | Read-only detail view |
[Entity]Action.vue | UserAction.vue | Action buttons/toolbar |
[Entity]QuickView.vue | CampaignQuickView.vue | Quick preview panel |
[Entity]Modal.vue | ImportOrdersModal.vue | Entity-specific modal |
Ag[Column].vue | AgCustomDocStatus.vue | AG Grid cell renderer |
Composables
UI State Composables
Defined in composables/states.ts, these provide global reactive state without a store library:
| Composable | Type | Purpose |
|---|---|---|
useSideBar() | boolean | Sidebar visibility toggle |
useTabs() | any[] | Tab navigation state (default: Home tab) |
useActiveMenu() | string | Active menu item tracking |
usePrintPreview() | boolean | Print preview dialog state |
useAttachmentPreview() | boolean | Attachment viewer state |
useQuickView() | string | Quick view modal state |
useWindowParam() | any | Window/modal parameter passing |
useEmailInvoice() | boolean | Email invoice dialog state |
useBatchPrintPreview() | boolean | Batch print dialog state |
useDataTableFilters() | any | Table filter persistence |
useBoM() | any | Bill of Materials state |
useGenerateShipments() | any | Shipment generation state |
useGenerateInvoices() | any | Invoice generation state |
Feature Composables
useAuthError
Classifies authentication errors. Determines if logout is needed. Mirrors backend authErrorHelper logic.
useOrderStream
Server-Sent Events (SSE) stream for real-time order updates. Auto-reconnect with 5s delay. Filters by org, document number, external order ID.
useOrderPolling
Fallback polling mechanism (30s default) for order updates when SSE is unavailable.
usePushNotifications
Web Push via VAPID. Request permissions, subscribe/unsubscribe, show notifications, notify new orders.
useBarcodeScanner
Quagga2-based camera barcode scanning. Supports Code 128, EAN, UPC, Code 39, Codabar, I2OF5. 1.15s debounce.
useNativeScanner
Capacitor native barcode scanning. Listens for DataWedge broadcasts (Zebra/Honeywell enterprise scanners).
useTheme
Light/dark mode management. Wraps useColorMode(). Stored as logship_theme in localStorage.
useTranslation
Multi-language support. Converts iDempiere format (en_US) to standard (en-US). Cookie + localStorage persistence.
useFeedback
Audio + visual feedback. Web Audio API: 800Hz success / 300Hz error sounds. Green/red flash overlays.
useAppUpdate
Capacitor app update detection. Semver comparison. APK download and installation for Android.
usePWAInstall
PWA installation prompting. Detects standalone mode. Handles beforeinstallprompt event.
useOpenShipments
Fetches open fulfillment shipments. Multi-step: customers → organisations → shipments. Calculates totals.
Menu Composables
Each ERP module has a dedicated menu composable that defines its sidebar navigation structure. Located in composables/ and composables/menu/:
| Composable | Module | Menu Items |
|---|---|---|
useSales() | Sales | Orders, Fulfillment Orders, Invoices, Payments, Shipments, RMA, Returns, Channels, Campaigns |
useMaterials() | Materials | Products, Stock, Inventory, Warehouses, Price Lists, Shippers, Promotions |
useProcurements() | Procurement | Purchase Orders, Bills, Payments, Receipts, Vendor RMA, Returns |
usePartners() | Partners | Partners, Groups, Greetings, Dunnings, Payment Terms, Jobs |
useSettings() | Settings | Documents, Taxes, Charges, Activities, Order Sources, Currencies |
useUsers() | Users | Users, Leads, External Users, Roles, Tenants, Organisations |
useRequests() | Requests | Requests, Types, Status, Categories, Groups, Resolutions |
useAnalysis() | Analysis | Accountings, Financial Reports, Costs, Performance |
Plugins
| Plugin | File | Side | Purpose |
|---|---|---|---|
| Service Worker | plugins/01.service-worker.client.ts |
Client | Registers service worker, monitors updates, reloads on new version, checks push subscriptions across navigation |
| Push Notifications | plugins/02.push-notifications.client.ts |
Client | Restores push subscriptions for users with existing permissions. Async initialisation to avoid blocking app load. |
| AmCharts | plugins/amcharts.client.js |
Client | Provides global access to AmCharts 5: $am5, $am5xy, $am5percent, $am5themes_Animated |
State Management
The application uses Nuxt 3's built-in useState() for all reactive state. There is no Pinia or Vuex store. This approach provides SSR-safe reactive state with automatic hydration.
// composables/states.ts
export const useSideBar = () => useState<boolean>('sideBar', () => false)
export const useTabs = () => useState<any[]>('tabs', () => [
{ link: '/', text: 'Home', active: true }
])
export const useActiveMenu = () => useState<string>('activeMenu', () => '')
State Categories
| Category | Storage | Persistence |
|---|---|---|
| UI State (sidebar, tabs, menus) | useState() | Session (no persistence) |
| Authentication | HTTP Cookies | Persistent across requests |
| Theme | localStorage (logship_theme) | Persistent |
| Language | localStorage + cookie (logship_lang) | Persistent |
| Scanner preference | localStorage | Persistent |
| Tab navigation | localStorage | Persistent |
Server API Layer
The server/api/ directory contains 1167+ API route files that proxy requests to various backends. Routes follow Nuxt's file-based convention with HTTP method suffixes.
API Route Convention
server/api/[resource]/ ├── index.get.ts # GET /api/[resource] (List) ├── index.post.ts # POST /api/[resource] (Create) ├── store.post.ts # POST /api/[resource]/store (Alternative create) ├── update.put.ts # PUT /api/[resource] (Update) ├── [id]/index.get.ts # GET /api/[resource]/[id] (Get single) ├── [id]/index.put.ts # PUT /api/[resource]/[id] (Update single) ├── [id]/index.delete.ts # DELETE /api/[resource]/[id] (Delete) └── [custom-action].post.ts # POST /api/[resource]/... (Custom action)
Major API Modules
| Module | Base Path | Backend | Key Endpoints |
|---|---|---|---|
| Auth | /api/auth/ | iDempiere | login, logout, authenticated, forgot-password, reset-password |
| iDempiere Auth | /api/idempiere-auth/ | iDempiere | authenticated, clients, roles, organisations, warehouses |
| Orders | /api/orders/ | iDempiere | CRUD, shipped, openso, sales/notfulfilled, stream (SSE) |
| Inouts | /api/inouts/ | iDempiere | Shipments, line items, packages, process/complete |
| Invoices | /api/invoices/ | iDempiere | CRUD, credit notes, payments |
| Materials | /api/materials/ | iDempiere | Products, stock, warehouses, locators, price lists |
| Partners | /api/partners/ | iDempiere | CRUD, groups, greetings, payment terms |
| Fulfillment | /api/fulfillment/ | iDempiere + Laravel | Customers, stocks, invoices, pricing rules |
| Mobile | /api/mobile/ | iDempiere | Inventory, movement, return, commission, app-version |
| Dashboard | /api/dashboard/ | Multiple | Overview data, KPIs, charts |
| Search | /api/search/ | Elasticsearch | Full-text search across entities |
| Push | /api/push/ | SQLite + web-push | Subscribe, unsubscribe, send notifications |
| Shopify | /api/shopify/ | Shopify API | E-commerce integration |
| PlentyOne | /api/plentyone/ | PlentyOne API | E-commerce platform sync |
| Tracking | /api/commission/ | Multiple | Shipment tracking lookups |
Server Utilities
| Utility | File | Purpose |
|---|---|---|
| fetchHelper | server/utils/fetchHelper.ts | Central HTTP client for iDempiere. Handles Bearer tokens, request/response logging with timing, error context. |
| refreshTokenHelper | server/utils/refreshTokenHelper.ts | Two-tier token refresh: refresh token first, then full re-auth. Updates cookies on success. |
| getTokenHelper | server/utils/getTokenHelper.ts | Extracts JWT from logship_it cookie. |
| authErrorHelper | server/utils/authErrorHelper.ts | Classifies errors: token_expired, token_invalid, authorization, other. Determines logout necessity. |
| forceLogoutHelper | server/utils/forceLogoutHelper.ts | Clears cookies and calls auth/logout. Only triggers on true auth failures. |
| errorHandlingHelper | server/utils/errorHandlingHelper.ts | Standardises error responses: extracts status, message, detail from various error shapes. |
| laravelHelper | server/utils/laravelHelper.ts | HTTP client for Laravel microservice backend. |
| strapiHelper | server/utils/strapiHelper.ts | HTTP client for Strapi CMS with Bearer token auth. |
| postgrestHelper | server/utils/postgrestHelper.ts | PostgREST client for direct PostgreSQL REST queries. |
| elasticsearchHelper | server/utils/elasticsearchHelper.ts | Elasticsearch client for full-text search. |
| dhlHelper | server/utils/dhlHelper.ts | DHL Parcel API integration. |
| dhlTrackingHelper | server/utils/dhlTrackingHelper.ts | DHL shipment tracking API. |
| sendcloudHelper | server/utils/sendcloudHelper.ts | SendCloud multi-carrier shipping API. |
| pushDb | server/utils/pushDb.ts | SQLite database for push subscriptions. WAL mode. 90-day auto-cleanup. |
| pushNotifier | server/utils/pushNotifier.ts | Web Push notification sender via VAPID. Auto-removes expired subscriptions. |
| orgRoleAccessCache | server/utils/orgRoleAccessCache.ts | Caches organisation-role access permissions. |
Databases
PostgreSQL (iDempiere)
Main ERP database. Accessed via iDempiere REST API and directly via pg driver for custom queries. Stores all business data: orders, products, partners, invoices, etc.
SQLite
Local database at data/push-subscriptions.db. WAL journal mode for concurrent access. Stores push notification subscriptions with user/role associations. Auto-cleanup at 90 days.
Elasticsearch
Full-text search engine. Indexes products, orders, partners for fast querying. Accessed via official @elastic/elasticsearch client.
External Integrations
iDempiere
Core ERP backend. RESTful API at /api/v1. JWT authentication. Manages all business entities: AD_Client, AD_Org, C_Order, M_Inout, C_Invoice, M_Product, C_BPartner, etc.
Laravel
Supplementary microservice backend at dev-data.logship.de. Handles custom business logic, data processing, and integration tasks.
Strapi CMS
Content management system for structured content. Bearer token authentication. Used for product information, documentation, media management.
PostgREST
Automatic REST API over PostgreSQL. Direct database access at /custom-api. Used for custom queries and reporting.
DHL Parcel
Deutsche Post DHL API at api-eu.dhl.com/parcel/de. Label creation, tracking, shipment management. Full credential-based auth.
SendCloud
Multi-carrier shipping platform at panel.sendcloud.sc/api/v2. Public/private key authentication. Parcel creation and tracking.
Shopify
E-commerce platform integration. Product sync, order import, stock level synchronisation.
PlentyOne
E-commerce platform (PlentyMarkets) integration. Stock synchronisation and order management.
Lexware
Accounting software integration. Financial data synchronisation (active development as per recent commits).
ERP Modules
Sales Management
Full sales lifecycle management from order creation to fulfillment.
| Feature | Route | Description |
|---|---|---|
| Sales Orders | /sales/orders | Create, view, edit, duplicate, print sales orders |
| Fulfillment Orders | /sales/fulfillment-orders | Order picking and packing operations |
| Invoices & Credit Notes | /sales/invoices | Invoice generation, credit note management |
| Customer Payments | /sales/payments | Payment tracking and receipt management |
| Shipments | /sales/shipments | Shipment creation, tracking, label generation |
| Customer RMA | /sales/customer-rma | Return Merchandise Authorisation processing |
| Customer Returns | /sales/returns | Return processing and restocking |
| Marketing Channels | /sales/channels | Sales channel management |
| Marketing Campaigns | /sales/campaigns | Campaign tracking and analytics |
Materials & Inventory
Comprehensive inventory management with 93 pages covering products, stock, warehouses, and pricing.
| Feature | Route | Description |
|---|---|---|
| Products | /materials/products | Product catalogue with categories and attributes |
| Warehouses | /materials/warehouses | Warehouse definitions and management |
| Locators | /materials/locators | Warehouse locator/bin management |
| Stock Takes | /materials/stock-takes | Physical inventory counting |
| Stock Transfers | /materials/stock-transfers | Inter-warehouse stock movement |
| Price Lists | /materials/price-lists | Price list management with versioning |
| Shippers | /materials/shippers | Shipper configuration and management |
| Promotions | /materials/promotions | Product promotions and discount schemas |
| Planning | /materials/planning | Material requirements planning |
Procurement
Purchase order lifecycle from requisition to vendor payment.
| Feature | Route | Description |
|---|---|---|
| Purchase Orders | /procurements/orders | Create and manage purchase orders |
| Material Receipts | /procurements/receipts | Receive goods from vendors |
| Vendor Invoices | /procurements/invoices | Bills and debit notes |
| Vendor Payments | /procurements/payments | Payment to vendors |
| Vendor RMA | /procurements/vendor-rma | Return authorisation to vendors |
| Vendor Returns | /procurements/returns | Return goods to vendors |
Other Modules
Accounting
Chart of Accounts, journal entries, accounting periods/calendars, schemas, GL elements (asset, liability, equity, revenue, expense).
Manufacturing
Manufacturing orders, Bill of Materials (BOM), part types, quality tests, production tracking.
Partners
Customer/vendor master data, partner groups, greetings, dunning levels, payment terms, job categories, remunerations.
Projects
Project management with project types, budget tracking, and timeline management.
Requests
Request/ticket system with types, statuses, categories, groups, resolutions, and standard responses. Includes chat feature.
Assets
Fixed asset management, asset groups, depreciation tracking, and asset history.
Real-time Features
Server-Sent Events (SSE)
The useOrderStream composable establishes an SSE connection to /api/orders/sales/stream for live order updates:
// Message types:
// - "connected" → Stream established
// - "newOrders" → New orders available (triggers notification)
// - "heartbeat" → Keep-alive signal
// - "error" → Stream error (triggers reconnect)
const { startStream, stopStream, updateFilters } = useOrderStream({
orgId: organizationId,
documentNo: filterDocNo,
openOnly: true,
onNewOrders: (orders) => notifyNewOrders(orders.length)
})
Polling Fallback
When SSE is unavailable, useOrderPolling provides a configurable polling interval (default 30 seconds) with duplicate detection.
Push Notifications
Web Push with VAPID authentication. Service worker receives push events and displays native notifications with action buttons (e.g., "View Orders"). Push subscriptions are stored in SQLite and automatically cleaned up after 90 days.
Mobile & PWA
Capacitor Integration
| Config | Value |
|---|---|
| App ID | com.logship.mobile |
| App Name | LogShip |
| Platform | Android (Capacitor 8.0.2) |
| Server URL | https://app.logship.de |
| Mixed Content | Allowed (development) |
Mobile Features
- Orientation Lock: Portrait lock for phones (screen width < 600px), free rotation for tablets
- Touch Targets: Minimum 48px touch areas
- Landscape Warning: Overlay shown when phone is rotated
- Native Scanner: DataWedge integration for Zebra/Honeywell enterprise scanners
- App Updates: OTA update detection with APK download and install
- Dark Mode: Optimised for scanner usage
PWA Support
- Service Worker: Registered globally for offline support and push notifications
- Manifest:
public/manifest.jsonwith app icons and theme colour - Install Prompt:
usePWAInstallcomposable detects standalone mode and handlesbeforeinstallprompt
Mobile Pages
| Route | Purpose |
|---|---|
| /mobile | Mobile dashboard |
| /mobile/inventory | Inventory management |
| /mobile/movement | Stock movement |
| /mobile/return | Return processing |
| /mobile/commission | Commission tracking |
| /mobile/product | Product lookup |
| /mobile/locator-articles | Locator article management |
| /mobile/print-labels | Label printing |
| /mobile/generate-shipments | Shipment generation |
Barcode & QR Code Scanning
Browser-Based (Quagga2)
| Feature | Detail |
|---|---|
| Formats | Code 128, EAN, EAN-8, UPC, UPC-E, Code 39, Codabar, I2OF5 |
| Camera | Back camera preferred for mobile devices |
| Debounce | 1.15 seconds between scans (prevents duplicates) |
| Workers | Auto-detects hardware concurrency for parallel decoding |
| Retry | 20 retries with 100ms delay for initialization |
| Persistence | Scanner preference stored in localStorage |
Native Scanner (Capacitor)
Listens for DataWedge broadcasts from enterprise-grade scanners (Zebra, Honeywell). Falls back to custom nativeScan events. Detects if running on native platform via Capacitor bridge.
OCR (Tesseract.js)
Optical Character Recognition for text extraction from images. Used for document processing and label reading.
Document Processing
PDF Generation
Three PDF libraries: jsPDF for simple PDFs, pdfmake for complex layouts with tables, and pdf-lib for manipulation of existing PDFs.
PDF Viewing
@tato30/vue-pdf provides in-app PDF viewing with page navigation and zoom controls.
HTML to Canvas
html2canvas captures HTML elements as images. canvg renders SVG content. Used for report export and print previews.
Barcode Labels
JsBarcode generates barcode images for product labels, shipping labels, and locator labels.
Image Processing
Sharp handles server-side image optimization. ndarray-pixels for pixel-level image manipulation.
Batch Operations
Batch print previews, bulk invoice generation, and bulk shipment creation with progress tracking.
Shipping Integration
DHL Parcel
| Feature | Detail |
|---|---|
| API Base | api-eu.dhl.com/parcel/de |
| Authentication | API key + secret + DHL credentials |
| Capabilities | Label creation, shipment tracking, parcel management |
| Helpers | dhlHelper, dhlBaseHelper, dhlCustomHelper, dhlTrackingHelper |
SendCloud
| Feature | Detail |
|---|---|
| API Base | panel.sendcloud.sc/api/v2 |
| Authentication | Public key + private key |
| Capabilities | Multi-carrier shipping, label creation, tracking |
Extensible Architecture
Shipping processors are configurable through /materials/shipping-processors and /materials/shipping-processor-configurations, allowing new carriers to be added without code changes.
Internationalisation
The application supports 194+ languages with translation files in /assets/langs/.
| Feature | Detail |
|---|---|
| Translation Files | assets/langs/shared.js, menus.js, navs.js |
| Format Conversion | iDempiere format (en_US) ↔ standard (en-US) |
| Storage | localStorage (logship_lang) + HTTP cookie |
| Default Languages | German (de), English (en) |
| Detection | isGerman, isEnglish, isSpanish computed properties |
| Theme Storage | logship_theme in localStorage |
i18n.config.ts) is currently commented out in nuxt.config.ts. Translations are handled via custom composables (useTranslation and useLang).
Push Notifications
Architecture
| Feature | Detail |
|---|---|
| Protocol | Web Push with VAPID authentication |
| Library | web-push 3.6.7 |
| Storage | SQLite (data/push-subscriptions.db) |
| TTL | 24 hours |
| Urgency | High (for order notifications) |
| Targeting | By user ID or role IDs |
| Cleanup | Auto-remove subscriptions older than 90 days + expired (410/404) |
Build & Deployment
Scripts
| Command | Action |
|---|---|
npm run dev | Start development server (localhost:3000) |
npm run build | Generate icons + Nuxt build (production) |
npm run generate | Static site generation |
npm run preview | Preview production build |
npm run generate:icons | Generate app icon variants |
npm run postinstall | Nuxt prepare (auto-types) |
Build Configuration
| Setting | Value |
|---|---|
| Build Target | ES2022 (Vite + esbuild) |
| Top-level Await | Enabled |
| Package Manager | npm 9.8.1 |
| Module Type | ESM ("type": "module") |
| Deployment | Vercel (vercel.json present) |
| Compatibility | 2024-12-10 |
Environment Configuration
Three environment files support different deployment targets:
| File | Purpose |
|---|---|
.env | Default / development configuration |
.env-dev | Development-specific overrides |
.env-prod | Production configuration |
Key Environment Variables
| Category | Variables |
|---|---|
| iDempiere | URLV1, IDEMPIERETOKEN |
| Database | PG_HOST, PG_PORT, PG_DATABASE, PG_USER, PG_PASSWORD |
| Strapi | STRAPIV1, STRAPIUPLOAD, STRAPITOKEN, STRAPIPUBLIC |
| PostgREST | POSTGREST |
| Laravel | LARAVEL |
| DHL | DHLURL, DHLKEY, DHLSECRET, DHLUSER, DHLPASS |
| SendCloud | SENDCLOUD, SENDCLOUDPUBLICKEY, SENDCLOUDPRIVATEKEY |
| Elasticsearch | ELASTIC, ELASTICKEY, ELASTIC_USER, ELASTIC_PASS |
| Push | VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT |
| AG Grid | AGGRID (enterprise license key) |
| Build | GITHASH, BUILDTIME, SOLUTIONNAME |
| Defaults | TARGET_DOCUMENT_TYPE_ID, BUSINESS_PARTNER_GROUP_ID, PRICE_LIST_ID, COUNTRY_ID, IS_CUSTOMER |
Code Patterns & Conventions
Page Pattern
// Standard page template
<script setup lang="ts">
definePageMeta({
layout: 'app',
middleware: ['auth']
})
const headers = useRequestHeaders(['cookie'])
const { data } = await useFetch('/api/resource', { headers })
</script>
API Endpoint Pattern
// Standard server API with token refresh
export default defineEventHandler(async (event) => {
const handleFunc = async (event: any, token?: string) => {
const authToken = token || getTokenHelper(event)
return await fetchHelper(event, 'endpoint', 'GET', authToken, null)
}
let data: any = {}
try {
data = await handleFunc(event)
} catch(err) {
try {
let authToken = await refreshTokenHelper(event)
data = await handleFunc(event, authToken)
} catch(error) {
data = errorHandlingHelper(err, error)
forceLogoutHelper(event, data)
}
}
return data
})
Data Fetching Pattern (Client)
// Pattern 1: useFetch (SSR-compatible)
const { data } = await useFetch('/api/orders', {
headers: useRequestHeaders(['cookie'])
})
// Pattern 2: Direct $fetch (client-side)
const loadData = async () => {
const res = await $fetch('/api/orders?page=1&size=20', {
headers: useRequestHeaders(['cookie'])
})
if (res?.records) items.value = res.records
}
iDempiere Data Model Pattern
// Entity references use ID + tableName format:
{
AD_Org_ID: { id: orgId, tableName: 'AD_Org' },
C_BPartner_ID: { id: partnerId, tableName: 'C_BPartner' },
M_Warehouse_ID: { id: warehouseId, tableName: 'M_Warehouse' },
C_Order_ID: { id: orderId, tableName: 'C_Order' },
M_Product_ID: { id: productId, tableName: 'M_Product' }
}
API Response Format
// Standard response from iDempiere
{
"records": [
{ "id": 1, "name": "...", ... },
{ "id": 2, "name": "...", ... }
],
"page-count": 5,
"records-size": 100,
"skip-records": 0,
"row-count": 100
}
LogShip ERP — Technical Documentation
Generated February 2026 | Branch: dev | Nuxt 3.17.4 + Vue 3.5.16
This documentation was generated from source code analysis of the erp-nuxt-frontend repository.