AKHN: Architectural Transition of a Marketplace Platform from a REST Monolith to GraphQL/DDD
Leading a full architectural transition of a marketplace platform connecting clients with engineering contractor teams: from a REST monolith to a GraphQL backend with DDD/CQRS, alongside a parallel frontend rewrite from Redux to Apollo Client. Three applications, one developer.
AKHN is a marketplace platform connecting clients with engineering contractor teams. The system is made up of three applications: a public website (team catalogue, request forms, order creation from the landing page), a main application — the shared workspace for both sides (orders, teams, documents, finances, chat), and a backend.
I'm leading the backend's architectural transition and a parallel frontend rewrite — not a rewrite from scratch, but a managed transition without stopping the product.
Business domain
The platform covers: authentication, two user types (individuals/ businesses), teams with a role model and an invitation system, a full order lifecycle (from draft to dispute and completion), document workflow with contract generation, finances and payments (multiple providers), a built-in real-time messenger, notifications, RBAC access control, and an admin panel.
Where it started
The backend was a NestJS monolith with a REST API on top of MySQL. A few modules had already partially adopted the CQRS pattern, but without consistent architectural discipline across the whole project.
Where I'm taking it
I'm building the new backend on DDD layers (domain/application/ infrastructure/presentation) with CQRS across every business module, on GraphQL instead of REST and PostgreSQL instead of MySQL. Access control runs on CASL with a layered model: user type → global permissions → a contextual role scoped to a specific team.
Migrating the frontend
The frontend follows the new backend's lead, not the other way around:
- Redux is being replaced by Apollo Client — a reactive GraphQL cache instead of a global store.
- REST calls are moving to GraphQL operations, with one deliberate exception (an external OAuth integration I chose not to force into GraphQL just for consistency).
- The frontend architecture is moving to Feature-Sliced Design, while every bit of the UI code (design system, components) carries over unchanged — it's the structure being refactored, not the look.
- A separate challenge is the terminology drift between the old frontend and the new backend (renamed roles, renamed order statuses): every mapping lives in one single source of truth, so old values can't leak back into the codebase.
The migration proceeds in phases, from simple and low-risk (infrastructure, auth) to complex (the messenger comes last, as its own phase).
Verifying through audit
Beyond tests, I run a systematic check of the frontend code against the backend's live GraphQL schema: going operation by operation, confirming every status/role comparison and every permission check actually matches what the server returns — not what the frontend code assumes from memory. That caught real bugs before production: a one-letter typo in an order status filter that would have silently matched nothing, handlers with no error handling for network failures, and hardcoded pagination that would have made a chunk of users unreachable in the admin panel.
Result
The entire project — all three applications and the architectural migration itself — is being built solo, from designing the architecture and picking the stack to auditing the frontend line by line against the real backend schema.