A TypeScript-based REST API for managing transit lines and stops. This backend service provides endpoints for creating, reading, updating, and deleting transit lines and their associated stops.
- 🚇 Full CRUD operations for transit lines and stops
- 🔍 Filtering capabilities for stops based on various metrics
- 📊 Population reachability metrics for stops
- 💾 Persistent storage with file-based JSON database
- 🔒 Input validation and error handling
- ���� Comprehensive API documentation
- ✨ Clean, type-safe TypeScript implementation
- Language: TypeScript
- Runtime: Node.js
- Framework: Express.js
- Testing: Jest
- Code Quality: ESLint, Prettier
- Documentation: JSDoc
- Node.js >= 14.0.0
- npm >= 7.0.0
-
Clone the repository:
git clone https://github.com/[your-username]/typescript-challenge-backend.git cd typescript-challenge-backend -
Install dependencies:
npm install
-
Start the development server:
npm start
-
Run tests:
npm test
- GET
/transit-lines - Returns all transit lines in the system
- Response: Array of TransitLine objects
- Status Codes: 200 (Success)
- GET
/transit-lines/:lineId - Returns details of a specific transit line
- Response: TransitLine object
- Status Codes: 200 (Success), 400 (Not Found)
- POST
/transit-lines/:lineId - Creates a new transit line
- Body:
{ stops: TransitStop[] } - Requirements:
- At least 2 stops required
- Line ID must be unique
- Status Codes: 201 (Created), 400 (Invalid Request)
- DELETE
/transit-lines/:lineId - Removes a transit line and all its stops
- Status Codes: 200 (Success), 400 (Not Found)
- GET
/transit-lines/stops - Returns all stops across all lines
- Query Parameters:
peopleOn: Filter by minimum number of boarding passengerspeopleOff: Filter by minimum number of alighting passengersreachablePopulationWalk: Filter by minimum walking-distance populationreachablePopulationBike: Filter by minimum biking-distance population
- Response: Array of TransitStop objects
- Status Codes: 200 (Success)
- POST
/transit-lines/:lineId/stops/:referenceId - Adds a new stop to a line
- Body:
{ stop: TransitStop, position: 'before' | 'after' }
- Status Codes: 200 (Success), 400 (Invalid Request)
- PUT
/transit-lines/:lineId/stops/:stopId - Updates stop properties
- Body: Partial (excluding id, prevId, nextId)
- Status Codes: 200 (Success), 400 (Invalid Request)
- DELETE
/transit-lines/:lineId/stops/:stopId - Removes a stop from a line
- Status Codes: 200 (Success), 400 (Invalid Request)
interface TransitLine {
id: string;
stops: TransitStop[];
}interface TransitStop {
name: string;
id: string;
lat: number;
lng: number;
prevId: string;
nextId: string;
peopleOn: number;
peopleOff: number;
reachablePopulationWalk: number;
reachablePopulationBike: number;
}The application follows a clean architecture pattern:
api/: HTTP controllers and route definitionsservices/: Business logic and data manipulationtypes/: TypeScript interfaces and type definitionsconfig/: Application configuration
The API provides meaningful error messages and appropriate HTTP status codes:
- 200: Successful operation
- 201: Resource created successfully
- 400: Invalid request or resource not found
- 500: Server error
The project includes comprehensive test coverage:
npm test # Run all tests
npm test -- --coverage # Run tests with coverage reportThe project uses ESLint and Prettier for consistent code style:
npm run lint # Check code style
npm run lint:fix # Fix code style issuesnpm run lint # Includes TypeScript type checkingPotential areas for enhancement:
- Add authentication and authorization
- Implement rate limiting
- Add database support (e.g., PostgreSQL)
- Add OpenAPI/Swagger documentation
- Add more advanced filtering and sorting options
- Implement caching
- Add real-time updates via WebSocket
While this is a challenge project, I welcome feedback and suggestions for improvement.
This project is part of a technical challenge and is available for review purposes.