Skip to main content

Architectural Decision Records (ADR)

This document records the significant architectural decisions made during the development of Skin Club Pro.

ADR 1: Monorepo Structure

  • Status: Accepted
  • Context: We needed a way to manage multiple services, a shared library, and multiple frontend applications while maintaining type safety and code reuse.
  • Decision: Use an NPM Workspaces-based monorepo.
  • Consequences: Easier sharing of entities and types via @skinclubpro/shared, unified CI/CD, but requires careful dependency management.
  • Status: Accepted
  • Context: Traditional Bearer tokens in LocalStorage are vulnerable to XSS.
  • Decision: Use HttpOnly, Secure, SameSite=Strict cookies to store JWTs.
  • Consequences: Significantly improved security against XSS. Requires CSRF protection and handling of cross-domain cookie issues in development.

ADR 3: Microservices with NestJS

  • Status: Accepted
  • Context: The system needs to scale different modules (Auth, Clinic, CMS, Notifications) independently.
  • Decision: Use NestJS for all backend services.
  • Consequences: Consistent developer experience across services, built-in support for dependency injection, and easy integration with TypeORM and BullMQ.

ADR 4: Asynchronous Processing with Redis/BullMQ

  • Status: Accepted
  • Context: Tasks like sending emails or processing heavy data should not block the main request-response cycle.
  • Decision: Use Redis with BullMQ for reliable background job processing.
  • Consequences: Improved system responsiveness and reliability. Adds Redis as a required infrastructure component.

ADR 5: CloudFront SaaS Manager for Site Provisioning

  • Status: Accepted
  • Context: We need to provide subdomains for practitioners instantly without complex DNS management for every new user.
  • Decision: Use a Wildcard DNS + Wildcard SSL + CloudFront Functions to route traffic based on the Host header.
  • Consequences: Instant site provisioning (database-only operation), centralized SSL management, and reduced infrastructure cost.

ADR 6: Shared Entity Pattern

  • Status: Accepted
  • Context: Multiple services need to share the same database schema and TypeScript types.
  • Decision: Define TypeORM entities in the shared package and import them into services.
  • Consequences: Single source of truth for the database schema. Requires services to be rebuilt when shared entities change.

ADR 7: Portable CMS UI

  • Status: Accepted
  • Context: CMS functionality needs to be embedded in different apps (Admin, Practitioner Dashboard).
  • Decision: Extract CMS UI components into a dedicated package @skinclubpro/cms-ui.
  • Consequences: Consistent CMS experience across different platforms and easier maintenance of the CMS interface.