Architecture Overview
Understanding Salora's system design and component interactions
Salora follows a modern, layered architecture designed for scalability, maintainability, and performance.
System Architecture
┌─────────────────────────────────────────┐
│ Client Layer │
│ Browser / SvelteKit Frontend │
└──────────────────┬──────────────────────┘
│ HTTP
▼
┌─────────────────────────────────────────┐
│ Application Server Layer │
│ SvelteKit (with tRPC integration) │
└──────────────────┬──────────────────────┘
│ tRPC RPCs
▼
┌─────────────────────────────────────────┐
│ API Layer (tRPC) │
│ ├─ Procedures (Queries/Mutations) │
│ ├─ Middleware (Auth, Validation) │
│ └─ Type Safety (End-to-End) │
└──────────────────┬──────────────────────┘
│
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
Business Scheduling Authentication
Logic Engine Service
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────┐
│ Data Access Layer │
│ Prisma ORM with Type Safety │
└──────────────────┬───────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ Database Layer │
│ PostgreSQL (Relational) │
└──────────────────────────────────────────┘Layered Design
1. Presentation Layer
Frontend (SvelteKit)
- Server-side rendering for performance
- File-based routing for simplicity
- Reactive components with Svelte
- Type-safe client code through tRPC
Key Files:
apps/frontend/src/routes/- Page componentsapps/frontend/src/lib/components/- Reusable components
2. API Layer (tRPC)
Type-Safe Remote Procedure Calls
tRPC provides:
- End-to-end TypeScript type safety
- Input validation with Zod schemas
- Output type definitions
- Automatic code generation
Structure:
src/lib/server/trpc/
├── context.ts # Request context setup
├── router.ts # Root router composition
└── routers/ # Organized route definitions
├── v1/ # API v1 endpoints
└── v2/ # API v2 endpointsProcedure Types:
publicProcedure- Publicly accessible endpointsprivateProcedure- Authenticated user endpointsportalProcedure- Public portal endpoints (appointments)
3. Business Logic Layer
Domain-Specific Services
- AvailabilityEngine - Slot calculation and availability
- NotificationService - Email and notification dispatch
- Authentication - User auth and sessions
Key Directories:
src/lib/server/- Server-side utilitiespackages/scheduler/- Scheduling algorithms
4. Data Access Layer
Prisma ORM
- Database-agnostic queries
- Type-safe models
- Migration management
- Transaction support
Schema Structure:
packages/database/prisma/schema.prisma- Data model
5. Database Layer
PostgreSQL
- ACID compliance
- Relational data integrity
- Full-text search capability
- JSON support
Key Components
Authentication System
┌─────────────────┐
│ User Login │
└────────┬────────┘
│
▼
┌─────────────────────┐
│ Auth.js (BetterAuth)│
└────────┬────────────┘
│ Session/Token
▼
┌──────────────────────┐
│ Session Validation │
└────────┬─────────────┘
│
▼
┌──────────────────────┐
│ tRPC Context (ctx) │
└──────────────────────┘Features:
- Magic links for passwordless auth
- Session-based authentication
- Organization/role support
- User context in tRPC
Data Model
Core Entities:
Organization
├── Members (Team)
├── Services
├── Customers
├── Employees
├── OpeningTimes
└── CalendarItems (Appointments)
└── BookingsRelationships:
- Users can be members of multiple organizations
- Organizations have services and employees
- Customers book services with employees
- Calendar items track availability and appointments
Availability Engine
The scheduling subsystem calculates available slots:
┌──────────────────────────────────┐
│ Request for Available Slots │
│ (Service, Date, Employee) │
└──────────────────┬───────────────┘
│
┌────────────┴────────────┐
│ │
▼ ▼
1. Fetch Opening 2. Fetch Booked
Times Slots
│ │
└────────────┬────────────┘
│
▼
3. Calculate Free Slots
(Opening Hours - Bookings)
│
▼
4. Apply Service Duration
│
▼
5. Return Available TimesAPI Versioning
Salora maintains multiple API versions for backward compatibility:
tRPC Router
├── v1/
│ ├── authenticated/ (user-scoped)
│ └── protected/ (rate-limited public)
├── v2/
│ └── authenticated/ (enhanced endpoints)
└── appointment/ (public booking)Request/Response Flow
Authenticated Query Example
// Client request
const result = await trpc.v1.authenticated.customers.getCustomers
.query({ organizationId })
// Flow:
1. Client sends tRPC query
2. Server receives in tRPC handler
3. Context middleware validates session
4. Procedure input validated with Zod
5. Business logic executes query
6. Prisma queries database
7. Results returned and type-checked
8. Client receives fully typed responseMutation Example
// Client sends mutation
const result = await trpc.v1.authenticated.customers.updateCustomer
.mutate({ id, organizationId, name, email })
// Flow:
1. Input validation (Zod schema)
2. User auth check (session)
3. Organization ownership verification
4. Database update transaction
5. Notification service triggered
6. Response returned with new state
7. Client updates local stateError Handling
tRPC Error Codes:
NOT_FOUND- Resource doesn't existUNAUTHORIZED- User not authenticatedFORBIDDEN- User lacks permissionsBAD_REQUEST- Invalid inputINTERNAL_SERVER_ERROR- Server error
Pattern:
if (!user) {
throw new TRPCError({
code: 'UNAUTHORIZED',
message: 'user_not_authenticated'
});
}Performance Considerations
Database Optimization
- Indexes on frequently queried fields
- Eager loading with Prisma
include - Transaction batching for multi-step operations
- Pagination with skip/take
Caching Strategy
- Session tokens for auth
- Redis for rate limiting
- Client-side query caching with Svelte stores
Asset Delivery
- Static files via CDN (Cloudflare)
- SvelteKit SSR for initial page load
- Component-level code splitting
Deployment Architecture
┌─────────────────────┐
│ Git Repository │
└────────────┬────────┘
│
▼
┌────────────────┐
│ Verification │
│ (Lint, Test) │
└────────┬───────┘
│
┌──────┴──────┐
│ │
▼ ▼
Frontend Email Worker/
(Cloudflare Cloudflare
Pages) Workers
│
▼
┌──────────────┐
│ Production │
│ Environment │
└──────────────┘Deployment Options:
- Frontend: Cloudflare Pages (SvelteKit adapter)
- Database: Managed PostgreSQL (AWS RDS, Heroku, etc.)
- Email Worker: Cloudflare Workers
- Email Queue: Redis or message queue
Development vs Production
Development Environment
- Local database (docker-compose)
- Hot module reloading
- Detailed error messages
- No authentication required (dev mode)
Production Environment
- Managed database with backups
- Optimized builds
- Error tracking/logging
- Full authentication enforced
- Rate limiting active
Next Steps
- Review Core Concepts to understand domain entities
- Check Development Setup for environment configuration
- Explore the codebase using Project Structure as a guide