Internal Tech Issue & Feature Tracker
A collaborative platform for software teams to report bugs, suggest features, and coordinate resolutions.
| Technology | Note |
|---|---|
| Node.js | LTS runtime (24.x or higher) |
| TypeScript | use latest version, dont use beta version |
| Express.js | Modular router architecture |
| PostgreSQL | Relational database, native pg driver only |
| Raw SQL | Direct pool.query() calls, absolutely no query builders, ORMs, or SQL JOINs |
| bcrypt | Password hashing, salt rounds between 8 and 12 |
| jsonwebtoken | JWT generation & verification (standard tokens) |
| Role | Allowed Actions |
|---|---|
| contributor | • Register and log in • Create new issues (bug or feature request) • View all issues • Update own issue field |
| maintainer | • All contributor permissions • Update any issue field • Delete any issue • Change issue workflow status independently |
- JWT Flow: Client sends credentials → Server validates & hashes/compares → Server returns signed JWT → Client attaches token to
Authorization: <token>header → Server verifies signature & expiry before processing. - Security Rules:
- Passwords are never exposed in responses or logs.
- Protected endpoints reject requests without a valid JWT.
- Role verification occurs before privileged operations.
| Field | Requirement (Plain Text) |
|---|---|
id |
Auto-incrementing unique identifier for each account |
name |
Full display name of the team member, must be provided |
email |
Valid login address, must be unique across all accounts, must be provided |
password |
Encrypted string stored securely, must be provided during registration, never returned in responses |
role |
Determines system access level, defaults to contributor, must be contributor or maintainer |
created_at |
Timestamp marking when the account was created, automatically generated on insert |
updated_at |
Timestamp marking when the account was last updated, automatically refreshed on update |
| Field | Requirement (Plain Text) |
|---|---|
id |
Auto-incrementing unique identifier for each reported item |
title |
Short descriptive headline, must be provided, maximum 150 characters |
description |
Detailed explanation of the problem or suggestion, must be provided, minimum 20 characters |
type |
Categorizes the entry, must be either bug or feature_request |
status |
Current workflow state, defaults to open. Status must be one of: open, in_progress, resolved |
reporter_id |
References the user who submitted the issue (no foreign key constraint required; validate in application logic) |
created_at |
Timestamp marking when the issue was created, automatically generated on insert |
updated_at |
Timestamp marking when the issue was last updated, automatically refreshed on update |
Access: Public
Description: Register a new user account with contributor or maintainer role
Endpoint
POST /api/auth/signup
Request Body
{
"name": "John Doe",
"email": "john.doe@devpulse.com",
"password": "securePassword123",
"role": "contributor"
}Success Response (201 Created)
{
"success": true,
"message": "User registered successfully",
"data": {
"id": 1,
"name": "John Doe",
"email": "john.doe@devpulse.com",
"role": "contributor",
"created_at": "2026-01-20T09:00:00Z",
"updated_at": "2026-01-20T09:00:00Z"
}
}Access: Public
Description: Authenticate user and receive JWT token
Endpoint
POST /api/auth/login
Request Body
{
"email": "john.doe@devpulse.com",
"password": "securePassword123"
}Success Response (200 OK)
{
"success": true,
"message": "Login successful",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"name": "John Doe",
"email": "john.doe@devpulse.com",
"role": "contributor",
"created_at": "2026-01-20T09:00:00Z",
"updated_at": "2026-01-20T09:00:00Z"
}
}
}💡 Hint: When signing the JWT during login, include the user's
id,name, androlein the token payload. These fields will be needed later to identify the requester and enforce permissions.
Access: Authenticated users (contributor, maintainer)
Description: Create a new bug report or feature request
Endpoint
POST /api/issues
Headers
Authorization: <JWT_TOKEN>
Request Body
{
"title": "Database connection timeout under load",
"description": "Pool exhausts after 50+ concurrent queries, causing 500 errors",
"type": "bug"
}Success Response (201 Created)
{
"success": true,
"message": "Issue created successfully",
"data": {
"id": 45,
"title": "Database connection timeout under load",
"description": "Pool exhausts after 50+ concurrent queries, causing 500 errors",
"type": "bug",
"status": "open",
"reporter_id": 1,
"created_at": "2026-01-20T10:30:00Z",
"updated_at": "2026-01-20T10:30:00Z"
}
}💡 Hint: The
reporter_idis extracted from the decoded JWT (req.user.id), not from the request body.
Access: Public
Description: Retrieve all issues with optional sorting and filtering
Endpoint
GET /api/issues?sort=newest
Query Parameters (let’s take a challenge)
| Param | Values | Default |
|---|---|---|
sort |
newest, oldest |
newest |
type |
bug, feature_request |
(none) |
status |
open, in_progress, resolved |
(none) |
Success Response (200 OK)
{
"success": true,
"message": "Issues retrived successfully",
"data": [
{
"id": 45,
"title": "Database connection timeout under load",
"description": "Pool exhausts after 50+ concurrent queries, causing 500 errors",
"type": "bug",
"status": "open",
"reporter": {
"id": 1,
"name": "John Doe",
"role": "contributor"
},
"created_at": "2026-01-20T10:30:00Z",
"updated_at": "2026-01-20T14:45:00Z"
}
]
}💡 Hint: To include
reporterdetails without JOINs, fetch issues first, then fetch reporter data for each issue in a separate query (or batch withWHERE id IN (...)).
Access: Public
Description: Retrieve full details of a specific issue
Endpoint
GET /api/issues/:id
Success Response (200 OK)
{
"success": true,
"message": "Issue retrived successfully",
"data": {
"id": 45,
"title": "Database connection timeout under load",
"description": "Pool exhausts after 50+ concurrent queries, causing 500 errors",
"type": "bug",
"status": "open",
"reporter": {
"id": 1,
"name": "John Doe",
"role": "contributor"
},
"created_at": "2026-01-20T10:30:00Z",
"updated_at": "2026-01-20T14:45:00Z"
}
}Access: Maintainer (any issue) OR Contributor (own issue, only if status is open)
Description: Update issue title, description, or type
Endpoint
PATCH /api/issues/:id
Headers
Authorization: <JWT_TOKEN>
Request Body
{
"title": "Updated: Database pool exhaustion fix needed",
"description": "Updated description with reproduction steps...",
"type": "bug"
}Success Response (200 OK)
{
"success": true,
"message": "Issue updated successfully",
"data": {
"id": 45,
"title": "Updated: Database pool exhaustion fix needed",
"description": "Updated description with reproduction steps...",
"type": "bug",
"status": "in_progress",
"reporter_id": 1,
"created_at": "2026-01-20T10:30:00Z",
"updated_at": "2026-01-20T14:45:00Z"
}
}Access: Maintainer only
Description: Permanently remove an issue from the system
Endpoint
DELETE /api/issues/:id
Headers
Authorization: <JWT_TOKEN>
Success Response (200 OK)
{
"success": true,
"message": "Issue deleted successfully"
}Standard Success Response Structure
{
"success": true,
"message": "Operation description",
"data": "Response data"
}Standard Error Response Structure
{
"success": false,
"message": "Error description",
"errors": "Error details"
}HTTP Status Codes
(Tip: Use the http-status-codes package for consistent status code references)
| Code | Reason Phrase | Usage |
|---|---|---|
200 |
OK | Successful GET, PATCH, PUT, DELETE |
201 |
Created | Successful POST (resource created) |
204 |
No Content | Successful DELETE with no response body |
400 |
Bad Request | Validation errors, invalid input, duplicate resource |
401 |
Unauthorized | Missing, expired, or invalid JWT token |
403 |
Forbidden | Valid token but insufficient role/permissions |
404 |
Not Found | Requested resource does not exist |
409 |
Conflict | Business logic conflict (e.g., editing resolved issue) |
500 |
Internal Server Error | Unexpected server or database error |
Questions:
- How does the Node.js event loop execute asynchronous tasks without blocking the single main thread?
- What is the purpose of
next()in Express middleware, and what happens if it is omitted in a route handler? - How do you create a centralized error-handling middleware in Express to safely catch both sync and async errors?
- What are the main differences between SQL (PostgreSQL) and NoSQL (MongoDB) regarding schema design and scaling?
- What is database connection pooling in PostgreSQL, and why is it preferred over opening a new client connection for every request?
🎤 Recording Instructions:
- Use your smartphone selfie camera or laptop webcam in landscape (horizontal) mode.
- Record in a well-lit, quiet room with your face fully visible throughout the video.
- Select and answer any 2 questions from the list above, spoken in English.
- Keep each answer between 3–5 minutes. Speak naturally from your understanding — avoid reading verbatim from notes or scripts.
- Upload your video to Google Drive, YouTube (Unlisted), or any cloud platform, and share a publicly accessible link.
Architecture & Code Quality:
- Use modular architecture: separate
modules/,utils/,config/, andmiddleware/directories - Create reusable utility functions for common tasks (response formatting, error handling, SQL queries)
- Follow the DRY principle: avoid code duplication; extract shared logic into helpers
- Keep code clean and readable: meaningful variable names, consistent formatting, inline comments for complex logic
- Use TypeScript strictly: no
anytypes, proper interfaces for request/response bodies
Critical Requirement:
API Endpoints Specification exactly—including endpoint paths, HTTP methods, request body structure, and response format. Deviations will result in 0 marks.
- Deploy backend to Vercel, Render, or Railway
- Use NeonDB, Supabase, or ElephantSQL for PostgreSQL
- Ensure CORS and environment variables are properly configured
**README.md must include:**
- Project name, live URL, features, tech stack
- Setup steps, API endpoint list, database schema summary
- Keep it clear and professional
Submit the following in your assignment form:
✅ GitHub Repo (Public): <https://github.com/yourusername/devpulse>
✅ Live Deployment (Public): <https://devpulse-api.vercel.app>
✅ Interview Video (Public): <https://drive.google.com/>... or <https://youtu.be/>...
💡 Pro Tips:
- Ensure your GitHub repo has at least 10 meaningful commits showing progressive development
- Avoid single-commit submissions
- Double-check all links are publicly accessible before submitting
| Marks | Deadline |
|---|---|
| 60 Marks | May 23, 2026 at 11:59 PM |
| 50 Marks | May 24, 2026 at 11:59 PM |
| 30 Marks | May 24 to June 15, 2026 at 11:59 PM |
- Plagiarism will not be tolerated. All submissions must be your original work.
- Any instance of plagiarism will result in 0 Marks and may trigger disciplinary action.
🔍 Submissions may be reviewed via code similarity tools and oral defense if required.
Good luck! 🚀 Build something clean, secure, and well-documented.