A RESTful API service for managing topics with versioning support and hierarchical organization.
- Create, read, update, and delete topics with version control
- Hierarchical topic organization (parent-child relationships)
- Version history for each topic
- Resource attachments (video, article, podcast, audio, image, pdf)
- Find shortest path between topics in the hierarchy (comming soon)
- Role-based access control (admin, editor, viewer)
- Cascade delete support for hierarchical topics
- Node.js (v16 or higher recommended)
- Express.js
- TypeScript
- RESTful API design
- Design Patterns:
- Singleton (Services)
- Factory (DAO creation)
- Strategy (Permissions)
- Composite (Topic hierarchy)
- DAO & Repository (Data access)
- Service Layer
- Observer (Middleware)
- Builder (Topic creation)
- Version Control
- MVC
- Error Handler
- Dependency Injection (manual)
- Utility Classes (reusable functionality)
- Node.js (v16 or higher)
- npm or yarn
-
Install dependencies:
npm install -
Set up environment variables:
cp .env.example .envRequired environment variables:
PORT: Server port (default: 3000)NODE_ENV: Environment (development/production)STORAGE_PATH: Path for JSON storage files
Start the development server with hot reloading:
npm run dev
Build the TypeScript code:
npm run build
npm start
To run the tests, use the following commands:
# Install dependencies
npm install
# Run all tests
npm test
# Run tests with coverage report
npm run test:coverage
# Run tests in watch mode (useful during development)
npm run test:watchThis project uses ESLint and Prettier to maintain code quality and consistent formatting:
# Check code for linting issues
npm run lint:check
# Fix linting issues automatically
npm run lint
# Check code formatting
npm run format:check
# Format code
npm run formatThe linting configuration enforces:
- TypeScript best practices
- Consistent code formatting
- Proper error handling
- No use of console.log (use LogUtils instead)
- Many other code quality rules
For VS Code users, the project includes settings for automatic formatting on save and ESLint integration.
This service uses role-based access control with the following roles:
- Admin: Full access to all operations
- Editor: Can create, edit, and manage resources
- Viewer: Read-only access
Authentication is implemented via middleware that checks user roles and ownership.
GET /topics- Get all topics (latest versions)GET /topics/:id- Get a specific topic by ID (latest version)POST /topics- Create a new topicPUT /topics/:id- Update a topic (creates a new version)DELETE /topics/:id- Delete a topic (add ?cascade=true to delete children)
GET /topics/:id/versions- Get all versions of a topicGET /topics/:id/versions/:version- Get a specific version of a topic
GET /topics/:id/hierarchy- Get the topic hierarchy starting from a specific topicGET /topics/path/:fromId/:toId- Find shortest path between two topicsGET /topics/ancestor/:topicId1/:topicId2- Find lowest common ancestor of two topics
PUT /topics/:id/resource- Set a resource for a topicDELETE /topics/:id/resource- Remove a resource from a topic
GET /health- Check if the service is running
Request:
POST /topics
Content-Type: application/json
{
"name": "Introduction to Soccer",
"content": "Soccer is the world's most popular sport...",
"parentTopicId": null,
"resource": {
"url": "https://example.com/soccer-intro",
"description": "Comprehensive guide to soccer",
"type": "article"
}
}Response:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Introduction to Soccer",
"content": "Soccer is the world's most popular sport...",
"parentTopicId": null,
"version": 1,
"ownerId": "user123",
"createdAt": "2023-08-27T12:00:00.000Z",
"updatedAt": "2023-08-27T12:00:00.000Z",
"resource": {
"id": "res123",
"url": "https://example.com/soccer-intro",
"description": "Comprehensive guide to soccer",
"type": "article",
"topicId": "123e4567-e89b-12d3-a456-426614174000"
}
}Request:
GET /topics/path/123e4567-e89b-12d3-a456-426614174000/987fcdeb-a89b-12d3-a456-426614174000Response:
{
"path": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Introduction to Soccer",
"version": 1
},
{
"id": "456e4567-e89b-12d3-a456-426614174000",
"name": "Soccer Rules",
"version": 1
},
{
"id": "987fcdeb-a89b-12d3-a456-426614174000",
"name": "Offside Rule",
"version": 1
}
],
"distance": 2
}Request:
GET /topics/ancestor/123e4567-e89b-12d3-a456-426614174000/987fcdeb-a89b-12d3-a456-426614174000Response:
{
"ancestor": {
"id": "456e4567-e89b-12d3-a456-426614174000",
"name": "Soccer Rules",
"version": 1
},
"distanceToFirst": 1,
"distanceToSecond": 1
}// 404 Not Found (Path not found)
{
"message": "No path found between topics"
}
// 404 Not Found (Topic not found)
{
"message": "Topic not found"
}
// 400 Bad Request (Same topic)
{
"message": "Source and target topics must be different"
}
// 403 Forbidden
{
"message": "You do not have permission to update this topic",
"details": {
"role": "viewer",
"isOwner": false
}
}
// 409 Conflict (Delete with children)
{
"error": "Cannot delete topic with 2 child topics. Use cascade=true to delete all children."
}Valid resource types:
- video
- article
- podcast
- audio
- image
-
Download the Postman collection:
/postman/Knowledge-Base-Service.postman_collection.json -
Import the collection into Postman:
- Open Postman
- Click "Import" button
- Choose the downloaded collection file
- Select the imported "Knowledge Base Service" collection
MIT