Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/CodexaCP/DG_WEB/llms.txt

Use this file to discover all available pages before exploring further.

Dragon Guard WMS Web hosts two distinct surfaces inside the same Angular shell: a tenant surface for company admins managing their warehouse, and a SaaS surface for Grupo MAS super-administrators managing the platform itself. These surfaces share a login screen but diverge immediately after authentication — different routes, different Angular services, different backend API namespaces, and different session metadata. The split is intentional and fail-closed: access to the wrong surface is rejected by both the frontend guard and the backend authorization layer.

Two Surfaces at a Glance

Served to: Company admins (ADMIN role and below)Root route: /dashboard (and sub-paths like /dashboard/receipts, /dashboard/admin)Angular service: WmsService — resolves companyId automatically from session; scopes every request to the authenticated tenant.Backend namespace: /api/* (standard WMS endpoints)Guard: authGuard (all routes) + adminGuard (/dashboard/admin/**)

Session Keys

After a successful login, AuthService writes the following keys to sessionStorage. All downstream services and guards read from this store. localStorage is never used.
KeyTypePurpose
tokenstringJWT bearer token attached to every API request
active_company_idnumberThe tenant context injected by WmsService into scoped requests
active_rolestringRole string used by guards (ADMIN, SUPERADMIN_SUPREMO, etc.)
is_supreme_adminbooleanFast flag used at login to determine post-auth redirect destination
active_company_id is intentionally absent from a super-admin’s session when they have no operational tenant. WmsService will not inject a fallback company ID — requests that require a tenant context must originate from a tenant-scoped session.

SupremeService Endpoints

The SaaS surface is backed by a dedicated set of API endpoints under the /api/supreme/ namespace. These endpoints are only called by SupremeService and are never invoked from tenant screens.
GET  /api/supreme/dashboard              # Platform-wide stats
GET  /api/supreme/companies              # List all tenant companies
POST /api/supreme/companies              # Create a new tenant company

GET  /api/supreme/plans                  # List subscription plans
POST /api/supreme/plans                  # Create a plan

GET  /api/supreme/companies/{tenantId}/users   # Users for a specific tenant
POST /api/supreme/companies/{tenantId}/users   # Add a user to a tenant
These endpoints must never be called from tenant-scoped Angular code. Importing SupremeService into a module outside supreme/ is a contract violation. Backend authorization will reject such calls regardless, but mixing the services introduces coupling that is hard to untangle.

Login and Role-Based Routing

1

Credentials submitted

Both super-admins and company admins use the same /auth/login screen. The POST /api/Auth/login response includes is_supreme_admin alongside the JWT and company list.
2

Session keys written

AuthService writes all four session keys to sessionStorage. For a super-admin with no operational tenant, active_company_id is left unset.
3

Redirect decision

AuthService reads is_supreme_admin:
  • true → redirect to /dashboard/supreme
  • false → redirect to /dashboard
4

Menu rendered for role

The shell’s sidebar menu is built from the session role. SUPERADMIN_SUPREMO sees only the SaaS menu (companies, plans, platform dashboard). Tenant menu items are hidden entirely — they are not collapsed or disabled, they are absent from the menu tree.

Business Rules

The following rules govern the multi-tenant model and must be respected in all future frontend and backend work:
  • SUPERADMIN_SUPREMO is always redirected to /dashboard/supreme after login. They do not land on the tenant dashboard, even if they somehow also have a companyId in their token.
  • Only the SaaS menu is shown for SUPERADMIN_SUPREMO. Tenant screens are not rendered, not merely hidden.
  • Company admins use the standard dashboard and tenant modules. They have no visibility into other companies’ data.
  • A super-admin with no operational tenant can still log in. The absence of active_company_id is a valid session state for the SaaS surface.
  • No default fallback company is injected for super-admins. If a super-admin accidentally triggers a tenant-scoped request, WmsService will not silently pick a company — the call will fail rather than leak data.
  • Prefer additive changes to the session schema. Adding a new session key is safe. Renaming or removing a key requires updating every guard, service, and component that reads it.

Security Model

Frontend guards are a UX convenience, not a security boundary. The backend must enforce authorization on every request independently of what the Angular guard decided.
The multi-tenant security model has two layers that must both hold:
LayerMechanismWhat it prevents
FrontendsupremeGuard on /dashboard/supreme/**Prevents accidental navigation; fast rejection without a network round-trip
BackendJWT claims checked on every /api/supreme/* callPrevents any client — Angular, MAUI, curl — from accessing cross-tenant data
A company admin who types /dashboard/supreme/companies directly into the address bar is rejected by supremeGuard before the route loads. If they somehow bypass the guard, the first API call returns 401 or 403 from Wms.Api. Neither layer alone is sufficient.

Edge Cases

ScenarioExpected behaviour
Super-admin navigates directly to /dashboard/receiptsauthGuard passes (valid token), but the tenant-scoped API calls fail because active_company_id is unset
Company admin navigates directly to /dashboard/supreme/companiessupremeGuard rejects the navigation; user stays on current route
Token expires mid-session on the SaaS surfaceJWT interceptor catches 401, clears sessionStorage, redirects to /auth/login
Super-admin has an operational tenant accountis_supreme_admin: true always wins; user is routed to SaaS surface regardless
Multi-company tenant admin switches companyactive_company_id is updated in sessionStorage; WmsService picks up the new value on the next request

Architecture Overview

Module structure, lazy routing, central service rule, JWT auth flow, and the web/handheld responsibility boundary.

API Contracts

Endpoint inventory, contract stability rules, MAUI compatibility requirements, and the versioning strategy.

Build docs developers (and LLMs) love