Server Package
Backend services and data layer for the monorepo.
Overview
The packages/server/ directory contains backend services, repositories, and utilities shared across applications.
Location: packages/server/
Sub-packages:
@uwdsc/server/core- Shared backend utilities@uwdsc/server/web- Web app backend@uwdsc/server/cxc- CxC app backend
Structure
packages/server/
βββ core/ # Shared backend utilities
β βββ src/
β β βββ database/ # Supabase client
β β βββ services/ # Auth, file services
β β βββ repository/ # Base repository
β β βββ types/ # TypeScript types
β β βββ utils/ # Error handling
β βββ package.json
βββ web/ # Web app backend
β βββ src/
β β βββ db/ # Database migrations (db-mate)
β β βββ services/ # Business logic
β β βββ repository/ # Data access
β β βββ types/ # Types
β βββ package.json
βββ cxc/ # CxC app backend
βββ src/
β βββ db/ # Database migrations (db-mate)
β βββ services/ # Business logic
β βββ repository/ # Data access
β βββ types/ # Types
βββ package.jsonCore Package (@uwdsc/server/core)
Shared backend utilities used by both web and cxc backends.
Exports
import { AuthService } from "@uwdsc/server/core/services/authService";
import { FileService } from "@uwdsc/server/core/services/fileService";
import { BaseRepository } from "@uwdsc/server/core/repository/baseRepository";Services
AuthService - Authentication with Supabase
- Sign up
- Sign in
- User management
- Session handling
FileService - File upload/storage with Supabase Storage
- Upload files
- Get public URLs
- Delete files
ResumeService - Resume processing
- Parse resumes
- Extract data
Repository
BaseRepository - Base class for all repositories
- pg connection pool access
- Common database operations
- Transaction support
Web Package (@uwdsc/server/web)
Backend services specific to the main website.
Exports
import { HealthService } from "@uwdsc/server/web/services/healthService";
import { ProfileService } from "@uwdsc/server/web/services/profileService";
import { ApplicationService } from "@uwdsc/server/web/services/applicationService";Services
- HealthService - System health checks
- ProfileService - User profile management
- ApplicationService - Membership applications
- EventService - Event management
Repositories
- HealthRepository - Health check queries
- ProfileRepository - Profile data access
- ApplicationRepository - Application data access
- EventRepository - Event data access
CxC Package (@uwdsc/server/cxc)
Backend services specific to the CxC AI hackathon app.
Exports
import { ApplicationService } from "@uwdsc/server/cxc/services/applicationService";
import { TeamService } from "@uwdsc/server/cxc/services/teamService";Services
- ApplicationService - AI hackathon applications
- TeamService - Team management
- EventService - AI hackathon events
Usage
In API Routes
// apps/web/app/api/profile/route.ts
import { NextResponse } from "next/server";
import { ProfileService } from "@uwdsc/server/web/services/profileService";
export async function GET() {
const profileService = new ProfileService();
const profile = await profileService.getProfile(userId);
return NextResponse.json(profile);
}Service Layer
// packages/server/web/src/services/profileService.ts
import { ProfileRepository } from "../repository/profileRepository";
export class ProfileService {
private repository: ProfileRepository;
constructor() {
this.repository = new ProfileRepository();
}
async getProfile(userId: string) {
return await this.repository.findById(userId);
}
}Repository Layer
// packages/server/web/src/repository/profileRepository.ts
import { BaseRepository } from "@uwdsc/server/core/repository/baseRepository";
export class ProfileRepository extends BaseRepository {
async findById(userId: string) {
const result = await this.pool.query(
"SELECT * FROM users WHERE id = $1",
[userId]
);
return result.rows[0] || null;
}
}Database
Migrations (db-mate)
Each app-specific package has its own migration directory:
-- packages/server/web/src/db/migrations/001_create_users_table.up.sql
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_users_email ON users(email);Migrations are managed with db-mate:
# Create new migration
db-mate new add_user_bio
# Apply migrations
db-mate up
# Rollback last migration
db-mate downSupabase
Core package uses Supabase for:
- Authentication
- File storage
- Real-time subscriptions
Best Practices
β Do
- Use services for business logic
- Use repositories for data access
- Extend BaseRepository for common functionality
- Handle errors appropriately
- Use TypeScript types
- Write unit tests
β Donβt
- Put business logic in repositories
- Access database directly from services
- Skip error handling
- Expose internal errors to clients
- Mix concerns across layers
Next Steps
- API Architecture - Learn about backend patterns
- Creating API Endpoints - Build APIs
- Database Setup - Work with db-mate and pg