# 🚀 Next Steps - Getting Started with Development You've successfully completed Sprint 0! Here's what to do next. --- ## 🎯 Immediate Actions (Today) ### 1. Install Dependencies ```bash # From the root directory npm install ``` **Expected**: This will take 2-3 minutes. You may see some deprecation warnings (normal). **On Windows**: If you see `EISDIR` symlink errors, that's okay - dependencies are still installed. ### 2. Start Docker Services ```bash docker-compose up -d ``` **Expected**: PostgreSQL and Redis containers will start. **Verify**: ```bash docker-compose ps # You should see: # xpeditis-postgres - Up (healthy) # xpeditis-redis - Up (healthy) ``` ### 3. Setup Environment Files ```bash # Backend cp apps/backend/.env.example apps/backend/.env # Frontend cp apps/frontend/.env.example apps/frontend/.env ``` **Note**: Default values work for local development. No changes needed! ### 4. Start the Backend ```bash # Option 1: From root npm run backend:dev # Option 2: From backend directory cd apps/backend npm run dev ``` **Expected Output**: ``` ╔═══════════════════════════════════════╗ ║ 🚢 Xpeditis API Server Running ║ ║ API: http://localhost:4000/api/v1 ║ ║ Docs: http://localhost:4000/api/docs ║ ╚═══════════════════════════════════════╝ ``` **Verify**: Open http://localhost:4000/api/v1/health ### 5. Start the Frontend (New Terminal) ```bash # Option 1: From root npm run frontend:dev # Option 2: From frontend directory cd apps/frontend npm run dev ``` **Expected Output**: ``` ▲ Next.js 14.0.4 - Local: http://localhost:3000 ✓ Ready in 2.3s ``` **Verify**: Open http://localhost:3000 --- ## ✅ Verification Checklist Before proceeding to development, verify: - [ ] `npm install` completed successfully - [ ] Docker containers are running (check with `docker-compose ps`) - [ ] Backend starts without errors - [ ] Health endpoint returns 200 OK: http://localhost:4000/api/v1/health - [ ] Swagger docs accessible: http://localhost:4000/api/docs - [ ] Frontend loads: http://localhost:3000 - [ ] No TypeScript compilation errors **All green? You're ready to start Phase 1! 🎉** --- ## 📅 Phase 1 - Core Search & Carrier Integration (Next 6-8 weeks) ### Week 1-2: Domain Layer & Port Definitions **Your first tasks**: #### 1. Create Domain Entities Create these files in `apps/backend/src/domain/entities/`: ```typescript // organization.entity.ts export class Organization { constructor( public readonly id: string, public readonly name: string, public readonly type: 'FREIGHT_FORWARDER' | 'NVOCC' | 'DIRECT_SHIPPER', public readonly scac?: string, public readonly address?: Address, public readonly logoUrl?: string, ) {} } // user.entity.ts export class User { constructor( public readonly id: string, public readonly organizationId: string, public readonly email: Email, // Value Object public readonly role: UserRole, public readonly passwordHash: string, ) {} } // rate-quote.entity.ts export class RateQuote { constructor( public readonly id: string, public readonly origin: PortCode, // Value Object public readonly destination: PortCode, // Value Object public readonly carrierId: string, public readonly price: Money, // Value Object public readonly surcharges: Surcharge[], public readonly etd: Date, public readonly eta: Date, public readonly transitDays: number, public readonly route: RouteStop[], public readonly availability: number, ) {} } // More entities: Carrier, Port, Container, Booking ``` #### 2. Create Value Objects Create these files in `apps/backend/src/domain/value-objects/`: ```typescript // email.vo.ts export class Email { private constructor(private readonly value: string) { this.validate(value); } static create(value: string): Email { return new Email(value); } private validate(value: string): void { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(value)) { throw new InvalidEmailException(value); } } getValue(): string { return this.value; } } // port-code.vo.ts export class PortCode { private constructor(private readonly value: string) { this.validate(value); } static create(value: string): PortCode { return new PortCode(value.toUpperCase()); } private validate(value: string): void { // UN LOCODE format: 5 characters (CCCCC) if (!/^[A-Z]{5}$/.test(value)) { throw new InvalidPortCodeException(value); } } getValue(): string { return this.value; } } // More VOs: Money, ContainerType, BookingNumber, DateRange ``` #### 3. Define Ports **API Ports (domain/ports/in/)** - What the domain exposes: ```typescript // search-rates.port.ts export interface SearchRatesPort { execute(input: RateSearchInput): Promise; } export interface RateSearchInput { origin: PortCode; destination: PortCode; containerType: ContainerType; mode: 'FCL' | 'LCL'; departureDate: Date; weight?: number; volume?: number; hazmat: boolean; } ``` **SPI Ports (domain/ports/out/)** - What the domain needs: ```typescript // rate-quote.repository.ts export interface RateQuoteRepository { save(rateQuote: RateQuote): Promise; findById(id: string): Promise; findByRoute(origin: PortCode, destination: PortCode): Promise; } // carrier-connector.port.ts export interface CarrierConnectorPort { searchRates(input: RateSearchInput): Promise; checkAvailability(input: AvailabilityInput): Promise; } // cache.port.ts export interface CachePort { get(key: string): Promise; set(key: string, value: T, ttl: number): Promise; delete(key: string): Promise; } ``` #### 4. Write Domain Tests ```typescript // domain/services/rate-search.service.spec.ts describe('RateSearchService', () => { let service: RateSearchService; let mockCache: jest.Mocked; let mockConnectors: jest.Mocked[]; beforeEach(() => { mockCache = createMockCache(); mockConnectors = [createMockConnector('Maersk')]; service = new RateSearchService(mockCache, mockConnectors); }); it('should return cached rates if available', async () => { const input = createTestRateSearchInput(); const cachedRates = [createTestRateQuote()]; mockCache.get.mockResolvedValue(cachedRates); const result = await service.execute(input); expect(result).toEqual(cachedRates); expect(mockConnectors[0].searchRates).not.toHaveBeenCalled(); }); it('should query carriers if cache miss', async () => { const input = createTestRateSearchInput(); mockCache.get.mockResolvedValue(null); const carrierRates = [createTestRateQuote()]; mockConnectors[0].searchRates.mockResolvedValue(carrierRates); const result = await service.execute(input); expect(result).toEqual(carrierRates); expect(mockCache.set).toHaveBeenCalledWith( expect.any(String), carrierRates, 900, // 15 minutes ); }); // Target: 90%+ coverage for domain }); ``` --- ## 📚 Recommended Reading Order Before starting development, read these in order: 1. **[QUICK-START.md](QUICK-START.md)** (5 min) - Get everything running 2. **[CLAUDE.md](CLAUDE.md)** (30 min) - Understand hexagonal architecture - Learn the rules for each layer - See complete examples 3. **[apps/backend/README.md](apps/backend/README.md)** (10 min) - Backend-specific guidelines - Available scripts - Testing strategy 4. **[TODO.md](TODO.md)** - Sections relevant to current sprint (20 min) - Detailed task breakdown - Acceptance criteria - Technical specifications --- ## 🛠️ Development Guidelines ### Hexagonal Architecture Rules **Domain Layer** (`src/domain/`): - ✅ Pure TypeScript classes - ✅ Define interfaces (ports) - ✅ Business logic only - ❌ NO imports from NestJS, TypeORM, or any framework - ❌ NO decorators (@Injectable, @Column, etc.) **Application Layer** (`src/application/`): - ✅ Import from `@domain/*` only - ✅ Controllers, DTOs, Mappers - ✅ Handle HTTP-specific concerns - ❌ NO business logic **Infrastructure Layer** (`src/infrastructure/`): - ✅ Import from `@domain/*` only - ✅ Implement port interfaces - ✅ Framework-specific code (TypeORM, Redis, etc.) - ❌ NO business logic ### Testing Strategy - **Domain**: 90%+ coverage, test without any framework - **Application**: 80%+ coverage, test DTOs and mappings - **Infrastructure**: 70%+ coverage, test with test databases ### Git Workflow ```bash # Create feature branch git checkout -b feature/domain-entities # Make changes and commit git add . git commit -m "feat: add Organization and User domain entities" # Push and create PR git push origin feature/domain-entities ``` --- ## 🎯 Success Criteria for Week 1-2 By the end of Sprint 1-2, you should have: - [ ] All core domain entities created (Organization, User, RateQuote, Carrier, Port, Container) - [ ] All value objects created (Email, PortCode, Money, ContainerType, etc.) - [ ] All API ports defined (SearchRatesPort, CreateBookingPort, etc.) - [ ] All SPI ports defined (Repositories, CarrierConnectorPort, CachePort, etc.) - [ ] Domain services implemented (RateSearchService, BookingService, etc.) - [ ] Domain unit tests written (90%+ coverage) - [ ] All tests passing - [ ] No TypeScript errors - [ ] Code formatted and linted --- ## 💡 Tips for Success ### 1. Start Small Don't try to implement everything at once. Start with: - One entity (e.g., Organization) - One value object (e.g., Email) - One port (e.g., SearchRatesPort) - Tests for what you created ### 2. Test First (TDD) ```typescript // 1. Write the test it('should create organization with valid data', () => { const org = new Organization('1', 'ACME Freight', 'FREIGHT_FORWARDER'); expect(org.name).toBe('ACME Freight'); }); // 2. Implement the entity export class Organization { /* ... */ } // 3. Run the test npm test // 4. Refactor if needed ``` ### 3. Follow Patterns Look at examples in CLAUDE.md and copy the structure: - Entities are classes with readonly properties - Value objects validate in the constructor - Ports are interfaces - Services implement ports ### 4. Ask Questions If something is unclear: - Re-read CLAUDE.md - Check TODO.md for specifications - Look at the PRD.md for business context ### 5. Commit Often ```bash git add . git commit -m "feat: add Email value object with validation" # Small, focused commits are better ``` --- ## 📞 Need Help? **Documentation**: - [QUICK-START.md](QUICK-START.md) - Setup issues - [CLAUDE.md](CLAUDE.md) - Architecture questions - [TODO.md](TODO.md) - Task details - [apps/backend/README.md](apps/backend/README.md) - Backend specifics **Troubleshooting**: - [INSTALLATION-STEPS.md](INSTALLATION-STEPS.md) - Common issues **Architecture**: - Read the hexagonal architecture guidelines in CLAUDE.md - Study the example flows at the end of CLAUDE.md --- ## 🎉 You're Ready! **Current Status**: ✅ Sprint 0 Complete **Next Milestone**: Sprint 1-2 - Domain Layer **Timeline**: 2 weeks **Focus**: Create all domain entities, value objects, and ports **Let's build something amazing! 🚀** --- *Xpeditis MVP - Maritime Freight Booking Platform* *Good luck with Phase 1!*