fix tests
This commit is contained in:
@@ -1,148 +0,0 @@
|
||||
# Docker Auth/Session Test Fixes Summary
|
||||
|
||||
## Problem
|
||||
The docker-compose.test.yml setup had 18 failing tests related to authentication session issues. The main problems were:
|
||||
|
||||
1. **Service dependency issues**: Website container started before deps container finished installing
|
||||
2. **Cookie domain problems**: Mock API cookies weren't working properly in Docker environment
|
||||
3. **Network connectivity**: Website couldn't reach API due to timing and configuration issues
|
||||
|
||||
## Root Causes
|
||||
|
||||
### 1. Missing Service Dependencies
|
||||
- Website container didn't wait for deps container to complete
|
||||
- API container didn't wait for deps container
|
||||
- This caused "next: not found" and module resolution errors
|
||||
|
||||
### 2. Cookie Domain Issues
|
||||
- Mock API set cookies without domain specification
|
||||
- In Docker, cookies need proper domain settings to work across containers
|
||||
- Browser at localhost:3100 couldn't access cookies from API at localhost:3101
|
||||
|
||||
### 3. Slow npm Install
|
||||
- deps container took too long to install packages
|
||||
- Website container would timeout waiting
|
||||
- No proper health checks or completion signals
|
||||
|
||||
## Fixes Applied
|
||||
|
||||
### 1. Updated `docker-compose.test.yml`
|
||||
|
||||
**Before:**
|
||||
```yaml
|
||||
website:
|
||||
depends_on:
|
||||
api:
|
||||
condition: service_healthy
|
||||
```
|
||||
|
||||
**After:**
|
||||
```yaml
|
||||
deps:
|
||||
command: ["sh", "-lc", "echo '[deps] Ready' && sleep infinity"]
|
||||
# Simple command that completes immediately
|
||||
|
||||
api:
|
||||
depends_on:
|
||||
deps:
|
||||
condition: service_started
|
||||
# Added deps dependency
|
||||
|
||||
website:
|
||||
depends_on:
|
||||
deps:
|
||||
condition: service_started # Wait for deps
|
||||
api:
|
||||
condition: service_healthy # Wait for API
|
||||
command:
|
||||
- sh
|
||||
- -lc
|
||||
- |
|
||||
# Check if node_modules exist, install if needed
|
||||
if [ ! -d "node_modules" ] || [ ! -f "node_modules/.bin/next" ]; then
|
||||
echo "[website] Installing dependencies..."
|
||||
npm install --no-package-lock --include-workspace-root --no-audit --fund=false --prefer-offline
|
||||
else
|
||||
echo "[website] node_modules already present"
|
||||
fi
|
||||
echo "[website] Starting Next.js dev server..."
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### 2. Fixed `testing/mock-api-server.cjs`
|
||||
|
||||
**Before:**
|
||||
```javascript
|
||||
const cookies = [
|
||||
`gp_session=${encodeURIComponent(gpSessionValue)}; Path=/; HttpOnly`,
|
||||
`gridpilot_demo_mode=${encodeURIComponent(mode)}; Path=/`,
|
||||
];
|
||||
```
|
||||
|
||||
**After:**
|
||||
```javascript
|
||||
// Set cookies with proper domain for Docker environment
|
||||
const domain = 'localhost';
|
||||
const cookies = [
|
||||
`gp_session=${encodeURIComponent(gpSessionValue)}; Path=/; HttpOnly; Domain=${domain}`,
|
||||
`gridpilot_demo_mode=${encodeURIComponent(mode)}; Path=/; Domain=${domain}`,
|
||||
];
|
||||
```
|
||||
|
||||
### 3. Verified `playwright.website.config.ts`
|
||||
- Already correctly configured for Docker
|
||||
- Uses `http://localhost:3100` when `DOCKER_SMOKE=true`
|
||||
- Proper timeout and retry settings
|
||||
|
||||
## Key Configuration Changes
|
||||
|
||||
### Environment Variables
|
||||
- `API_BASE_URL=http://api:3000` (internal Docker network)
|
||||
- `NEXT_PUBLIC_API_BASE_URL=http://localhost:3101` (external for browser)
|
||||
- `DOCKER_SMOKE=true` (tells tests to use Docker ports)
|
||||
|
||||
### Cookie Settings
|
||||
- Added `Domain=localhost` to all Set-Cookie headers
|
||||
- Ensures cookies work across localhost:3100 and localhost:3101
|
||||
|
||||
### Service Dependencies
|
||||
- deps → api → website (proper startup order)
|
||||
- Health checks ensure services are ready before dependent services start
|
||||
|
||||
## Testing the Fixes
|
||||
|
||||
### Quick Test
|
||||
```bash
|
||||
# Start services
|
||||
docker-compose -f docker-compose.test.yml up -d
|
||||
|
||||
# Wait for startup
|
||||
sleep 30
|
||||
|
||||
# Run tests
|
||||
DOCKER_SMOKE=true npx playwright test --config=playwright.website.config.ts
|
||||
```
|
||||
|
||||
### Verification Steps
|
||||
1. Check deps container starts immediately
|
||||
2. API container waits for deps and becomes healthy
|
||||
3. Website container waits for both deps and API
|
||||
4. Cookies are set with proper domain
|
||||
5. Tests can access both website and API
|
||||
|
||||
## Expected Results
|
||||
- All 93 tests should pass
|
||||
- No "next: not found" errors
|
||||
- No connection refused errors
|
||||
- Auth sessions work properly in Docker
|
||||
- Cookie-based authentication flows correctly
|
||||
|
||||
## Files Modified
|
||||
1. `docker-compose.test.yml` - Service dependencies and startup logic
|
||||
2. `testing/mock-api-server.cjs` - Cookie domain settings
|
||||
3. `test-docker-fix.sh` - Verification script (new)
|
||||
|
||||
## Notes
|
||||
- The fixes address the core infrastructure issues that were causing auth/session failures
|
||||
- The mock API now properly simulates real authentication flows
|
||||
- Docker networking is properly configured for cross-container communication
|
||||
@@ -1,175 +0,0 @@
|
||||
# Docker Setup Analysis & Verification
|
||||
|
||||
## Summary
|
||||
I have thoroughly analyzed and tested the Docker setup for both development and production environments. Here's what I found:
|
||||
|
||||
## ✅ Development Setup - WORKING PERFECTLY
|
||||
|
||||
### Status: **OPERATIONAL**
|
||||
- **API Service**: Running on port 3000 (with debug on 9229)
|
||||
- **Website Service**: Running on port 3001
|
||||
- **Database Service**: PostgreSQL 15-alpine on port 5432
|
||||
- **Hot Reloading**: Enabled via volume mounts
|
||||
- **Health Checks**: All services healthy
|
||||
|
||||
### Commands:
|
||||
```bash
|
||||
# Start development
|
||||
npm run docker:dev:build
|
||||
|
||||
# View logs
|
||||
npm run docker:dev:logs
|
||||
|
||||
# Stop services
|
||||
npm run docker:dev:down
|
||||
|
||||
# Clean everything
|
||||
npm run docker:dev:clean
|
||||
```
|
||||
|
||||
### Architecture:
|
||||
- **API**: NestJS with TypeScript, hot-reload enabled
|
||||
- **Website**: Next.js with hot-reload enabled
|
||||
- **Database**: PostgreSQL with persistent volume
|
||||
- **Network**: Custom bridge network (gridpilot-network)
|
||||
|
||||
## ⚠️ Production Setup - NEEDS ATTENTION
|
||||
|
||||
### Status: **CONFIGURATION COMPLETE, BUILD PENDING**
|
||||
|
||||
### Issues Found & Fixed:
|
||||
|
||||
#### 1. **Missing .env.production.example** ✅ FIXED
|
||||
- **Issue**: No example file for production environment variables
|
||||
- **Solution**: Created `.env.production.example` with all required variables
|
||||
- **Action Required**: Copy to `.env.production` and update with real credentials
|
||||
|
||||
#### 2. **SSL Directory Missing** ✅ FIXED
|
||||
- **Issue**: `nginx/ssl/` directory referenced but didn't exist
|
||||
- **Solution**: Created empty directory for future SSL certificates
|
||||
- **Note**: HTTPS server is commented out in nginx config for local testing
|
||||
|
||||
#### 3. **Environment Variables** ✅ FIXED
|
||||
- **Issue**: Production env file had placeholder values that could cause issues
|
||||
- **Solution**: Updated `.env.production` with safe defaults for local testing
|
||||
- **Action Required**: Update with real production credentials before deployment
|
||||
|
||||
#### 4. **Docker Build Resource Constraints** ⚠️ IDENTIFIED
|
||||
- **Issue**: Production builds are resource-intensive and may get killed
|
||||
- **Solution**: Build in stages or increase Docker resource limits
|
||||
- **Recommendation**: Use `docker-compose -f docker-compose.prod.yml build --no-cache` with adequate resources
|
||||
|
||||
### Production Architecture:
|
||||
- **API**: Multi-stage build, optimized production image
|
||||
- **Website**: Next.js production build with optimized dependencies
|
||||
- **Database**: PostgreSQL 15-alpine with performance tuning
|
||||
- **Redis**: Cache layer with LRU eviction and persistence
|
||||
- **Nginx**: Reverse proxy with rate limiting, security headers, caching
|
||||
|
||||
### Commands:
|
||||
```bash
|
||||
# Build production images (may need increased resources)
|
||||
npm run docker:prod:build
|
||||
|
||||
# Start production (detached)
|
||||
npm run docker:prod
|
||||
|
||||
# View logs
|
||||
npm run docker:prod:logs
|
||||
|
||||
# Stop services
|
||||
npm run docker:prod:down
|
||||
|
||||
# Clean everything
|
||||
npm run docker:prod:clean
|
||||
```
|
||||
|
||||
## 🔧 Files Created/Updated
|
||||
|
||||
### New Files:
|
||||
- `.env.production.example` - Production environment template
|
||||
- `nginx/ssl/` - Directory for SSL certificates
|
||||
- `DOCKER_SETUP_ANALYSIS.md` - This analysis document
|
||||
|
||||
### Updated Files:
|
||||
- `.env.production` - Fixed with safe defaults
|
||||
- `.dockerignore` - Enhanced to include production example
|
||||
|
||||
## 🚀 Deployment Checklist
|
||||
|
||||
Before deploying to production:
|
||||
|
||||
1. **Environment Variables**:
|
||||
```bash
|
||||
cp .env.production.example .env.production
|
||||
# Edit .env.production with real credentials
|
||||
```
|
||||
|
||||
2. **SSL Certificates** (for HTTPS):
|
||||
- Place certificates in `nginx/ssl/`
|
||||
- Uncomment HTTPS server block in `nginx/nginx.conf`
|
||||
- Update domain names in environment variables
|
||||
|
||||
3. **Database Credentials**:
|
||||
- Update `POSTGRES_PASSWORD` with strong password
|
||||
- Update `DATABASE_URL` with production database
|
||||
|
||||
4. **Redis Password**:
|
||||
- Update `REDIS_PASSWORD` with a strong password
|
||||
- No `REDIS_URL` is required (the Redis container is configured via `REDIS_PASSWORD` in `docker-compose.prod.yml`)
|
||||
|
||||
5. **Vercel KV** (if using):
|
||||
- Get credentials from Vercel dashboard
|
||||
- Update `KV_REST_API_URL` and `KV_REST_API_TOKEN`
|
||||
|
||||
6. **Domain Configuration**:
|
||||
- Update `NEXT_PUBLIC_SITE_URL` with your domain
|
||||
- Update `NEXT_PUBLIC_API_BASE_URL` with your public API base (often `https://your-domain.com/api` when nginx proxies `/api`)
|
||||
|
||||
7. **Build & Deploy**:
|
||||
```bash
|
||||
# Build with adequate resources
|
||||
docker-compose -f docker-compose.prod.yml build
|
||||
|
||||
# Start services
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# Verify health
|
||||
docker-compose -f docker-compose.prod.yml ps
|
||||
```
|
||||
|
||||
## 📊 Health Check Endpoints
|
||||
|
||||
### API Health:
|
||||
- **URL**: `http://localhost:3000/health` (dev) or `http://localhost/api/health` (prod)
|
||||
- **Response**: `{"status":"ok"}`
|
||||
|
||||
### Website Health:
|
||||
- **URL**: `http://localhost:3001` (dev) or `http://localhost` (prod)
|
||||
- **Response**: Next.js application running
|
||||
|
||||
### Nginx Health:
|
||||
- **URL**: `http://localhost/health`
|
||||
- **Response**: `healthy`
|
||||
|
||||
## 🎯 Key Improvements Made
|
||||
|
||||
1. **Documentation**: Created comprehensive environment example
|
||||
2. **Security**: Added SSL directory structure
|
||||
3. **Reliability**: Fixed environment variable placeholders
|
||||
4. **Maintainability**: Enhanced .dockerignore rules
|
||||
5. **Testing**: Verified both dev and prod configurations
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- **Development**: Fully operational and ready for use
|
||||
- **Production**: Configuration complete, ready for deployment with proper credentials
|
||||
- **Performance**: Production setup includes resource limits and health checks
|
||||
- **Security**: Nginx configured with rate limiting and security headers
|
||||
- **Scalability**: Ready for container orchestration (Kubernetes, etc.)
|
||||
|
||||
## 🎉 Conclusion
|
||||
|
||||
The Docker setup is **production-ready**! Both development and production configurations are properly set up. The development environment works perfectly, and the production environment is configured correctly - it just needs real credentials and adequate build resources.
|
||||
|
||||
**Next Steps**: Follow the deployment checklist above to deploy to production.
|
||||
@@ -62,16 +62,19 @@ Access:
|
||||
### Testing (Docker)
|
||||
The goal of Docker-backed tests is to catch *wiring* issues between Website ↔ API (wrong hostnames/ports/env vars, missing CORS for credentialed requests, etc.) in a deterministic environment.
|
||||
|
||||
- `npm run test:docker:website` - Start a dedicated test stack (ports `3100/3101`) and run Playwright smoke tests against it.
|
||||
- Uses [`docker-compose.test.yml`](docker-compose.test.yml:1).
|
||||
- Runs the Website in Docker and talks to an **API mock** container.
|
||||
- Validates that pages render and that core API fetches succeed (hostname + CORS + routing).
|
||||
- `npm run test:docker:website` - Start API/DB in Docker, run website locally via Playwright, and execute e2e tests.
|
||||
- Uses [`docker-compose.test.yml`](docker-compose.test.yml:1) for API and PostgreSQL.
|
||||
- Playwright starts the website locally via `webServer` config (not in Docker).
|
||||
- Tests run against `http://localhost:3000` (website) talking to `http://localhost:3101` (API).
|
||||
- Validates that pages render, middleware works, and API connections succeed.
|
||||
|
||||
**Important**: The website runs locally (not in Docker) to avoid Next.js SWC/compilation issues in containers.
|
||||
|
||||
Supporting scripts:
|
||||
- `npm run docker:test:deps` - Install monorepo deps inside a reusable Docker volume (one-shot).
|
||||
- `npm run docker:test:up` - Bring up the test stack.
|
||||
- `npm run docker:test:wait` - Wait for `http://localhost:3100` and `http://localhost:3101/health` to be ready.
|
||||
- `npm run docker:test:down` - Tear the test stack down (including volumes).
|
||||
- `npm run docker:test:deps` - Verify monorepo dependencies are installed.
|
||||
- `npm run docker:test:up` - Start API and PostgreSQL containers.
|
||||
- `npm run docker:test:wait` - Wait for API health check at `http://localhost:3101/health`.
|
||||
- `npm run docker:test:down` - Stop containers and clean up.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -117,16 +120,23 @@ The single source of truth for "what base URL should I use?" is [`getWebsiteApiB
|
||||
#### Test Docker defaults (docker-compose.test.yml)
|
||||
This stack is intended for deterministic smoke tests and uses different host ports to avoid colliding with `docker:dev`:
|
||||
|
||||
- Website: `http://localhost:3100`
|
||||
- API mock: `http://localhost:3101` (maps to container `api:3000`)
|
||||
- Website: `http://localhost:3000` (started by Playwright webServer, not Docker)
|
||||
- API: `http://localhost:3101` (maps to container `api:3000`)
|
||||
- PostgreSQL: `localhost:5433` (maps to container `5432`)
|
||||
- `NEXT_PUBLIC_API_BASE_URL=http://localhost:3101` (browser → host port)
|
||||
- `API_BASE_URL=http://api:3000` (website container → api container)
|
||||
- `API_BASE_URL=http://localhost:3101` (Playwright webServer → host port)
|
||||
|
||||
Important: the test stack's API is a mock server defined inline in [`docker-compose.test.yml`](docker-compose.test.yml:24). It exists to validate Website ↔ API wiring, not domain correctness.
|
||||
**Important**:
|
||||
- The website runs locally via Playwright's `webServer` config to avoid Next.js SWC compilation issues in Docker.
|
||||
- The API is a real TypeORM/PostgreSQL server (not a mock) for testing actual database interactions.
|
||||
- Playwright automatically starts the website server before running tests.
|
||||
|
||||
#### Troubleshooting
|
||||
- If `docker:dev` is running, use `npm run docker:dev:down` before `npm run test:docker:website` to avoid port conflicts.
|
||||
- If Docker volumes get stuck, run `npm run docker:test:down` (it uses `--remove-orphans` + `rm -f`).
|
||||
- **Port conflicts**: If `docker:dev` is running, use `npm run docker:dev:down` before `npm run test:docker:website` to avoid port conflicts (dev uses 3001, test uses 3101).
|
||||
- **Website not starting**: Playwright's webServer may fail if dependencies are missing. Run `npm install` first.
|
||||
- **Cookie errors**: The `WebsiteAuthManager` requires both `url` and `path` properties for cookies. Check Playwright version compatibility.
|
||||
- **Docker volumes stuck**: Run `npm run docker:test:down` (uses `--remove-orphans` + `rm -f`).
|
||||
- **SWC compilation issues**: If website fails to start in Docker, use the local webServer approach (already configured in `playwright.website.config.ts`).
|
||||
|
||||
### API "Real vs In-Memory" Mode
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
#HttpOnly_localhost FALSE / FALSE 1767404531 gp_session gp_6b1738c6-8a80-407d-b934-b14fb9834ba1
|
||||
119
split.js
119
split.js
@@ -1,119 +0,0 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const filePath = 'apps/api/src/domain/league/dtos/LeagueDto.ts';
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const lines = content.split('\n');
|
||||
|
||||
let allImports = lines.filter(line => line.startsWith('import '));
|
||||
|
||||
let classBlocks = [];
|
||||
let currentClassLines = [];
|
||||
let inClass = false;
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let line = lines[i];
|
||||
if (line.startsWith('export class ')) {
|
||||
if (inClass) {
|
||||
classBlocks.push(currentClassLines);
|
||||
currentClassLines = [];
|
||||
}
|
||||
inClass = true;
|
||||
}
|
||||
if (inClass) {
|
||||
currentClassLines.push(line);
|
||||
if (line.trim() === '}') {
|
||||
classBlocks.push(currentClassLines);
|
||||
currentClassLines = [];
|
||||
inClass = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentClassLines.length > 0) {
|
||||
classBlocks.push(currentClassLines);
|
||||
}
|
||||
|
||||
// Function to get imports for class
|
||||
function getImportsForClass(classLines, className) {
|
||||
let classContent = classLines.join('\n');
|
||||
let neededImports = [];
|
||||
|
||||
// ApiProperty
|
||||
if (classContent.includes('@ApiProperty')) {
|
||||
neededImports.push("import { ApiProperty } from '@nestjs/swagger';");
|
||||
}
|
||||
|
||||
// class-validator
|
||||
let validators = [];
|
||||
if (classContent.includes('@IsString')) validators.push('IsString');
|
||||
if (classContent.includes('@IsNumber')) validators.push('IsNumber');
|
||||
if (classContent.includes('@IsBoolean')) validators.push('IsBoolean');
|
||||
if (classContent.includes('@IsDate')) validators.push('IsDate');
|
||||
if (classContent.includes('@IsOptional')) validators.push('IsOptional');
|
||||
if (classContent.includes('@IsEnum')) validators.push('IsEnum');
|
||||
if (classContent.includes('@IsArray')) validators.push('IsArray');
|
||||
if (classContent.includes('@ValidateNested')) validators.push('ValidateNested');
|
||||
if (validators.length > 0) {
|
||||
neededImports.push(`import { ${validators.join(', ')} } from 'class-validator';`);
|
||||
}
|
||||
|
||||
// class-transformer
|
||||
if (classContent.includes('@Type')) {
|
||||
neededImports.push("import { Type } from 'class-transformer';");
|
||||
}
|
||||
|
||||
// Other DTOs
|
||||
if (classContent.includes('DriverDto')) {
|
||||
neededImports.push("import { DriverDto } from '../../driver/dto/DriverDto';");
|
||||
}
|
||||
if (classContent.includes('RaceDto')) {
|
||||
neededImports.push("import { RaceDto } from '../../race/dto/RaceDto';");
|
||||
}
|
||||
|
||||
// Local DTOs
|
||||
let localDTOs = ['LeagueSettingsDTO', 'LeagueWithCapacityDTO', 'LeagueSummaryDTO', 'AllLeaguesWithCapacityDTO', 'AllLeaguesWithCapacityAndScoringDTO', 'LeagueStatsDTO', 'ProtestDTO', 'SeasonDTO', 'LeagueJoinRequestDTO', 'GetLeagueJoinRequestsQueryDTO', 'ApproveJoinRequestInputDTO', 'ApproveJoinRequestOutputDTO', 'RejectJoinRequestInputDTO', 'RejectJoinRequestOutputDTO', 'GetLeagueAdminPermissionsInputDTO', 'LeagueAdminPermissionsDTO', 'RemoveLeagueMemberInputDTO', 'RemoveLeagueMemberOutputDTO', 'UpdateLeagueMemberRoleInputDTO', 'UpdateLeagueMemberRoleOutputDTO', 'GetLeagueOwnerSummaryQueryDTO', 'LeagueOwnerSummaryDTO', 'LeagueConfigFormModelBasicsDTO', 'LeagueConfigFormModelStructureDTO', 'LeagueConfigFormModelScoringDTO', 'LeagueConfigFormModelDropPolicyDTO', 'LeagueConfigFormModelStewardingDTO', 'LeagueConfigFormModelTimingsDTO', 'LeagueConfigFormModelDTO', 'GetLeagueAdminConfigQueryDTO', 'GetLeagueAdminConfigOutputDTO', 'LeagueAdminConfigDTO', 'GetLeagueProtestsQueryDTO', 'LeagueAdminProtestsDTO', 'GetLeagueSeasonsQueryDTO', 'LeagueSeasonSummaryDTO', 'LeagueAdminDTO', 'LeagueMemberDTO', 'LeagueMembershipsDTO', 'LeagueStandingDTO', 'LeagueStandingsDTO', 'LeagueScheduleDTO', 'LeagueStatsDTO', 'CreateLeagueInputDTO', 'CreateLeagueOutputDTO'];
|
||||
|
||||
for (let dto of localDTOs) {
|
||||
if (dto !== className && classContent.includes(dto)) {
|
||||
neededImports.push(`import { ${dto} } from './${dto}';`);
|
||||
}
|
||||
}
|
||||
|
||||
return neededImports;
|
||||
}
|
||||
|
||||
for (let classLines of classBlocks) {
|
||||
let classNameLine = classLines.find(line => line.startsWith('export class '));
|
||||
if (classNameLine) {
|
||||
let match = classNameLine.match(/export class (\w+)/);
|
||||
if (match) {
|
||||
let className = match[1];
|
||||
// Rename
|
||||
if (className.endsWith('ViewModel')) {
|
||||
className = className.replace('ViewModel', 'DTO');
|
||||
} else if (className.endsWith('Dto')) {
|
||||
className = className.replace('Dto', 'DTO');
|
||||
} else if (className.endsWith('Input')) {
|
||||
className = className + 'DTO';
|
||||
} else if (className.endsWith('Output')) {
|
||||
className = className + 'DTO';
|
||||
} else if (className.endsWith('Query')) {
|
||||
className = className + 'DTO';
|
||||
} else {
|
||||
className = className + 'DTO';
|
||||
}
|
||||
let fileName = className + '.ts';
|
||||
// Update class name in lines
|
||||
classLines[0] = classLines[0].replace(/export class \w+/, 'export class ' + className);
|
||||
// Update references in the class
|
||||
for (let i = 1; i < classLines.length; i++) {
|
||||
classLines[i] = classLines[i].replace(/ViewModel/g, 'DTO').replace(/Dto/g, 'DTO').replace(/Input\b/g, 'InputDTO').replace(/Output\b/g, 'OutputDTO').replace(/Query\b/g, 'QueryDTO');
|
||||
classLines[i] = classLines[i].replace(/DriverDTO/g, 'DriverDto').replace(/RaceDTO/g, 'RaceDto');
|
||||
}
|
||||
let imports = getImportsForClass(classLines, className);
|
||||
let fileContent = imports.join('\n') + '\n\n' + classLines.join('\n');
|
||||
fs.writeFileSync(path.join('apps/api/src/domain/league/dtos', fileName), fileContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test API signup endpoint
|
||||
|
||||
echo "Testing API signup endpoint..."
|
||||
echo ""
|
||||
|
||||
# Test 1: Check if API is reachable
|
||||
echo "1. Checking if API is reachable..."
|
||||
curl -s -o /dev/null -w "HTTP Status: %{http_code}\n" http://localhost:3001/health || echo "Health endpoint not found"
|
||||
|
||||
echo ""
|
||||
|
||||
# Test 2: Try signup with correct data
|
||||
echo "2. Attempting signup with correct data..."
|
||||
curl -X POST http://localhost:3001/auth/signup \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"email": "testuser@example.com",
|
||||
"password": "TestPass123",
|
||||
"displayName": "Test User"
|
||||
}' \
|
||||
-w "\nHTTP Status: %{http_code}\n" \
|
||||
-s
|
||||
|
||||
echo ""
|
||||
|
||||
# Test 3: Try signup with extra fields (should fail with whitelist error)
|
||||
echo "3. Attempting signup with extra fields (should fail)..."
|
||||
curl -X POST http://localhost:3001/auth/signup \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"email": "testuser2@example.com",
|
||||
"password": "TestPass123",
|
||||
"displayName": "Test User 2",
|
||||
"extraField": "should not exist"
|
||||
}' \
|
||||
-w "\nHTTP Status: %{http_code}\n" \
|
||||
-s
|
||||
|
||||
echo ""
|
||||
echo "Done."
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test script to verify docker auth/session fixes
|
||||
|
||||
echo "=== Testing Docker Auth/Session Fixes ==="
|
||||
|
||||
# Clean up any existing containers
|
||||
echo "1. Cleaning up existing containers..."
|
||||
docker-compose -f docker-compose.test.yml down -v 2>/dev/null || true
|
||||
|
||||
# Start services
|
||||
echo "2. Starting services..."
|
||||
docker-compose -f docker-compose.test.yml up -d
|
||||
|
||||
# Wait for services to be ready
|
||||
echo "3. Waiting for services to be ready..."
|
||||
sleep 30
|
||||
|
||||
# Check service status
|
||||
echo "4. Checking service status..."
|
||||
docker-compose -f docker-compose.test.yml ps
|
||||
|
||||
# Check website logs for any errors
|
||||
echo "5. Checking website logs..."
|
||||
docker-compose -f docker-compose.test.yml logs --tail=10 website
|
||||
|
||||
# Check API health
|
||||
echo "6. Testing API health..."
|
||||
curl -f http://localhost:3101/health && echo " ✓ API is healthy" || echo " ✗ API health check failed"
|
||||
|
||||
# Test website accessibility
|
||||
echo "7. Testing website accessibility..."
|
||||
curl -f http://localhost:3100/ && echo " ✓ Website is accessible" || echo " ✗ Website accessibility failed"
|
||||
|
||||
echo ""
|
||||
echo "=== Setup Complete ==="
|
||||
echo "To run tests: DOCKER_SMOKE=true npx playwright test --config=playwright.website.config.ts"
|
||||
echo "To stop: docker-compose -f docker-compose.test.yml down"
|
||||
@@ -1,89 +0,0 @@
|
||||
# Fix Verification for Team Logo Issue
|
||||
|
||||
## Problem Summary
|
||||
- **Issue**: Teams with stale `logoRef` values (`system-default/logo`) persist across force reseeds
|
||||
- **Root Cause**: `clearExistingRacingData()` didn't clear `racing_teams` table
|
||||
- **Impact**: API returns `/media/default/logo.png` instead of `/media/teams/{id}/logo`
|
||||
|
||||
## Fix Applied
|
||||
Updated `adapters/bootstrap/SeedRacingData.ts` `clearExistingRacingData()` method to:
|
||||
|
||||
1. **Clear team join requests** - Before deleting teams
|
||||
2. **Clear team memberships** - Before deleting teams
|
||||
3. **Clear teams** - The critical fix (teams have stale logoRef)
|
||||
4. **Clear related racing data** - Results, standings, races, etc.
|
||||
|
||||
## Key Changes
|
||||
```typescript
|
||||
// Before (incomplete):
|
||||
private async clearExistingRacingData(): Promise<void> {
|
||||
// Only cleared drivers and leagues
|
||||
// Missing: teams, team_memberships, team_join_requests
|
||||
}
|
||||
|
||||
// After (complete):
|
||||
private async clearExistingRacingData(): Promise<void> {
|
||||
// Clear stats
|
||||
await this.seedDeps.driverStatsRepository.clear();
|
||||
await this.seedDeps.teamStatsRepository.clear();
|
||||
|
||||
// Clear race registrations
|
||||
const races = await this.seedDeps.raceRepository.findAll();
|
||||
for (const race of races) {
|
||||
await this.seedDeps.raceRegistrationRepository.clearRaceRegistrations(race.id.toString());
|
||||
}
|
||||
|
||||
// Clear team join requests
|
||||
const teams = await this.seedDeps.teamRepository.findAll();
|
||||
for (const team of teams) {
|
||||
const joinRequests = await this.seedDeps.teamMembershipRepository.getJoinRequests(team.id.toString());
|
||||
for (const request of joinRequests) {
|
||||
await this.seedDeps.teamMembershipRepository.removeJoinRequest(request.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear team memberships
|
||||
for (const team of teams) {
|
||||
const memberships = await this.seedDeps.teamMembershipRepository.getTeamMembers(team.id.toString());
|
||||
for (const membership of memberships) {
|
||||
await this.seedDeps.teamMembershipRepository.removeMembership(team.id.toString(), membership.driverId.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Clear teams (CRITICAL FIX)
|
||||
for (const team of teams) {
|
||||
await this.seedDeps.teamRepository.delete(team.id.toString());
|
||||
}
|
||||
|
||||
// Clear other racing data...
|
||||
// Results, standings, races, league memberships, etc.
|
||||
}
|
||||
```
|
||||
|
||||
## Expected Behavior After Fix
|
||||
|
||||
### Before Fix:
|
||||
1. Start dev with `GRIDPILOT_API_FORCE_RESEED=1`
|
||||
2. Teams from previous seed remain with `logoRef: {"type":"system-default","variant":"logo"}`
|
||||
3. `GET /teams/all` returns `"logoUrl": "/media/default/logo.png"`
|
||||
|
||||
### After Fix:
|
||||
1. Start dev with `GRIDPILOT_API_FORCE_RESEED=1`
|
||||
2. All racing data cleared including teams
|
||||
3. New teams seeded with `logoRef: MediaReference.generated('team', teamId)`
|
||||
4. `GET /teams/all` returns `"logoUrl": "/media/teams/{id}/logo"`
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. **Start with existing data**: Run API with force reseed enabled
|
||||
2. **Check database**: Verify `racing_teams` table is cleared
|
||||
3. **Verify new data**: Teams should have generated logoRef
|
||||
4. **Test API**: `/teams/all` should return correct logo URLs
|
||||
|
||||
## Files Modified
|
||||
- `adapters/bootstrap/SeedRacingData.ts` - Enhanced `clearExistingRacingData()` method
|
||||
|
||||
## Related Code
|
||||
- `RacingTeamFactory.createTeams()` - Sets `logoRef: MediaReference.generated('team', teamId)`
|
||||
- `AllTeamsPresenter.present()` - Derives `logoUrl` from `logoRef`
|
||||
- `MediaController.debugResolve()` - Validates media resolution
|
||||
@@ -33,11 +33,12 @@ export class WebsiteAuthManager {
|
||||
const token = await WebsiteAuthManager.loginViaApi(request, apiBaseUrl, role);
|
||||
|
||||
// Critical: the website (localhost:3000) must receive `gp_session` so middleware can forward it.
|
||||
// Playwright cookie format - either url OR domain+path
|
||||
await context.addCookies([
|
||||
{
|
||||
name: 'gp_session',
|
||||
value: token,
|
||||
url: baseURL,
|
||||
domain: 'localhost',
|
||||
path: '/',
|
||||
httpOnly: true,
|
||||
sameSite: 'Lax',
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
# Type Inventory & Classification
|
||||
|
||||
This document catalogs all types from the monolithic `apps/website/lib/apiClient.ts` file (lines 13-634) and inline DTOs from `apps/website/app/races/[id]/results/page.tsx` (lines 17-56). Types are organized by domain and classified according to Clean Architecture principles.
|
||||
|
||||
## Summary
|
||||
- **Total Types**: 89 types in apiClient.ts + 5 inline DTOs = 94 types
|
||||
- **Domains**: Common/Shared, League, Driver, Team, Race, Sponsor, Media, Analytics, Auth, Payments
|
||||
- **Classification Breakdown**:
|
||||
- DTO: 45 (pure transport objects, no business logic)
|
||||
- ViewModel: 44 (UI-ready with potential computed properties)
|
||||
- Input: 3 (request parameters)
|
||||
- Output: 2 (response wrappers)
|
||||
|
||||
## Extraction Strategy Overview
|
||||
- **DTOs**: Move to `apps/website/lib/dtos/{domain}/` with filename `{TypeName}.ts`
|
||||
- **ViewModels**: Move to `apps/website/lib/view-models/{domain}/` with filename `{TypeName}.ts`
|
||||
- **Inputs/Outputs**: Treat as DTOs in appropriate domain
|
||||
- **Dependencies**: Update imports after extraction
|
||||
- **No Empty Files**: Ensure each extracted file has content
|
||||
- **Clean Architecture**: Maintain separation between transport (DTO) and presentation (ViewModel) layers
|
||||
|
||||
---
|
||||
|
||||
## Common/Shared Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| DriverDTO | 13-19 | DTO | `apps/website/lib/dtos/common/DriverDto.ts` | None | LeagueAdminPresenter.ts, TeamAdminPresenter.ts, presenters (multiple) |
|
||||
| ProtestViewModel | 21-29 | ViewModel | `apps/website/lib/view-models/common/ProtestViewModel.ts` | None | LeagueAdminProtestsDto.ts |
|
||||
| LeagueMemberViewModel | 31-36 | ViewModel | `apps/website/lib/view-models/league/LeagueMemberViewModel.ts` | DriverDTO | LeagueMembershipsDto.ts, LeagueAdminDto.ts, leagueMembership.ts |
|
||||
| StandingEntryViewModel | 38-46 | ViewModel | `apps/website/lib/view-models/league/StandingEntryViewModel.ts` | DriverDTO | LeagueStandingsDto.ts, LeagueStandingsPresenter.ts |
|
||||
| ScheduledRaceViewModel | 48-54 | ViewModel | `apps/website/lib/view-models/race/ScheduledRaceViewModel.ts` | None | LeagueScheduleDto.ts |
|
||||
|
||||
---
|
||||
|
||||
## League Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| LeagueSummaryViewModel | 57-70 | ViewModel | `apps/website/lib/view-models/league/LeagueSummaryViewModel.ts` | None | AllLeaguesWithCapacityAndScoringPresenter.ts |
|
||||
| AllLeaguesWithCapacityViewModel | 72-74 | ViewModel | `apps/website/lib/view-models/league/AllLeaguesWithCapacityViewModel.ts` | LeagueSummaryViewModel | ScheduleRaceFormPresenter.ts, AllLeaguesWithCapacityAndScoringPresenter.ts |
|
||||
| LeagueStatsDto | 76-79 | DTO | `apps/website/lib/dtos/league/LeagueStatsDto.ts` | None | None found |
|
||||
| LeagueJoinRequestViewModel | 80-86 | ViewModel | `apps/website/lib/view-models/league/LeagueJoinRequestViewModel.ts` | None | LeagueAdminDto.ts, LeagueAdminPresenter.ts |
|
||||
| LeagueAdminPermissionsViewModel | 88-95 | ViewModel | `apps/website/lib/view-models/league/LeagueAdminPermissionsViewModel.ts` | None | LeagueAdminPermissionsDto.ts (existing), LeagueAdminPresenter.ts |
|
||||
| LeagueOwnerSummaryViewModel | 97-102 | ViewModel | `apps/website/lib/view-models/league/LeagueOwnerSummaryViewModel.ts` | None | LeagueAdminPresenter.ts |
|
||||
| LeagueConfigFormModelDto | 104-111 | DTO | `apps/website/lib/dtos/league/LeagueConfigFormModelDto.ts` | None | LeagueAdminDto.ts |
|
||||
| LeagueAdminProtestsViewModel | 113-115 | ViewModel | `apps/website/lib/view-models/league/LeagueAdminProtestsViewModel.ts` | ProtestViewModel | LeagueAdminProtestsDto.ts, LeagueAdminPresenter.ts |
|
||||
| LeagueSeasonSummaryViewModel | 117-123 | ViewModel | `apps/website/lib/view-models/league/LeagueSeasonSummaryViewModel.ts` | None | LeagueAdminPresenter.ts |
|
||||
| LeagueMembershipsViewModel | 125-127 | ViewModel | `apps/website/lib/view-models/league/LeagueMembershipsViewModel.ts` | LeagueMemberViewModel | LeagueMembershipsDto.ts, leagueMembership.ts |
|
||||
| LeagueStandingsViewModel | 129-131 | ViewModel | `apps/website/lib/view-models/league/LeagueStandingsViewModel.ts` | StandingEntryViewModel | LeagueStandingsPresenter.ts, TeamStandingsPresenter.ts |
|
||||
| LeagueScheduleViewModel | 133-135 | ViewModel | `apps/website/lib/view-models/league/LeagueScheduleViewModel.ts` | ScheduledRaceViewModel | LeagueScheduleDto.ts |
|
||||
| LeagueStatsViewModel | 137-145 | ViewModel | `apps/website/lib/view-models/league/LeagueStatsViewModel.ts` | None | None found |
|
||||
| LeagueAdminViewModel | 147-151 | ViewModel | `apps/website/lib/view-models/league/LeagueAdminViewModel.ts` | LeagueConfigFormModelDto, LeagueMemberViewModel, LeagueJoinRequestViewModel | None found |
|
||||
| CreateLeagueInput | 153-159 | Input | `apps/website/lib/dtos/league/CreateLeagueInput.ts` | None | leagueWizardService.ts |
|
||||
| CreateLeagueOutput | 161-164 | Output | `apps/website/lib/dtos/league/CreateLeagueOutput.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Driver Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| DriverLeaderboardItemViewModel | 167-175 | ViewModel | `apps/website/lib/view-models/driver/DriverLeaderboardItemViewModel.ts` | None | DriversLeaderboardPresenter.ts |
|
||||
| DriversLeaderboardViewModel | 177-179 | ViewModel | `apps/website/lib/view-models/driver/DriversLeaderboardViewModel.ts` | DriverLeaderboardItemViewModel | DriversLeaderboardPresenter.ts |
|
||||
| DriverStatsDto | 181-183 | DTO | `apps/website/lib/dtos/driver/DriverStatsDto.ts` | None | None found |
|
||||
| CompleteOnboardingInput | 185-188 | Input | `apps/website/lib/dtos/driver/CompleteOnboardingInput.ts` | None | None found |
|
||||
| CompleteOnboardingOutput | 190-193 | Output | `apps/website/lib/dtos/driver/CompleteOnboardingOutput.ts` | None | None found |
|
||||
| DriverRegistrationStatusViewModel | 195-199 | ViewModel | `apps/website/lib/view-models/driver/DriverRegistrationStatusViewModel.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Team Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| TeamSummaryViewModel | 202-208 | ViewModel | `apps/website/lib/view-models/team/TeamSummaryViewModel.ts` | None | AllTeamsPresenter.ts |
|
||||
| AllTeamsViewModel | 210-212 | ViewModel | `apps/website/lib/view-models/team/AllTeamsViewModel.ts` | TeamSummaryViewModel | AllTeamsPresenter.ts |
|
||||
| TeamMemberViewModel | 214-219 | ViewModel | `apps/website/lib/view-models/team/TeamMemberViewModel.ts` | DriverDTO | TeamDetailsPresenter.ts, TeamRosterPresenter.ts |
|
||||
| TeamJoinRequestItemViewModel | 221-227 | ViewModel | `apps/website/lib/view-models/team/TeamJoinRequestItemViewModel.ts` | None | TeamAdminPresenter.ts |
|
||||
| TeamDetailsViewModel | 229-237 | ViewModel | `apps/website/lib/view-models/team/TeamDetailsViewModel.ts` | TeamMemberViewModel | TeamDetailsPresenter.ts |
|
||||
| TeamMembersViewModel | 239-241 | ViewModel | `apps/website/lib/view-models/team/TeamMembersViewModel.ts` | TeamMemberViewModel | TeamRosterPresenter.ts |
|
||||
| TeamJoinRequestsViewModel | 243-245 | ViewModel | `apps/website/lib/view-models/team/TeamJoinRequestsViewModel.ts` | TeamJoinRequestItemViewModel | None found |
|
||||
| DriverTeamViewModel | 247-252 | ViewModel | `apps/website/lib/view-models/team/DriverTeamViewModel.ts` | None | DriverTeamPresenter.ts |
|
||||
| CreateTeamInput | 254-258 | Input | `apps/website/lib/dtos/team/CreateTeamInput.ts` | None | None found |
|
||||
| CreateTeamOutput | 260-263 | Output | `apps/website/lib/dtos/team/CreateTeamOutput.ts` | None | None found |
|
||||
| UpdateTeamInput | 265-269 | Input | `apps/website/lib/dtos/team/UpdateTeamInput.ts` | None | TeamAdminPresenter.ts |
|
||||
| UpdateTeamOutput | 271-273 | Output | `apps/website/lib/dtos/team/UpdateTeamOutput.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Race Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| RaceListItemViewModel | 276-284 | ViewModel | `apps/website/lib/view-models/race/RaceListItemViewModel.ts` | None | None found |
|
||||
| AllRacesPageViewModel | 286-288 | ViewModel | `apps/website/lib/view-models/race/AllRacesPageViewModel.ts` | RaceListItemViewModel | None found |
|
||||
| RaceStatsDto | 290-292 | DTO | `apps/website/lib/dtos/race/RaceStatsDto.ts` | None | None found |
|
||||
| RaceDetailEntryViewModel | 295-302 | ViewModel | `apps/website/lib/view-models/race/RaceDetailEntryViewModel.ts` | None | None found |
|
||||
| RaceDetailUserResultViewModel | 304-313 | ViewModel | `apps/website/lib/view-models/race/RaceDetailUserResultViewModel.ts` | None | None found |
|
||||
| RaceDetailRaceViewModel | 315-326 | ViewModel | `apps/website/lib/view-models/race/RaceDetailRaceViewModel.ts` | None | None found |
|
||||
| RaceDetailLeagueViewModel | 328-336 | ViewModel | `apps/website/lib/view-models/race/RaceDetailLeagueViewModel.ts` | None | None found |
|
||||
| RaceDetailRegistrationViewModel | 338-341 | ViewModel | `apps/website/lib/view-models/race/RaceDetailRegistrationViewModel.ts` | None | None found |
|
||||
| RaceDetailViewModel | 343-350 | ViewModel | `apps/website/lib/view-models/race/RaceDetailViewModel.ts` | RaceDetailRaceViewModel, RaceDetailLeagueViewModel, RaceDetailEntryViewModel, RaceDetailRegistrationViewModel, RaceDetailUserResultViewModel | None found |
|
||||
| RacesPageDataRaceViewModel | 352-364 | ViewModel | `apps/website/lib/view-models/race/RacesPageDataRaceViewModel.ts` | None | races/page.tsx, races/all/page.tsx |
|
||||
| RacesPageDataViewModel | 366-368 | ViewModel | `apps/website/lib/view-models/race/RacesPageDataViewModel.ts` | RacesPageDataRaceViewModel | races/page.tsx, races/all/page.tsx |
|
||||
| RaceResultViewModel | 370-381 | ViewModel | `apps/website/lib/view-models/race/RaceResultViewModel.ts` | None | None found |
|
||||
| RaceResultsDetailViewModel | 383-387 | ViewModel | `apps/website/lib/view-models/race/RaceResultsDetailViewModel.ts` | RaceResultViewModel | races/[id]/results/page.tsx |
|
||||
| RaceWithSOFViewModel | 389-393 | ViewModel | `apps/website/lib/view-models/race/RaceWithSOFViewModel.ts` | None | races/[id]/results/page.tsx |
|
||||
| RaceProtestViewModel | 395-405 | ViewModel | `apps/website/lib/view-models/race/RaceProtestViewModel.ts` | None | None found |
|
||||
| RaceProtestsViewModel | 407-410 | ViewModel | `apps/website/lib/view-models/race/RaceProtestsViewModel.ts` | RaceProtestViewModel | races/[id]/stewarding/page.tsx |
|
||||
| RacePenaltyViewModel | 412-421 | ViewModel | `apps/website/lib/view-models/race/RacePenaltyViewModel.ts` | None | None found |
|
||||
| RacePenaltiesViewModel | 423-426 | ViewModel | `apps/website/lib/view-models/race/RacePenaltiesViewModel.ts` | RacePenaltyViewModel | races/[id]/stewarding/page.tsx |
|
||||
| RegisterForRaceParams | 428-431 | Input | `apps/website/lib/dtos/race/RegisterForRaceParams.ts` | None | None found |
|
||||
| WithdrawFromRaceParams | 433-435 | Input | `apps/website/lib/dtos/race/WithdrawFromRaceParams.ts` | None | None found |
|
||||
| ImportRaceResultsInput | 437-439 | Input | `apps/website/lib/dtos/race/ImportRaceResultsInput.ts` | None | None found |
|
||||
| ImportRaceResultsSummaryViewModel | 441-447 | ViewModel | `apps/website/lib/view-models/race/ImportRaceResultsSummaryViewModel.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Sponsor Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| GetEntitySponsorshipPricingResultDto | 450-454 | DTO | `apps/website/lib/dtos/sponsor/GetEntitySponsorshipPricingResultDto.ts` | None | None found |
|
||||
| SponsorViewModel | 456-462 | ViewModel | `apps/website/lib/view-models/sponsor/SponsorViewModel.ts` | None | None found |
|
||||
| GetSponsorsOutput | 463-465 | Output | `apps/website/lib/dtos/sponsor/GetSponsorsOutput.ts` | SponsorViewModel | None found |
|
||||
| CreateSponsorInput | 467-472 | Input | `apps/website/lib/dtos/sponsor/CreateSponsorInput.ts` | None | None found |
|
||||
| CreateSponsorOutput | 474-477 | Output | `apps/website/lib/dtos/sponsor/CreateSponsorOutput.ts` | None | None found |
|
||||
| SponsorDashboardDTO | 479-485 | DTO | `apps/website/lib/dtos/sponsor/SponsorDashboardDto.ts` | None | None found |
|
||||
| SponsorshipDetailViewModel | 487-497 | ViewModel | `apps/website/lib/view-models/sponsor/SponsorshipDetailViewModel.ts` | None | None found |
|
||||
| SponsorSponsorshipsDTO | 499-502 | DTO | `apps/website/lib/dtos/sponsor/SponsorSponsorshipsDto.ts` | SponsorshipDetailViewModel | None found |
|
||||
|
||||
---
|
||||
|
||||
## Media Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| RequestAvatarGenerationInput | 505-508 | Input | `apps/website/lib/dtos/media/RequestAvatarGenerationInput.ts` | None | None found |
|
||||
| RequestAvatarGenerationOutput | 510-514 | Output | `apps/website/lib/dtos/media/RequestAvatarGenerationOutput.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Analytics Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| RecordPageViewInput | 517-521 | Input | `apps/website/lib/dtos/analytics/RecordPageViewInput.ts` | None | None found |
|
||||
| RecordPageViewOutput | 523-525 | Output | `apps/website/lib/dtos/analytics/RecordPageViewOutput.ts` | None | None found |
|
||||
| RecordEngagementInput | 527-532 | Input | `apps/website/lib/dtos/analytics/RecordEngagementInput.ts` | None | None found |
|
||||
| RecordEngagementOutput | 534-536 | Output | `apps/website/lib/dtos/analytics/RecordEngagementOutput.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Auth Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| LoginParams | 539-542 | Input | `apps/website/lib/dtos/auth/LoginParams.ts` | None | None found |
|
||||
| SignupParams | 544-548 | Input | `apps/website/lib/dtos/auth/SignupParams.ts` | None | None found |
|
||||
| SessionData | 550-556 | DTO | `apps/website/lib/dtos/auth/SessionData.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Payments Domain Types
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| PaymentViewModel | 559-565 | ViewModel | `apps/website/lib/view-models/payments/PaymentViewModel.ts` | None | None found |
|
||||
| GetPaymentsOutput | 567-569 | Output | `apps/website/lib/dtos/payments/GetPaymentsOutput.ts` | PaymentViewModel | None found |
|
||||
| CreatePaymentInput | 571-577 | Input | `apps/website/lib/dtos/payments/CreatePaymentInput.ts` | None | None found |
|
||||
| CreatePaymentOutput | 579-582 | Output | `apps/website/lib/dtos/payments/CreatePaymentOutput.ts` | None | None found |
|
||||
| MembershipFeeViewModel | 584-589 | ViewModel | `apps/website/lib/view-models/payments/MembershipFeeViewModel.ts` | None | None found |
|
||||
| MemberPaymentViewModel | 591-596 | ViewModel | `apps/website/lib/view-models/payments/MemberPaymentViewModel.ts` | None | None found |
|
||||
| GetMembershipFeesOutput | 598-601 | Output | `apps/website/lib/dtos/payments/GetMembershipFeesOutput.ts` | MembershipFeeViewModel, MemberPaymentViewModel | None found |
|
||||
| PrizeViewModel | 603-609 | ViewModel | `apps/website/lib/view-models/payments/PrizeViewModel.ts` | None | None found |
|
||||
| GetPrizesOutput | 611-613 | Output | `apps/website/lib/dtos/payments/GetPrizesOutput.ts` | PrizeViewModel | None found |
|
||||
| WalletTransactionViewModel | 615-621 | ViewModel | `apps/website/lib/view-models/payments/WalletTransactionViewModel.ts` | None | None found |
|
||||
| WalletViewModel | 623-628 | ViewModel | `apps/website/lib/view-models/payments/WalletViewModel.ts` | WalletTransactionViewModel | None found |
|
||||
| GetWalletOutput | 630-632 | Output | `apps/website/lib/dtos/payments/GetWalletOutput.ts` | WalletViewModel | None found |
|
||||
|
||||
---
|
||||
|
||||
## Inline DTOs from Results Page
|
||||
|
||||
| Type Name | Line Range | Classification | Target Location | Dependencies | Used By |
|
||||
|-----------|------------|----------------|-----------------|--------------|---------|
|
||||
| PenaltyTypeDTO | 17-24 | DTO | `apps/website/lib/dtos/race/PenaltyTypeDto.ts` | None | PenaltyTypeDto.ts (existing file) |
|
||||
| PenaltyData | 26-30 | DTO | `apps/website/lib/dtos/race/PenaltyData.ts` | PenaltyTypeDTO | None found |
|
||||
| RaceResultRowDTO | 32-41 | DTO | `apps/website/lib/dtos/race/RaceResultRowDto.ts` | None | None found |
|
||||
| DriverRowDTO | 43-46 | DTO | `apps/website/lib/dtos/race/DriverRowDto.ts` | None | None found |
|
||||
| ImportResultRowDTO | 48-56 | DTO | `apps/website/lib/dtos/race/ImportResultRowDto.ts` | None | None found |
|
||||
|
||||
---
|
||||
|
||||
## Extraction Recommendations
|
||||
|
||||
1. **Create Directory Structure**:
|
||||
- `apps/website/lib/dtos/common/`
|
||||
- `apps/website/lib/dtos/league/`
|
||||
- `apps/website/lib/dtos/driver/`
|
||||
- `apps/website/lib/dtos/team/`
|
||||
- `apps/website/lib/dtos/race/`
|
||||
- `apps/website/lib/dtos/sponsor/`
|
||||
- `apps/website/lib/dtos/media/`
|
||||
- `apps/website/lib/dtos/analytics/`
|
||||
- `apps/website/lib/dtos/auth/`
|
||||
- `apps/website/lib/dtos/payments/`
|
||||
- `apps/website/lib/view-models/common/`
|
||||
- `apps/website/lib/view-models/league/`
|
||||
- `apps/website/lib/view-models/driver/`
|
||||
- `apps/website/lib/view-models/team/`
|
||||
- `apps/website/lib/view-models/race/`
|
||||
- `apps/website/lib/view-models/sponsor/`
|
||||
- `apps/website/lib/view-models/payments/`
|
||||
|
||||
2. **Move Types Sequentially**:
|
||||
- Start with types that have no dependencies
|
||||
- Update imports in apiClient.ts and dependent files
|
||||
- Test after each major domain extraction
|
||||
|
||||
3. **Update Existing DTOs**:
|
||||
- Some DTOs already exist (e.g., LeagueAdminPermissionsDto.ts)
|
||||
- Ensure consistency in naming and structure
|
||||
|
||||
4. **Clean Architecture Compliance**:
|
||||
- DTOs: Pure data transfer, no methods
|
||||
- ViewModels: May include computed properties for UI
|
||||
- Clear separation maintained
|
||||
|
||||
5. **Post-Extraction**:
|
||||
- Remove types from apiClient.ts
|
||||
- Update all import statements
|
||||
- Run tests to ensure no breaking changes
|
||||
Reference in New Issue
Block a user