Skip to content

AlonPulver/issueflow-api

Repository files navigation

IssueFlow - Ticket Management Backend

IssueFlow is a NestJS/TypeScript backend for a lightweight project and issue tracking system. It exposes REST APIs for users, projects, tickets, comments, audit logs, dependencies, attachments, CSV import/export, soft delete/restore, mentions, workload reporting, auto-assignment, and overdue escalation.

Stack

  • NestJS 10
  • TypeScript
  • PostgreSQL
  • TypeORM
  • Docker Compose for local PostgreSQL
  • Jest and Supertest for tests

Main Capabilities

  • JWT-protected API endpoints with POST /auth/login and POST /auth/logout.
  • Users with roles ADMIN and DEVELOPER.
  • Projects with soft delete and admin restore.
  • Project developer membership via POST /projects/:projectId/members.
  • Tickets with lifecycle enforcement: TODO -> IN_PROGRESS -> IN_REVIEW -> DONE.
  • Optimistic concurrency on ticket and comment updates through a required version field.
  • Dependency/blocker rules: dependencies must stay inside one project, and tickets cannot move to DONE while blockers are unresolved.
  • Comments with persisted known @username mentions. Unknown handles do not block comment creation.
  • Mentions lookup newest-first via GET /users/:userId/mentions.
  • Attachments with 10 MB max size and MIME allowlist: image/png, image/jpeg, application/pdf, text/plain.
  • CSV ticket import/export.
  • Audit logs for state-changing actions.
  • Auto-assignment to the least-loaded project developer, with ties broken by oldest user registration.
  • Auto-escalation of overdue tickets with persisted is_overdue and auto_escalation_count state.

Authentication

All API endpoints are protected by a global JWT guard except:

  • GET /
  • POST /auth/login

On startup, the app creates a default admin if one does not already exist:

username: admin
password: admin

Login:

curl -X POST http://localhost:3000/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin"}'

Use the returned token:

curl http://localhost:3000/users \
  -H "Authorization: Bearer <accessToken>"

Important API Notes

  • PATCH /tickets/:ticketId requires the current version.
  • PATCH /tickets/:ticketId/comments/:commentId requires the current version.
  • Restore endpoints use the authenticated JWT user as the actor; the user must be ADMIN.
  • Explicit ticket assignees must be developer members of the ticket project.
  • If a ticket is created without assigneeId, the app assigns it to the least-loaded developer in that project. If the project has no developer members, the ticket remains unassigned.
  • Manual priority changes reset auto-escalation state.

Run

See run.md for exact setup, build, run, and test commands.

Quick start:

npm install
docker compose up -d db
npm run start

Test

npm run lint
npm test -- --runInBand
npm run build
npm run test:e2e

The unit suite covers the main business rules. The e2e suite boots the full Nest app against PostgreSQL, verifies the JWT guard, and runs an authenticated workflow through HTTP: login, create developer, create project, add project member, create auto-assigned ticket, move the ticket forward, and reject an illegal backward transition.

The repository also includes a GitHub Actions workflow at .github/workflows/ci.yml that starts PostgreSQL and runs lint, unit tests, build, and e2e tests.

Architecture

The code is split into focused Nest services by domain:

  • AuthService handles login, JWT validation, logout, and token revocation.
  • UsersService handles users, default admin creation, password hashing, and admin checks.
  • ProjectsService handles projects, project membership, workload, and assignee eligibility.
  • TicketsService handles tickets, lifecycle rules, dependency rules, CSV import/export, assignment, and escalation.
  • CommentsService handles comments and mentions.
  • AttachmentsService handles upload validation and attachment persistence.
  • AuditService centralizes audit log writes and reads.
  • IssueflowService is now a thin facade kept for controller compatibility; business logic lives in the domain services above.

For a production version, I would also replace TypeORM synchronize: true with migrations, move the escalation loop to a dedicated worker or queue, and split these services into separate Nest modules once the project grows.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors