Phase 1: Team Setup, Architecture & Integration Planning
Overview
Success in a team project requires clear architecture, well-defined boundaries, and effective communication. In this phase, you'll form your team, assign vertical slices, set up the shared codebase, and design integration points that allow independent development while ensuring seamless collaboration.
Learning Objectives
By the end of this phase, you will:
- Understand vertical slice architecture for team collaboration
- Have a complete monorepo setup with shared code
- Know your team member responsibilities and deliverables
- Have designed clear integration contracts
- Established Git workflow and code review process
Requirements
1. Team Formation & Role Assignment
Team Size: 3 people
Role Assignments:
Person 1: Shipment Creation Engineer
- Shipment intake and order creation
- Carrier selection and routing
- Address validation
- Cost estimation
- Patterns: Factory Method, Strategy, Chain of Responsibility, Builder
Person 2: Package Tracking Engineer
- Real-time tracking interface
- Status update system
- Delivery confirmation
- Exception handling
- Patterns: State, Observer, Memento, Command
Person 3: Customer Portal Developer
- Customer-facing order management
- Multi-channel notifications
- Delivery preferences
- Reporting and analytics
- Patterns: Observer, Template Method, Mediator, Facade
2. Project Setup
Monorepo Structure:
bash1# Initialize Next.js project2npx create-next-app@latest shipment-platform --typescript --tailwind --app3cd shipment-platform45# Additional dependencies6npm install zod date-fns recharts7npm install @tanstack/react-query8npm install -D vitest @testing-library/react @testing-library/jest-dom
Required Directory Structure:
1shipment-platform/2├── src/3│ ├── app/ # Next.js App Router4│ │ ├── (routes)/5│ │ │ ├── shipments/ # Person 1's routes6│ │ │ ├── tracking/ # Person 2's routes7│ │ │ ├── portal/ # Person 3's routes8│ │ │ └── layout.tsx9│ │ └── api/10│ │ ├── shipments/ # Person 1's API11│ │ ├── tracking/ # Person 2's API12│ │ └── notifications/ # Person 3's API13│ ├── features/ # Feature modules (vertical slices)14│ │ ├── shipment-creation/ # Person 1's feature15│ │ │ ├── components/16│ │ │ ├── services/17│ │ │ ├── hooks/18│ │ │ └── types.ts19│ │ ├── package-tracking/ # Person 2's feature20│ │ │ ├── components/21│ │ │ ├── services/22│ │ │ ├── hooks/23│ │ │ └── types.ts24│ │ └── customer-portal/ # Person 3's feature25│ │ ├── components/26│ │ ├── services/27│ │ ├── hooks/28│ │ └── types.ts29│ ├── shared/ # Shared code (team collaboration)30│ │ ├── types/ # Shared type definitions31│ │ │ ├── domain.ts32│ │ │ ├── api.ts33│ │ │ └── events.ts34│ │ ├── components/ # Shared UI components35│ │ │ ├── ui/ # Base components36│ │ │ └── layout/37│ │ ├── lib/ # Shared utilities38│ │ │ ├── storage.ts39│ │ │ ├── formatters.ts40│ │ │ └── validators.ts41│ │ └── hooks/ # Shared custom hooks42│ ├── services/ # Shared services43│ │ └── event-bus.ts # For inter-feature communication44│ └── config/45│ └── constants.ts46├── docs/47│ ├── architecture.md48│ ├── integration-contracts.md49│ └── team-workflow.md50└── package.json
3. Shared Type Definitions
Create src/shared/types/domain.ts:
typescript1// Core domain types (shared by all team members)23export interface Address {4 id?: string;5 name: string;6 street1: string;7 street2?: string;8 city: string;9 state: string;10 postalCode: string;11 country: string;12 phone?: string;13}1415export interface Package {16 id: string;17 dimensions: PackageDimensions;18 weight: PackageWeight;19 type: PackageType;20 declaredValue?: number;21}2223export interface PackageDimensions {24 length: number;25 width: number;26 height: number;27 unit: 'in' | 'cm';28}2930export interface PackageWeight {31 value: number;32 unit: 'lbs' | 'kg';33}3435export type PackageType = 'envelope' | 'box' | 'tube' | 'pallet';3637export type CarrierName = 'USPS' | 'FedEx' | 'UPS' | 'DHL';3839export type ServiceSpeed = 'overnight' | 'two-day' | 'standard' | 'economy';4041// Shipment entity (created by Person 1, used by Person 2 & 3)42export interface Shipment {43 id: string;44 orderId: string;45 package: Package;46 origin: Address;47 destination: Address;48 carrier: CarrierName;49 serviceLevel: string;50 trackingNumber: string;51 status: ShipmentStatus;52 estimatedDelivery: Date;53 actualDelivery?: Date;54 cost: number;55 createdAt: Date;56 updatedAt: Date;57 createdBy: string; // User ID58}5960// Shipment status (managed by Person 2)61export enum ShipmentStatus {62 CREATED = 'created',63 PICKED_UP = 'picked_up',64 IN_TRANSIT = 'in_transit',65 OUT_FOR_DELIVERY = 'out_for_delivery',66 DELIVERED = 'delivered',67 EXCEPTION = 'exception',68 CANCELLED = 'cancelled',69}7071// Tracking event (Person 2's domain)72export interface TrackingEvent {73 id: string;74 shipmentId: string;75 status: ShipmentStatus;76 location: string;77 timestamp: Date;78 description: string;79 metadata?: Record<string, unknown>;80}8182// Notification (Person 3's domain)83export interface Notification {84 id: string;85 userId: string;86 shipmentId: string;87 type: NotificationType;88 channel: NotificationChannel;89 subject: string;90 message: string;91 sentAt: Date;92 readAt?: Date;93}9495export enum NotificationType {96 SHIPMENT_CREATED = 'shipment_created',97 STATUS_UPDATE = 'status_update',98 DELIVERY_CONFIRMATION = 'delivery_confirmation',99 EXCEPTION_ALERT = 'exception_alert',100}101102export enum NotificationChannel {103 EMAIL = 'email',104 SMS = 'sms',105 PUSH = 'push',106 IN_APP = 'in_app',107}108109// Customer (Person 3's domain)110export interface Customer {111 id: string;112 email: string;113 name: string;114 phone?: string;115 preferences: CustomerPreferences;116 createdAt: Date;117}118119export interface CustomerPreferences {120 notificationChannels: NotificationChannel[];121 defaultOriginAddress?: Address;122 savedAddresses: Address[];123}
Create src/shared/types/events.ts:
typescript1// Event types for inter-feature communication23export enum EventType {4 SHIPMENT_CREATED = 'shipment:created',5 SHIPMENT_STATUS_CHANGED = 'shipment:status_changed',6 TRACKING_EVENT_ADDED = 'tracking:event_added',7 NOTIFICATION_SENT = 'notification:sent',8}910export interface DomainEvent<T = unknown> {11 type: EventType;12 payload: T;13 timestamp: Date;14 source: string; // Feature that emitted the event15}1617// Specific event payloads18export interface ShipmentCreatedPayload {19 shipment: Shipment;20}2122export interface ShipmentStatusChangedPayload {23 shipmentId: string;24 oldStatus: ShipmentStatus;25 newStatus: ShipmentStatus;26 timestamp: Date;27}2829export interface TrackingEventAddedPayload {30 shipmentId: string;31 event: TrackingEvent;32}
4. Integration Contracts
Document in docs/integration-contracts.md:
markdown1# Integration Contracts Between Team Members23## Person 1 → Person 2 Integration45**Contract**: When a shipment is created, emit ShipmentCreated event67**Person 1 Responsibility**:8- Create shipment in database9- Generate tracking number10- Emit `SHIPMENT_CREATED` event via EventBus1112**Person 2 Expectation**:13- Listen for `SHIPMENT_CREATED` event14- Initialize tracking with first event (status: CREATED)15- Create tracking timeline entry1617**Data Contract**:18```typescript19interface ShipmentCreatedEvent extends DomainEvent {20 type: EventType.SHIPMENT_CREATED;21 payload: {22 shipment: Shipment;23 };24}
API Contract:
typescript1// Person 1 provides2POST /api/shipments3Response: Shipment45// Person 2 consumes6GET /api/tracking/:trackingNumber7Response: TrackingEvent[]
Person 2 → Person 3 Integration
Contract: When shipment status changes, emit StatusChanged event for notifications
Person 2 Responsibility:
- Update shipment status
- Create tracking event
- Emit
SHIPMENT_STATUS_CHANGEDevent
Person 3 Expectation:
- Listen for
SHIPMENT_STATUS_CHANGEDevent - Determine if notification should be sent (based on user preferences)
- Send notification via appropriate channel(s)
Data Contract:
typescript1interface ShipmentStatusChangedEvent extends DomainEvent {2 type: EventType.SHIPMENT_STATUS_CHANGED;3 payload: {4 shipmentId: string;5 oldStatus: ShipmentStatus;6 newStatus: ShipmentStatus;7 timestamp: Date;8 };9}
Person 3 → Person 1 Integration
Contract: Customer can reorder from portal using previous shipment data
Person 3 Responsibility:
- Display shipment history
- Provide "Reorder" button
- Call Person 1's shipment creation API with prefilled data
Person 1 Expectation:
- Accept shipment creation requests
- Validate all data even if from reorder
- Return created shipment
API Contract:
typescript1// Person 3 calls2POST /api/shipments3Body: CreateShipmentRequest4Response: Shipment
12### 5. Event Bus for Inter-Feature Communication34**Create `src/services/event-bus.ts`:**56```typescript7import { DomainEvent, EventType } from '@/shared/types/events';89type EventHandler<T = unknown> = (event: DomainEvent<T>) => void | Promise<void>;1011class EventBus {12 private static instance: EventBus;13 private handlers: Map<EventType, Set<EventHandler>>;1415 private constructor() {16 this.handlers = new Map();17 }1819 static getInstance(): EventBus {20 if (!EventBus.instance) {21 EventBus.instance = new EventBus();22 }23 return EventBus.instance;24 }2526 subscribe<T>(eventType: EventType, handler: EventHandler<T>): () => void {27 if (!this.handlers.has(eventType)) {28 this.handlers.set(eventType, new Set());29 }3031 this.handlers.get(eventType)!.add(handler as EventHandler);3233 // Return unsubscribe function34 return () => {35 this.handlers.get(eventType)?.delete(handler as EventHandler);36 };37 }3839 async publish<T>(event: DomainEvent<T>): Promise<void> {40 const handlers = this.handlers.get(event.type);4142 if (!handlers || handlers.size === 0) {43 console.warn(`No handlers registered for event: ${event.type}`);44 return;45 }4647 const promises = Array.from(handlers).map(handler => {48 try {49 return Promise.resolve(handler(event));50 } catch (error) {51 console.error(`Error in event handler for ${event.type}:`, error);52 return Promise.resolve();53 }54 });5556 await Promise.allSettled(promises);57 }58}5960export const eventBus = EventBus.getInstance();
6. Git Workflow
Branching Strategy:
1main2├── develop3 ├── feature/person1-shipment-creation4 ├── feature/person2-tracking-system5 └── feature/person3-customer-portal
Workflow:
- Each person works on their feature branch
- Regular commits with meaningful messages
- Pull requests to
developbranch - Code review by at least one other team member
- Merge to
developafter approval - Integration testing on
develop - Periodic releases to
main
Commit Message Convention:
1type(scope): description23feat(shipment): add carrier selection logic4fix(tracking): resolve status transition bug5docs(readme): update setup instructions6test(portal): add notification tests
7. Team Communication
Required Regular Meetings:
-
Kickoff Meeting (1-2 hours)
- Assign roles
- Review architecture
- Discuss integration points
- Set timeline and milestones
-
Daily Standups (15 minutes)
- What did you complete yesterday?
- What will you work on today?
- Any blockers?
-
Weekly Integration Sync (30 minutes)
- Test integration points
- Resolve conflicts
- Align on next steps
-
Code Review Sessions
- Review each other's PRs
- Share pattern implementations
- Discuss improvements
Communication Channels:
- Slack/Discord for async communication
- GitHub for code reviews and discussions
- Shared document for decisions and notes
Deliverables
By the end of Phase 1, your team must have:
- Team formed with roles assigned
- Monorepo set up with directory structure
- Shared types defined in
src/shared/types/ - Event bus implemented for inter-feature communication
- Integration contracts documented
- Git repository initialized with branching strategy
- Team workflow documented
- Architecture diagram showing vertical slices and integration points
- First team meeting completed with notes
Architecture Diagram Requirements
Create a diagram showing:
1┌─────────────────────────────────────────────────────────────┐2│ User Interface │3├─────────────┬─────────────────────┬─────────────────────────┤4│ Person 1 │ Person 2 │ Person 3 │5│ Shipment │ Tracking │ Portal │6│ Creation │ System │ & Notifications │7├─────────────┼─────────────────────┼─────────────────────────┤8│ Components │ Components │ Components │9│ Hooks │ Hooks │ Hooks │10│ Services │ Services │ Services │11├─────────────┴─────────────────────┴─────────────────────────┤12│ Event Bus (Integration) │13├──────────────────────────────────────────────────────────────┤14│ Shared Types & Utilities │15├──────────────────────────────────────────────────────────────┤16│ Data Layer │17│ (localStorage / Mock API) │18└──────────────────────────────────────────────────────────────┘1920Events Flow:21Person 1 → EventBus → Person 2 (ShipmentCreated)22Person 2 → EventBus → Person 3 (StatusChanged)23Person 3 → Person 1 API (Reorder)
Validation Checklist
Before moving to feature development:
- All team members can run
npm run devsuccessfully - Shared types compile without errors
- Event bus can publish and subscribe to events
- Git workflow is established and understood
- Each team member knows their responsibilities
- Integration contracts are clear and agreed upon
- All team members have access to shared resources
Resources
- Vertical Slice Architecture
- Monorepo Best Practices
- Git Branching Strategies
- Event-Driven Architecture
Common Pitfalls to Avoid
- Tight coupling: Keep vertical slices independent, communicate via events
- Merge conflicts: Communicate frequently about overlapping changes
- Inconsistent types: Always use shared types, never duplicate
- Poor communication: Over-communicate rather than under-communicate
- Working in isolation: Integrate early and often
Estimated Time
- Team formation and kickoff: 2 hours
- Project setup: 2 hours
- Shared types definition: 2 hours
- Integration planning: 3 hours
- Documentation: 2 hours
- Total: 11 hours (distributed across team)
Next Steps
Each team member proceeds to their respective vertical slice:
- Person 1 → Phase 2: Shipment Creation & Carrier Management
- Person 2 → Phase 3: Package Tracking & Status Management
- Person 3 → Phase 4: Customer Portal & Notifications
All members work in parallel on their features while maintaining integration contracts.