Skip to content

Repository files navigation

TaskFlow API

A multi-tenant team collaboration REST API for managing workspaces, projects, tasks, and team members — built with ASP.NET Core and Clean Architecture.

TaskFlow lets teams of any size — from a group of friends to a company department — organize their work inside shared workspaces, track project progress, manage tasks with priorities and deadlines, and communicate through comments.


Tech Stack

  • Framework: ASP.NET Core (.NET 10)
  • Architecture: Clean Architecture (Core / Infrastructure / API)
  • Database: SQL Server with Entity Framework Core 10
  • Authentication: ASP.NET Core Identity + JWT Bearer tokens
  • API Docs: Swagger UI (Swashbuckle)
  • Containerization: Docker & Docker Compose

Architecture

The solution is split into three projects following Clean Architecture principles:

  • TaskManager.Core — entities, interfaces, DTOs, enums, and exceptions. No external dependencies.
  • TaskManager.Infrastructure — EF Core DbContext, entity configurations, migrations, and service implementations.
  • TaskManager.API — controllers, middleware, and the application entry point.

Dependencies only flow inward: API → Infrastructure → Core. The Core layer knows nothing about HTTP or databases.


Features

  • JWT Authentication — register and login with secure token-based authentication
  • Role-Based Authorization — three workspace roles (Owner, Manager, Member) with different permissions enforced at the service layer
  • Workspace Management — create workspaces, invite members, promote/demote roles, remove members
  • Project Management — organize work into projects scoped to a workspace
  • Task Management — create tasks with title, description, priority, deadline, and assignee; any member can update task status independently
  • Comments — comment on any task; authors and moderators can delete comments
  • Pagination & Filtering — filter tasks by status, priority, assignee, and deadline with page-based pagination

Role Permissions

Action Owner Manager Member
Delete workspace
Invite members
Promote to Manager
Remove members ✅*
Create / update / delete projects
Create / update / delete tasks
Update task status
Comment on tasks
Delete own comment
Delete any comment

*Managers can only remove Members, not other Managers or the Owner.


API Endpoints

Auth

Method Endpoint Description
POST /api/auth/register Register a new user
POST /api/auth/login Login and receive JWT token

Workspaces

Method Endpoint Description
GET /api/workspace Get all workspaces for current user
GET /api/workspace/{id} Get workspace by ID
POST /api/workspace Create a new workspace
PUT /api/workspace/{id} Update workspace
DELETE /api/workspace/{id} Delete workspace (Owner only)

Workspace Members

Method Endpoint Description
GET /api/workspace/{workspaceId}/members List all members
POST /api/workspace/{workspaceId}/members Invite a member by email
PUT /api/workspace/{workspaceId}/members/{userId}/promote Promote member to Manager
DELETE /api/workspace/{workspaceId}/members/{userId} Remove a member

Projects

Method Endpoint Description
GET /api/workspace/{workspaceId}/projects Get all projects
GET /api/workspace/{workspaceId}/projects/{projectId} Get project by ID
POST /api/workspace/{workspaceId}/projects Create a project
PUT /api/workspace/{workspaceId}/projects/{projectId} Update a project
DELETE /api/workspace/{workspaceId}/projects/{projectId} Delete a project

Tasks

Method Endpoint Description
GET /api/workspace/{workspaceId}/projects/{projectId}/tasks Get tasks (with filtering & pagination)
GET /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId} Get task by ID
POST /api/workspace/{workspaceId}/projects/{projectId}/tasks Create a task
PUT /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId} Update a task
PUT /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId}/status Update task status only
DELETE /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId} Delete a task

Task Filtering Query Parameters

Parameter Type Example
status enum ?status=InProgress
priority enum ?priority=High
assignedToId string ?assignedToId=userId
deadlineBefore datetime ?deadlineBefore=2026-08-01
page int ?page=2
pageSize int (max 50) ?pageSize=10

Comments

Method Endpoint Description
GET /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId}/comments Get all comments
GET /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId}/comments/{commentId} Get comment by ID
POST /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId}/comments Add a comment
PUT /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId}/comments/{commentId} Edit a comment (author only)
DELETE /api/workspace/{workspaceId}/projects/{projectId}/tasks/{taskId}/comments/{commentId} Delete a comment

Getting Started

Prerequisites

  • .NET 10 SDK
  • SQL Server (local or remote) — for the manual setup path
  • Docker & Docker Compose — for the containerized setup path

Environment Variables

Only needed for the Docker path below. Copy .env.example to .env and fill in real values:

Variable Description
DB_USERNAME SQL Server login (sa for the Docker database)
DB_PASSWORD SQL Server password
JWT_KEY Secret key for signing JWTs, 32+ characters

Option A — Run Locally

  1. Clone the repository
git clone https://github.com/zezoz5/TaskFlow.git
cd TaskFlow
  1. Create your local settings file

Create appsettings.Development.json inside TaskManager.API/ — this file is git-ignored and must never be committed:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=YOUR_SERVER;Database=TaskFlowDb;Trusted_Connection=True;TrustServerCertificate=True"
  },
  "Jwt": {
    "Key": "YOUR_SECRET_KEY_AT_LEAST_32_CHARACTERS_LONG",
    "Issuer": "TaskFlowAPI",
    "Audience": "TaskFlowClient",
    "ExpireDays": 7
  }
}
  1. Apply migrations
cd TaskManager.API
dotnet ef database update
  1. Run the API
dotnet run --launch-profile https
  1. Open Swagger UI

Navigate to https://localhost:7173/swagger to explore and test all endpoints.

To authenticate in Swagger: call /api/auth/login, copy the token from the response, click the Authorize button, and paste the token.

Option B — Run with Docker

  1. Copy .env.example to .env and fill in real values
  2. docker compose up --build
  3. API available at http://localhost:8080/swagger

Swagger is intentionally enabled in Production here, not just Development — this is a portfolio API, and the goal is letting anyone explore the live endpoints directly. A production system handling real user data would normally lock this down or keep it internal-only.


Tests

Unit tests cover the service layer's authorization logic using xUnit and EF Core's InMemory provider — no database required.

dotnet test TaskManager.UnitTests

Integration tests exercise the full API pipeline through WebApplicationFactory, against a real SQL Server instance — update the connection string in TaskManagerWebApplicationFactory to match your own setup first.

dotnet test TaskManager.IntegrationTests

Demo

A visual demo page is included to explore the API without needing Swagger.

  1. Make sure the API is running
  2. Open demo/index.html in your browser
  3. Register or login, then explore workspaces, projects, tasks, and members live

What I Learned

  • Implementing Clean Architecture in a real project — keeping domain logic completely independent of HTTP and database concerns
  • JWT authentication from scratch — token generation, claim mapping, and the MapInboundClaims = false gotcha
  • Role-based authorization enforced at the service layer, not just at the controller level
  • EF Core navigation properties — when .Select() auto-joins vs. when .Include() is required
  • Guard clause pattern for cleaner, more readable authorization logic
  • Pagination and filtering using incremental LINQ query building
  • Real debugging skills — tracing 401 errors through middleware, claim inspection, package version conflicts
  • Unit testing service-layer logic with xUnit and EF Core's InMemory provider — seeding related entities through navigation properties (not just foreign key values) to satisfy relationship constraints, and asserting on exception messages, not just types, after catching a test that was passing for the wrong reason
  • .gitignore vs. .dockerignore solve different problems — the first keeps secrets out of git, the second keeps files out of the Docker build context, and neither one stops a locally-present gitignored file from silently getting copied into an image via COPY . .

Future Work

  • Refresh Tokens — short-lived access tokens with long-lived refresh tokens for production-ready authentication
  • OAuth 2.0 — Google/GitHub login for verified emails and frictionless registration
  • CI/CD — automated build and deploy pipeline with GitHub Actions
  • Deployment — host the API on a cloud platform with a managed SQL Server instance

A Note from the Developer

TaskFlow was built as a learning project with one goal in mind: to move beyond CRUD APIs and understand how maintainable backend applications are designed.

Every project I build focuses on learning something new, and TaskFlow represents my journey into Clean Architecture, role-based authorization, and multi-tenant application design.

There are still many improvements I'd like to make, but I'm proud of how much this project taught me.

About

ASP.NET Core REST API for team-based task management with workspaces, roles, and JWT authentication.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages