# Contract Testing Documentation

## Overview

This document describes the contract testing strategy for ensuring compatibility between the API (`apps/api`) and the website (`apps/website`) in the GridPilot monorepo.

## Architecture

The contract testing system consists of several layers:

### 1. API Contract Validation
- **Location**: `apps/api/src/shared/testing/contractValidation.test.ts`
- **Purpose**: Validates that API DTOs are consistent and generate valid OpenAPI specs
- **Tests**:
  - OpenAPI spec integrity
  - DTO consistency
  - Type generation integrity
  - Contract compatibility

### 2. Type Generation
- **Scripts**: 
  - `npm run api:generate-spec` - Generates OpenAPI spec from DTOs
  - `npm run api:generate-types` - Generates TypeScript types for website
  - `npm run api:sync-types` - Runs both in sequence
- **Output**: `apps/website/lib/types/generated/`

### 3. Website Contract Consumption
- **Location**: `apps/website/lib/types/contractConsumption.test.ts`
- **Purpose**: Validates that website can properly consume generated types
- **Tests**:
  - Generated types availability
  - Type compatibility
  - Service integration
  - Error handling

### 4. Compatibility Verification
- **Location**: `scripts/contract-compatibility.ts`
- **Purpose**: Detects breaking changes between type versions
- **Features**:
  - Backup current types
  - Generate new types
  - Compare and detect changes
  - Report breaking changes

## Workflow

### Local Development

```bash
# Run full contract testing suite
npm run test:contracts

# Or run individual steps:
npm run test:api:contracts          # Validate API contracts
npm run api:generate-spec           # Generate OpenAPI spec
npm run api:generate-types          # Generate types
npm run test:contract:compatibility # Check compatibility
npm run website:type-check          # Verify website types
```

### CI/CD Pipeline

The GitHub Actions workflow (`.github/workflows/contract-testing.yml`) automatically:

1. **On Pull Requests**:
   - Runs all contract tests
   - Validates API contracts
   - Generates types
   - Checks for breaking changes
   - Verifies website type checking
   - Uploads generated types as artifacts
   - Comments results on PR

2. **On Main Branch Push**:
   - Runs all tests
   - Generates and commits updated types

## Breaking Change Detection

The system detects several types of changes:

### Breaking Changes (❌ Fails CI)
- **Property Removal**: Required properties removed from DTOs
- **Type Changes**: Property types changed (e.g., `string` → `number`)
- **Required Field Addition**: New required fields added to existing DTOs

### Non-Breaking Changes (⚠️ Warning)
- **Property Addition**: Optional properties added
- **New DTOs**: New DTO types added
- **Documentation Changes**: Description updates

### Removed Changes (❌ Fails CI)
- **DTO Removal**: Entire DTO types removed
- **Property Removal**: Optional properties removed

## Generated Types Structure

The generated types follow this pattern:

```typescript
/**
 * Auto-generated DTO from OpenAPI spec
 * This file is generated by scripts/generate-api-types.ts
 * Do not edit manually - regenerate using: npm run api:sync-types
 */

import type { RelatedDTO } from './RelatedDTO';

export interface MyDTO {
  id: string;
  name: string;
  optionalField?: string;
  related?: RelatedDTO;
}
```

## Testing Strategy

### API Layer Tests

```typescript
// apps/api/src/shared/testing/contractValidation.test.ts
describe('API Contract Validation', () => {
  it('should have valid OpenAPI spec', async () => {
    // Validates spec structure
  });
  
  it('should have no circular references', async () => {
    // Prevents infinite loops
  });
  
  it('should maintain backward compatibility', async () => {
    // Ensures critical DTOs exist
  });
});
```

### Website Layer Tests

```typescript
// apps/website/lib/types/contractConsumption.test.ts
describe('Website Contract Consumption', () => {
  it('should allow creating valid DTO objects', () => {
    // Type-safe object creation
  });
  
  it('should work with service layer patterns', () => {
    // Integration with services
  });
  
  it('should handle error cases', () => {
    // Error handling patterns
  });
});
```

## Integration Points

### Service Layer Integration

Services in the website can import and use generated types:

```typescript
import type { RequestAvatarGenerationInputDTO } from '@/lib/types/generated/RequestAvatarGenerationInputDTO';
import type { RequestAvatarGenerationOutputDTO } from '@/lib/types/generated/RequestAvatarGenerationOutputDTO';

class AvatarService {
  async generateAvatar(input: RequestAvatarGenerationInputDTO): Promise<RequestAvatarGenerationOutputDTO> {
    const response = await apiClient.post('/avatar/generate', input);
    return response.data; // Type-safe
  }
}
```

### View Model Integration

View models can transform DTOs for UI consumption:

```typescript
import type { RaceDTO } from '@/lib/types/generated/RaceDTO';

class RaceViewModel {
  constructor(private dto: RaceDTO) {}
  
  get displayDate(): string {
    return new Date(this.dto.startTime).toLocaleDateString();
  }
}
```

## Troubleshooting

### Common Issues

1. **Type Generation Fails**
   - Check that DTOs have proper `@ApiProperty` decorators
   - Verify OpenAPI spec is valid JSON
   - Ensure all referenced types exist

2. **Breaking Changes Detected**
   - Review the change report
   - Update website code to handle new types
   - Consider versioning strategy for major changes

3. **Website Type Errors**
   - Run `npm run api:sync-types` to regenerate
   - Check import paths in website code
   - Verify TypeScript configuration

### Debugging Steps

1. **Check OpenAPI Spec**:
   ```bash
   npm run api:generate-spec
   cat apps/api/openapi.json | jq '.components.schemas'
   ```

2. **Compare Generated Types**:
   ```bash
   # Backup current types
   cp -r apps/website/lib/types/generated /tmp/types-backup
   
   # Regenerate
   npm run api:generate-types
   
   # Compare
   diff -r /tmp/types-backup apps/website/lib/types/generated
   ```

3. **Run Individual Tests**:
   ```bash
   # API tests
   npm run test:api:contracts
   
   # Website type checking
   npm run website:type-check
   ```

## Best Practices

### For API Developers

1. **Always use `@ApiProperty` decorators** with proper types
2. **Mark optional fields explicitly** with `required: false`
3. **Use proper TypeScript types** (avoid `any`)
4. **Add descriptions** to DTO properties
5. **Test DTOs** with contract validation tests

### For Website Developers

1. **Import from generated types**, not manual types
2. **Use type assertions** when consuming API responses
3. **Handle optional fields** properly
4. **Run contract tests** before committing type changes
5. **Update view models** when DTOs change

### For CI/CD

1. **Run contract tests on every PR**
2. **Block merges on breaking changes**
3. **Generate types on main branch pushes**
4. **Upload artifacts for debugging**
5. **Comment results on PRs**

## Future Enhancements

- [ ] Add API versioning support
- [ ] Generate client SDKs from OpenAPI
- [ ] Add contract testing for WebSocket events
- [ ] Implement schema registry
- [ ] Add automated migration scripts for breaking changes