A modern, full-stack shipping tracking application that provides a unified interface for tracking packages across all major US carriers. Built with Next.js, Prisma, and TypeScript.
- Real Carrier API Integration: Live tracking through FedEx API (sandbox)
- Major Carrier Support: Track packages from FedEx, USPS, and UPS
- Smart Carrier Detection: Automatically detects carrier based on tracking number format
- Real-time Tracking: Get up-to-date package status and location information
- Graceful Fallback: Automatic fallback to mock data when APIs are unavailable
- User Authentication: Secure JWT-based authentication system with tiered access
- Tracking History: Save and view tracking history for authenticated users (30 minutes cache)
- Modern UI: Beautiful, responsive interface built with Tailwind CSS
- Type Safety: Full TypeScript support throughout the application
- Multi-Platform Deployment: Support for both Vercel and Docker deployments
ShipTrack implements a tiered authentication system that provides the best user experience:
- β Basic package tracking functionality
- β Universal carrier support
- β Real-time tracking information
- β Smart carrier detection
- π Tracking History: Save all your tracking searches
- π Personalized Experience: User-specific data and preferences
This approach ensures that:
- Anyone can track packages without creating an account (like real carrier websites)
- Users are incentivized to sign up for enhanced features
- The system scales from casual users to power users
- Frontend: Next.js 14 (App Router), React, TypeScript, Tailwind CSS
- Backend: Next.js API Routes, Prisma ORM
- Database: PostgreSQL
- Authentication: JWT with bcrypt password hashing
- Validation: Zod schema validation
- Testing: Jest (ready for implementation)
- Containerization: Docker
- Deployment: Vercel (recommended) or Docker containers
- Node.js 18+
- npm or yarn
- Git
- Docker (for containerized deployment)
git clone git@github.com:Hamil1/ShipTrack.git
cd ShipTracknpm installCopy the example environment file and configure it for your setup:
cp .env.example .envGenerate a Secure JWT Secret:
Before editing the .env file, generate a secure JWT secret:
node -e "console.log('JWT_SECRET=\"' + require('crypto').randomBytes(64).toString('hex') + '\"')"Copy the output and use it as your JWT_SECRET value in the .env file.
Then edit the .env file with your specific values. See .env.example for all available environment variables and their descriptions.
Important Notes:
- If you're using Docker, the database URL will be automatically configured by the Docker Compose environment variables.
- Carrier API keys are optional. The app will use mock data if APIs are not configured.
- USPS API: Has geographic restrictions and may not be available outside the US.
- JWT_SECRET: Must be a secure, random string. Never use the default placeholder value in production.
# Generate Prisma client
npx prisma generate
# For Local Development (without Docker)
# You'll need PostgreSQL installed locally, then:
npx prisma db push
# For Docker Development
./scripts/init-db.sh devnpm run devOpen http://localhost:3000 to view the application.
git clone git@github.com:Hamil1/ShipTrack.git
cd ShipTrackUse the same JWT secret you generated in the earlier step for your Docker environment. Update the JWT_SECRET value in your docker-compose.yml file or .env file as needed.
# Initialize the development database
./scripts/init-db.sh# Using the convenience script
./scripts/docker-dev.sh
# Or manually
docker compose up --buildAccess the app at http://localhost:3001 Access the database at localhost:5433
# Initialize development database
./scripts/init-db.sh
# Start development environment
docker compose up --build
# Start development environment (detached)
docker compose up --build -d
# View logs
docker compose logs -f shiptrack-app
# Stop development environment
docker compose down
# Stop development environment and remove orphaned containers
docker compose down --remove-orphansRegister a new user account.
Request Body:
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123"
}Response:
{
"success": true,
"data": {
"user": {
"id": "user_id",
"name": "John Doe",
"email": "john@example.com",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
},
"token": "jwt_token_here"
},
"message": "User registered successfully"
}Authenticate a user and receive a JWT token.
Request Body:
{
"email": "john@example.com",
"password": "password123"
}Response:
{
"success": true,
"data": {
"user": {
"id": "user_id",
"name": "John Doe",
"email": "john@example.com",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
},
"token": "jwt_token_here"
},
"message": "Login successful"
}Universal tracking endpoint that works for both authenticated and non-authenticated users.
Request Body:
{
"trackingNumber": "1Z999AA1234567890"
}Headers (optional):
Authorization: Bearer <jwt_token>
Response (Non-authenticated):
{
"success": true,
"data": {
"trackingNumber": "1Z999AA1234567890",
"carrier": "UPS",
"status": "In Transit",
"location": "Memphis, TN",
"timestamp": "2024-01-01T12:00:00.000Z",
"description": "Package in transit to next facility",
"events": [...]
},
"message": "Tracking information retrieved for UPS (Sign up for enhanced features)"
}Response (Authenticated):
{
"success": true,
"data": {
"trackingNumber": "1Z999AA1234567890",
"carrier": "UPS",
"status": "In Transit",
"location": "Memphis, TN",
"timestamp": "2024-01-01T12:00:00.000Z",
"description": "Package in transit to next facility",
"events": [...],
"userFeatures": {
"historySaved": true,
"enhancedUpdates": true
}
},
"message": "Tracking information retrieved for UPS (Enhanced features enabled)"
}Get cached tracking information for a specific tracking number. This endpoint implements intelligent caching:
- Personal Cache: For authenticated users, checks their personal tracking history first
- Global Cache: Falls back to any user's recent tracking data
- Freshness Check: Returns cached data if it's less than 30 minutes old
- Carrier API: Calls carrier API if no fresh cached data exists
- Auto-Save: Saves new tracking data to user's history if authenticated
Headers (optional):
Authorization: Bearer <jwt_token>
Response (Cached):
{
"success": true,
"data": {
"trackingNumber": "1Z999AA1234567890",
"carrier": "UPS",
"status": "In Transit",
"location": "Memphis, TN",
"timestamp": "2024-01-01T12:00:00.000Z",
"description": "Package in transit to next facility",
"events": [...]
},
"message": "Cached tracking information retrieved for UPS"
}Response (Fresh):
{
"success": true,
"data": {
"trackingNumber": "1Z999AA1234567890",
"carrier": "UPS",
"status": "In Transit",
"location": "Memphis, TN",
"timestamp": "2024-01-01T12:00:00.000Z",
"description": "Package in transit to next facility",
"events": [...]
},
"message": "Fresh tracking information retrieved for UPS"
}Get all tracking history for the authenticated user (requires authentication).
Headers (required):
Authorization: Bearer <jwt_token>
Response:
{
"success": true,
"data": [
{
"id": "history_id",
"trackingNumber": "1Z999AA1234567890",
"carrier": "UPS",
"status": "In Transit",
"location": "Memphis, TN",
"timestamp": "2024-01-01T12:00:00.000Z",
"description": "Package in transit to next facility",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z"
}
],
"message": "Tracking history retrieved successfully"
}Get full tracking history for a specific tracking number (requires authentication).
Headers (required):
Authorization: Bearer <jwt_token>
| Carrier | Tracking Number Format | Example | API Status |
|---|---|---|---|
| FedEx | 12-14 digits | 123456789012 | β Real API |
| USPS | 9xxx + 15-18 digits | 9400100000000000000000 | |
| UPS | 1Z + 6 chars + 10 digits | 1Z999AA1234567890 |
ShipTrack/
βββ .github/ # GitHub Actions workflows
β βββ workflows/
β βββ deploy.yml
βββ .husky/ # Git hooks configuration
βββ config/ # Carrier configuration files
β βββ carriers/
β βββ fedex.json
β βββ ups.json
β βββ usps.json
βββ docs/ # Documentation
β βββ CARRIER_ONBOARDING_README.md
β βββ DEPLOYMENT.md
β βββ README.md
β βββ TRACKING_STATUSES.md
β βββ USPS_API_TROUBLESHOOTING.md
βββ prisma/ # Database schema and migrations
β βββ schema.prisma
βββ public/ # Static assets
β βββ carriers/ # Carrier logo SVGs
β β βββ fedex.svg
β β βββ ups.svg
β β βββ usps.svg
β βββ favicon.ico
β βββ ...
βββ scripts/ # Development and deployment scripts
β βββ cleanup.sh
β βββ docker-dev-hot-reload.sh
β βββ docker-dev.sh
β βββ docker-prod.sh
β βββ init-db.sh
βββ src/ # Application source code
β βββ app/ # Next.js App Router
β β βββ api/ # API routes
β β β βββ auth/ # Authentication endpoints
β β β β βββ login/
β β β β βββ register/
β β β β βββ validate/
β β β βββ track/ # Tracking endpoints
β β β βββ [trackingNumber]/
β β β βββ history/
β β β βββ [trackingNumber]/
β β βββ favicon.ico
β β βββ globals.css
β β βββ layout.tsx
β β βββ page.tsx
β βββ components/ # React components
β β βββ common/ # Reusable UI components
β β β βββ Button.tsx
β β β βββ Card.tsx
β β β βββ CarrierBadge.tsx
β β β βββ ErrorDisplay.tsx
β β β βββ Input.tsx
β β β βββ index.ts
β β βββ AuthPrompt.tsx
β β βββ Header.tsx
β β βββ LoginForm.tsx
β β βββ RegisterForm.tsx
β β βββ TrackingForm.tsx
β β βββ TrackingHistory.tsx
β β βββ TrackingResult.tsx
β β βββ UserMenu.tsx
β βββ contexts/ # React contexts
β β βββ AuthContext.tsx
β βββ lib/ # Library configurations
β β βββ prisma.ts
β βββ providers/ # Carrier API providers
β β βββ BaseCarrierProvider.ts
β β βββ FedExProvider.ts
β β βββ UPSProvider.ts
β β βββ USPSProvider.ts
β βββ services/ # Business logic services
β β βββ CarrierRegistry.ts
β β βββ TrackingService.ts
β βββ types/ # TypeScript type definitions
β β βββ carrier.ts
β β βββ index.ts
β βββ utils/ # Utility functions
β βββ __tests__/ # Test files
β β βββ auth.test.ts
β β βββ carrierDetection.test.ts
β β βββ trackingService.test.ts
β βββ auth.ts
β βββ carrierDetection.ts
β βββ carrierDetection.test.ts
β βββ carrierLogos.ts
β βββ trackingService.ts
βββ .dockerignore
βββ .env # Environment variables
βββ .env.example # Environment variables template
βββ .gitignore
βββ docker-compose.yml # Docker Compose configuration
βββ Dockerfile # Production Dockerfile
βββ Dockerfile.dev # Development Dockerfile
βββ eslint.config.mjs # ESLint configuration
βββ jest.config.js # Jest test configuration
βββ jest.setup.js # Jest setup file
βββ next-env.d.ts # Next.js TypeScript definitions
βββ next.config.ts # Next.js configuration
βββ package.json # Node.js dependencies and scripts
βββ postcss.config.mjs # PostCSS configuration
βββ README.md # Project documentation
βββ tsconfig.json # TypeScript configuration
βββ tsconfig.tsbuildinfo # TypeScript build info
βββ vercel.json # Vercel deployment configuration
The application includes comprehensive test coverage for critical functionality:
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage# View database in Prisma Studio
npx prisma studio
# Reset database
npx prisma db push --force-reset
# Generate migration
npx prisma migrate dev --name <migration_name># Run ESLint
npm run lint
# Run TypeScript check
npm run type-check
# Format code
npm run format
# Run tests (automatically runs before git commit)
npm testThe project uses Husky to ensure code quality:
- Pre-commit: Runs tests before each commit
This ensures that broken code cannot be committed to the repository.
- API Integration Status:
- β FedEx: Full API integration working (sandbox)
β οΈ USPS: Geographic restrictions may apply (US-based users only)β οΈ UPS: Requires valid OAuth credentials
- Caching: Basic caching implemented. Consider Redis for production caching.
- Real-time Updates: Polling-based updates. Consider WebSockets for real-time functionality.
Note: This is a technical assessment project. For production use, additional security measures, error handling, and carrier API integrations would be required.