Skip to content

ADR-008: Presentation Layer Modernization to Enterprise Angular SPA with PrimeNG and Tailwind CSS v4

ACCEPTED  2026-10-04


The initial B2B web presentation layer of the GERCIA Platform was built with Blazor Server (Gercia.Web) under @rendermode="InteractiveServer". While Blazor Server provided high initial C# code-sharing across the backend and frontend, adopting Google Cloud Run (serverless stateless containers) and expanding to enterprise multidisciplinary clinical workflows revealed insurmountable architectural frictions:

  1. Stateful WebSocket Circuits vs. Stateless Serverless Containers:

    • Blazor Server requires persistent, stateful WebSocket connections (SignalR) where each user’s complete Document Object Model (DOM) tree resides in the server’s RAM.
    • Google Cloud Run is designed for stateless HTTP request-driven workloads that automatically scale instances up and down and scale to zero when idle. In Blazor Server, recycling or scaling down an instance abruptly terminates user WebSocket circuits, displaying disruptive “Attempting to reconnect…” banners to medical staff mid-consultation.
    • Ensuring circuit stickiness on Cloud Run requires keeping containers permanently running (min-instances: 1), inflating idle cloud costs and defeating the serverless economics.
  2. Network Sensitivity in Real-World Clinical Environments:

    • Physicians, physiotherapists, and compounding technicians frequently operate across mobile tablets, clinic Wi-Fi networks, and cellular 4G/5G connections. Temporary network flickers (e.g., 2–3 seconds of packet loss) sever Blazor Server circuits, forcing page reloads and risking in-progress digital prescription inputs.
  3. Enterprise UI Ergonomics & Component Maturity:

    • Enterprise clinical workflows require specialized, high-density interfaces: interactive anatomical Odontogram components, dynamic 50+ field sanitary forms (ReactiveFormsModule), multi-practitioner appointment scheduling, and complex patient grids.
    • While Syncfusion Blazor provided initial components, its monolithic styling and proprietary runtime script architecture complicated customization and clashed with modern utility-first CSS frameworks.

The GERCIA Platform officially decommissions Blazor Server (Gercia.Web) and establishes Angular 22 (Zoneless, Signals) paired with PrimeNG 22 and Tailwind CSS v4 as the sovereign corporate B2B web presentation standard (app.gercia.com.br and app.gercia.vet.br), deployed statically via Cloudflare Pages.

flowchart TD
    subgraph CLIENT ["Client Browser Environment"]
        BROWSER["Web Browser Client<br>(Physicians, Dentists, Pharmacists, Clinics)"]
        SPA["<b>Angular Enterprise SPA (apps/app)</b><br>• Standalone Components & Angular Signals<br>• PrimeNG 22 UI Suite (Tailwind Presets)<br>• ReactiveFormsModule with Strict Type Checking<br>• FullCalendar Angular Scheduler"]
    end

    subgraph EDGE ["Static Delivery Tier (Cloudflare)"]
        CF_PAGES["Cloudflare Pages<br>Global Anycast CDN • Zero Hosting Cost<br>Instant Edge Asset Caching • Pre-compressed Assets"]
    end

    subgraph BACKEND ["Stateless Backend Tier (Google Cloud Platform)"]
        STS["OpenIddict STS<br>(OAuth 2.1 / OIDC - Auth Code + PKCE)"]
        SERVER["Gercia.Server (ASP.NET Core Minimal APIs)<br>Stateless Cloud Run Service<br>Scale-to-Zero • Automated CORS Controls"]
    end

    CF_PAGES -- "1. Delivers Static SPA Assets (HTML/JS/CSS)" --> BROWSER
    BROWSER --> SPA
    SPA -- "2. OIDC Authentication Challenge (PKCE)" --> STS
    SPA -- "3. HTTPS REST Calls (JSON with Bearer JWT)" --> SERVER
  1. Angular Standalone Architecture & Reactive State (Signals):

    • The application eliminates legacy NgModule declarations in favor of lightweight Standalone Components, leveraging Angular Signals for fine-grained, zone-less reactivity and ultra-low memory footprints.
    • Form validation leverages ReactiveFormsModule with nested typed FormGroups and FormArrays to enforce Brazilian sanitary regulations (CFM, ANVISA) on client-side inputs prior to network transmission.
  2. PrimeNG 22 with Native Tailwind CSS v4:

    • Component presentation standardizes on PrimeNG 22 using the Aura / Lara design tokens natively aligned with Tailwind CSS v4.
    • Delivers modern SaaS aesthetics (matching linear/stripe design standards) across DataTables, MultiSelects, Modals (p-dialog), and Toasts (p-toast).
  3. Medical & Pharmacy Scheduling (FullCalendar & PrimeNG Integration):

    • Clinical consultation and pharmacy workbench scheduling standardizes uniformly on @fullcalendar/angular (Day, Week, Month timegrid views, multi-practitioner/multi-station columns, and drag-and-drop rescheduling), surrounded by PrimeNG quick-booking dialogs, eliminating proprietary third-party commercial scheduling dependencies.
  4. Zero-Cost Static Hosting via Cloudflare Pages:

    • The compiled Angular SPA resides entirely on Cloudflare Pages edge CDN, achieving sub-second initial load times across all Brazilian geographic regions with zero origin container overhead.
  5. Decoupled API Authentication via OpenIddict (PKCE):

    • The Angular client authenticates against api.gercia.com.br using standard OAuth 2.1 Authorization Code Flow with Proof Key for Code Exchange (PKCE) via angular-auth-oidc-client. Tokens rotate periodically without stateful server sessions.

  • Stateless Resilience: Network dropouts of 2–5 seconds do not crash or reset the UI. The SPA remains responsive in the browser, queueing requests cleanly.
  • Serverless Cost Optimization: Removing Blazor Server WebSockets allows Gercia.Server containers on Google Cloud Run to scale to zero at night, eliminating unnecessary compute bills.
  • Enterprise Design Fidelity: PrimeNG 22 and Tailwind CSS v4 deliver a world-class, responsive healthcare SaaS interface with native dark mode support.
  • Rapid Developer Feedback: Fast HMR (Hot Module Replacement) via Vite/Angular CLI accelerates UI development.
  • Contract Duplication Management: Transitioning from full-stack C# to TypeScript requires automated OpenAPI/Swagger generation tools to synchronize backend DTOs with frontend TypeScript models.
  • Browser Bundle Size Governance: Strict tree-shaking and route-based lazy loading must be enforced to maintain initial bundle payloads under 350 KB.