KoroCRM
Multi-tenant CRM and Property Management System in production for Chivasom (Thailand) and Zulal (Qatar), two flagship luxury wellness resorts. NestJS + Nuxt 3 + MSSQL with decorator-enforced per-tenant isolation; ongoing platform engagement since November 2025.
The Problem
Luxury wellness resorts coordinate housekeeping, maintenance, lost-and-found, and concierge across spa, treatment, and back-of-house — often in multiple languages. Guest journeys are structured differently from a typical hotel stay, so generic “hotel software” rarely fits.
Off-the-shelf PMS products such as Opera or Mews cover broad hospitality operations. They are not tuned for high-touch wellness properties where treatment timing, inspections, and concierge routing sit at the centre of daily work.
Korotek needed one codebase serving multiple branded resorts with hard tenant boundaries: a Chivasom record must never appear under a Zulal context. The platform also had to evolve at the pace operations teams request features — not on an annual vendor release cycle.
The brief covered a full operational suite: Housekeeping, Inspections, Maintenance, Lost & Found, and Concierge. Every module had to be multi-tenant, auditable, and localised for the markets Chivasom and Zulal serve.
The Solution
Apex36 builds and maintains KoroCRM for Korotek on a continuous monthly engagement since November 2025. The product is also tracked internally as GXM360.
Backend: NestJS 10, Sequelize, Microsoft SQL Server, TypeScript. Frontend: Nuxt 3, Vue 3, Vuetify 3. Authentication uses JWT; authorisation uses CASL with permission decorators such as RequirePermissions on every controller.
Tenant isolation is enforced at the ORM layer. Custom TenantScoped and TenantIds NestJS decorators attach TenantId filtering to Sequelize queries. Context travels on x-tenant-id and x-tenant-scope headers, so a tenant-scoped query never reaches the database without a scope.
Five modules ship today: Housekeeping, Inspections, Maintenance, Lost & Found, and Concierge. English, Thai, Arabic, and French are in production — matching Chivasom, Zulal, and French-speaking guests.
An internal mssql-mcp-server (Model Context Protocol) speeds day-to-day MSSQL work during development. Repository rules in CLAUDE.md and AGENTS.md keep multi-tenant safety and permissions consistent as the team ships features.
Features
Five operational modules
Housekeeping, Inspections, Maintenance, Lost & Found, and Concierge. Each module is first-class in the product, with workflows aimed at luxury wellness operations rather than generic hotel patterns.
Decorator-based multi-tenancy
TenantScoped and TenantIds NestJS decorators enforce isolation at the Sequelize ORM layer. Requests carry x-tenant-id or x-tenant-scope; queries include a TenantId filter before MSSQL.
JWT + CASL authorisation
JWT for auth; CASL for fine-grained permissions (e.g. RequirePermissions on create/update paths). Capabilities are enforced at the controller before business logic runs.
English / Thai / Arabic / French i18n
Production support for English, Thai, Arabic, and French — for Chivasom, Zulal, and shared guest languages. Strings and payloads are localised across API and Nuxt UI.
Concierge + operator training
Concierge includes a training package: seven or more walkthrough videos plus DOCX transcripts for resort staff, so roll-out does not depend on ad-hoc explanations.
Internal mssql-mcp-server dev tool
Internal MCP server built to accelerate MSSQL querying during development.
Results / Impact
two luxury wellness resorts running on the same multi-tenant codebase.
spanning housekeeping, inspections, maintenance, lost & found, concierge.
at the ORM layer, clean separation across branded properties.
FAQ
Isolation uses two custom NestJS decorators — TenantScoped and TenantIds — wired into Sequelize so every query that touches tenant data includes TenantId before MSSQL.
Tenant context comes from x-tenant-id or x-tenant-scope headers. A scoped model cannot be queried without tenant context. Review follows CLAUDE.md conventions so a Chivasom row cannot surface under Zulal regardless of who wrote the handler.
Chivasom (Hua Hin, Thailand) and Zulal (Qatar) run on the same multi-tenant deployment. Both are flagship wellness destinations in their regions.
Production languages: English, Thai, Arabic, and French. Staff and guests see the interface in the language that matches their property and role.
Backend: NestJS 10, Sequelize, MSSQL, TypeScript. JWT auth and CASL permissions on endpoints. Frontend: Nuxt 3, Vue 3, Vuetify 3 with script setup and composables.
The codebase is also known internally as GXM360. Multi-tenancy is enforced in Nest decorators tied to Sequelize, not as an afterthought in middleware.
Apex36, on a monthly engagement with Korotek running since November 2025.
Scope includes backend architecture, all five operational modules, the Nuxt frontend, en/th/ar/fr localisation, CLAUDE.md and AGENTS.md conventions, and the internal mssql-mcp-server tooling for faster database work.
Ready to build something impactful?
Let's discuss your project and how we can help you ship faster and smarter.
Book a Free Strategy Call