Phase 1: Project Setup & Architecture Planning
Overview
In this phase, you'll establish the foundation for your Multi-Carrier Shipping Rate Calculator. You'll set up the development environment, design the core architecture, and plan how design patterns will be applied throughout the project.
Learning Objectives
By the end of this phase, you will:
- Have a fully configured Next.js 16 + TypeScript development environment
- Understand the domain model for shipping rate calculation
- Have designed a type-safe architecture using TypeScript interfaces and types
- Know which design patterns to apply and where
- Have a clear project structure that supports scalability
Requirements
1. Development Environment Setup
Required Tools:
- Node.js 18+ installed
- Next.js 16 with App Router
- TypeScript 5+ (strict mode enabled)
- Tailwind CSS 4
- Testing framework (Vitest or Jest + React Testing Library)
- ESLint with TypeScript rules
- Prettier for code formatting
Project Initialization Steps:
- Initialize a new Next.js project named "rate-calculator" with TypeScript, Tailwind CSS, and App Router enabled
- Navigate into the project directory
- Install the project
Additional Dependencies to Install:
zod- Runtime type validationdate-fns- Date manipulation utilitiesvitest(dev) - Testing framework@testing-library/react(dev) - React testing utilities@testing-library/jest-dom(dev) - Jest DOM matchers
2. Core Domain Model Design
File to Create: src/types/domain.ts
Design and implement TypeScript types and interfaces for the entire shipping domain. Your type system should be:
- Strictly typed (no
anytypes) - Use union types for enums where appropriate
- Use optional properties (
?) for non-required fields - Export all types for use throughout the application
Required Type Definitions:
Package Information Types
Create interfaces and types to represent:
- PackageDimensions: length, width, height (numbers), and unit ('in' or 'cm')
- PackageWeight: value (number) and unit ('lbs' or 'kg')
- PackageType: Union type for 'envelope', 'box', 'tube', 'custom'
- Package: id, dimensions, weight, type, and optional declaredValue
Address Information
Create an interface to represent a complete mailing address:
- Required fields: name, street1, city, state, postalCode, country
- Optional fields: street2, phone
Shipping Service Options
Create types for:
- ServiceSpeed: Union type for 'overnight', 'two-day', 'standard', 'economy'
- ShippingOptions: speed, boolean flags for signatureRequired, insurance, fragileHandling, saturdayDelivery, and optional insuredValue
Carrier and Rate Information
Create types representing:
- CarrierName: Union type for 'USPS', 'FedEx', 'UPS', 'DHL'
- ShippingRate: Complete rate information including id, carrier, serviceCode, serviceName, speed, features (string array), baseRate, additionalFees array, totalCost, estimatedDeliveryDate, guaranteedDelivery boolean
- FeeType: Union type for 'insurance', 'signature', 'fragile', 'saturdayDelivery'
- Fee: type (FeeType), amount, description
API Request/Response Types
Create interfaces for:
- RateRequest: Combines package, origin address, destination address, options, and optional carriers filter
- RateResponse: requestId, rates array, errors array, timestamp
- CarrierError: carrier, error message, recoverable boolean
3. Architecture Planning
Required Design Patterns:
Document in docs/architecture.md how you'll use these patterns:
-
Strategy Pattern - Rate Calculation Algorithms
- Where:
src/services/rate-calculators/ - Why: Different carriers have different rate calculation logic
- Interface:
RateCalculationStrategy
- Where:
-
Factory Method Pattern - Carrier Instance Creation
- Where:
src/factories/carrier-factory.ts - Why: Create appropriate carrier service based on carrier name
- Interface:
CarrierFactory
- Where:
-
Decorator Pattern - Additional Services/Fees
- Where:
src/services/fee-decorators/ - Why: Stack additional fees (insurance, signature, etc.) dynamically
- Interface:
RateDecorator
- Where:
-
Adapter Pattern - External API Integration
- Where:
src/adapters/carrier-adapters/ - Why: Normalize different carrier API response formats
- Interface:
CarrierAdapter
- Where:
-
Singleton Pattern - Configuration Management
- Where:
src/config/carrier-config.ts - Why: Single source of truth for carrier credentials and settings
- Class:
CarrierConfigManager
- Where:
Architecture Diagram Requirements:
Create a diagram showing:
- Component layers (UI → Business Logic → Data Layer)
- Pattern usage locations
- Data flow from form input to rate display
- Error handling boundaries
4. Project Structure
Required Directory Structure:
1src/2├── app/ # Next.js App Router3│ ├── (routes)/4│ │ ├── page.tsx # Main rate calculator page5│ │ └── layout.tsx6│ └── api/7│ └── rates/8│ └── route.ts # Server Action for rate fetching9├── components/ # React components10│ ├── ui/ # Reusable UI components11│ ├── forms/ # Form components12│ └── results/ # Results display components13├── services/ # Business logic14│ ├── rate-calculators/ # Strategy implementations15│ ├── fee-decorators/ # Decorator implementations16│ └── validators/ # Validation logic17├── adapters/ # Adapter pattern implementations18│ └── carrier-adapters/19├── factories/ # Factory pattern implementations20├── config/ # Configuration (Singleton)21├── types/ # TypeScript type definitions22│ ├── domain.ts23│ └── carrier-apis.ts24├── lib/ # Utilities and helpers25└── hooks/ # Custom React hooks
5. Configuration and Environment
Required Environment Variables:
Create a .env.local file with the following variables:
Carrier API Keys (use sandbox/test keys for development):
- FEDEX_API_KEY and FEDEX_API_SECRET
- UPS_API_KEY and UPS_API_SECRET
- USPS_API_KEY
- DHL_API_KEY
App Configuration:
- NEXT_PUBLIC_APP_URL (set to http://localhost:3000 for development)
TypeScript Configuration:
Update your tsconfig.json to enable strict mode with the following compiler options:
- Enable
strictmode - Enable
noImplicitAny - Enable
strictNullChecks - Enable
strictFunctionTypes - Enable
noUnusedLocals - Enable
noUnusedParameters - Enable
noFallthroughCasesInSwitch
These settings ensure maximum type safety and catch potential errors at compile time.
Deliverables
By the end of Phase 1, you must have:
- Initialized Next.js project with all required dependencies
- Created
src/types/domain.tswith all core type definitions - Written
docs/architecture.mddocumenting pattern usage - Set up project directory structure as specified
- Configured TypeScript in strict mode with no errors
- Configured ESLint and Prettier
- Created
.env.localwith placeholder API keys - Architecture diagram showing component layers and pattern usage
- Verified dev server runs:
npm run dev
Validation Checklist
Before moving to Phase 2:
-
npm run devstarts without errors - TypeScript compilation passes:
npx tsc --noEmit - ESLint passes:
npm run lint - All type definitions compile without
anytypes - Architecture document clearly maps patterns to use cases
- Project structure matches requirements exactly
- Git repository initialized with meaningful first commit
Resources
- Next.js 14+ App Router Documentation
- TypeScript Design Patterns
- Tailwind CSS 4 Installation
- Course: TypeScript Design Patterns for Enterprise Applications (Topics 1-3)
Common Pitfalls to Avoid
- Using
anytypes: Always use proper type definitions - Skipping architecture planning: Jumping into code without design leads to refactoring
- Loose TypeScript configuration: Strict mode catches errors early
- Flat file structure: Organize by feature/pattern from the start
- Not documenting pattern usage: Document why you chose each pattern
Estimated Time
- Environment setup: 1 hour
- Type system design: 2 hours
- Architecture planning and documentation: 3 hours
- Total: 6 hours
Next Steps
Once you've completed all deliverables and passed the validation checklist, proceed to Phase 2: Package Input Form & Validation where you'll build the React UI for collecting shipment information.