In the previous articles of this series, Solvisse explored how they replatformed thousands of partner websites onto dotCMS and how they engineered a multi‑site, multi‑tenant content architecture that could scale without losing control. But architecture alone doesn’t solve the real problem.
Once you’re operating at this level of scale, the CMS itself becomes a constraint if it’s not designed for the people who actually use it. That realization led us to build PartnerCMS.
The Real Bottleneck: CMS UX at Scale
dotCMS is a powerful and flexible platform. It excels as a centralized content repository and governance engine. However, its native UI is designed for trained marketing teams—not for thousands of non‑technical partners who need to make frequent, small updates without risking brand integrity.
Early on, Solvisse saw the friction:
Partners were overwhelmed by options they didn’t need.
Minor mistakes could easily lead to off‑brand content or broken layouts.
Training and support costs would only grow as the network expanded.
Rather than forcing partners to adapt to a tool that wasn’t built for them, Solvisse flipped the model.
They kept dotCMS exactly where it shines—behind the scenes—and introduced a purpose‑built experience in front of it. That experience became PartnerCMS.
PartnerCMS: A Purpose‑Built Control Layer
PartnerCMS is not a CMS replacement. It’s a UX‑driven control layer that sits between partners and dotCMS, using dotCMS purely as a content engine accessed through APIs.
The guiding principles were simple:
Make it impossible to go off‑brand.
Remove any need to understand CMS internals.
Optimize for speed, clarity, and safety.
Partners manage only what they’re allowed to manage. Everything else—templates, shared containers, global components, and governance—remains centrally controlled.
Frontend Architecture: Angular, Designed for Guardrails
The PartnerCMS frontend is a single‑page application built with Angular. We chose Angular for its strong modularity, predictable structure, and suitability for large, long‑lived enterprise applications.
Key frontend characteristics:
Feature‑based modular architecture, allowing us to evolve sections independently
RxJS‑driven state management, keeping UI state reactive and consistent
Responsive design using Bootstrap and SCSS for predictable theming.
Editing Without Risk
Instead of exposing raw HTML or generic CMS fields, PartnerCMS provides form‑driven editors tied directly to approved content models:
Articles
Banners
Tiles and cards
Contact and profile components
For richer experiences, we selectively introduced visual tooling:
TinyMCE for structured rich text (with strict formatting rules)
GrapesJS for visual page composition, limited to pre‑approved components only
At no point can a partner break layout, inject unsafe markup, or bypass brand rules—by design.
Accessibility and Usability
Accessibility wasn’t treated as an afterthought:
Semantic HTML and ARIA roles are used throughout
Keyboard navigation is supported across core flows
Components are designed to align with ADA expectations enforced at the template level
Backend Architecture: Reactive by Design
Behind PartnerCMS sits a reactive Java backend built with Spring WebFlux. The decision to go reactive was intentional.
At peak, the system needs to support:
Thousands of concurrent users
High‑frequency reads and writes
Continuous API interaction with dotCMS and internal services
WebFlux allows us to handle this load efficiently using non‑blocking I/O and a small thread footprint.
Layered Backend Design
The backend is organized into clearly defined layers:
Controllers: REST endpoints grouped by feature (articles, banners, analytics, publishing, etc.)
Published Services Layer: Core business logic - validation, guardrails, content limits, and workflows
Feature Services & Clients:
Direct dotCMS REST clients
Optional proxy APIs when abstraction or transformation is required
Domain & Mapping Layer: DTOs and assemblers mapping PartnerCMS models to dotCMS content types
This separation keeps the system testable, maintainable, and resilient to change.
Authentication, Authorization, and Safety
PartnerCMS integrates with the parent company’s identity platform using OAuth2. Authentication is fully stateless and token‑based.
Security highlights:
Role‑based access enforced at the endpoint level
Automatic token refresh via silent re‑authentication
Strict scoping so partners only ever see their own content
Even destructive actions are guarded. For example:
Content deletion is implemented as archiving, not hard deletes
True deletes are handled asynchronously via controlled background jobs
This ensures content safety while preserving operational flexibility.
Reliability and Operational Discipline
From day one, PartnerCMS was treated as a production‑critical system.
That meant:
75%+ unit test coverage on core business and mapping layers
Centralized error handling using reactive patterns like onErrorResume
Environment‑specific configuration via externalized YAML files
Predictable deployment behavior across environments
The goal wasn’t just to ship features—it was to build something that could be trusted at scale.
What Partners Actually Experience
From the partner’s point of view, none of the underlying complexity exists.
They see:
A clean dashboard showing what can be edited
Simple forms instead of CMS screens
Live preview and safe publishing workflows
Built‑in visibility into analytics
They don’t see:
dotCMS internals
Content modeling decisions
Workflow mechanics
Rendering logic
And that’s exactly the point.
Closing the Loop
PartnerCMS completes the architectural story we started in the first two articles.
dotCMS provides the content backbone
The multi‑site architecture enforces scale and governance
PartnerCMS delivers usability without compromise
Together, they form a system where thousands of independent partners can confidently manage their digital presence—without ever putting the brand, performance, or platform at risk.
In the final article of this series, we’ll dive into how we keep this entire ecosystem synchronized daily using scheduled jobs, Redis caching, proxy APIs, and programmatic publishing at scale.