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.
ADR 2: Cookie-based JWT Authentication
- Status: Accepted
- Context: Traditional Bearer tokens in LocalStorage are vulnerable to XSS.
- Decision: Use
HttpOnly,Secure,SameSite=Strictcookies 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
Hostheader. - 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
sharedpackage 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.