{"id":34571397,"url":"https://github.com/devdogukan/realtime-task-board","last_synced_at":"2026-04-11T06:42:55.957Z","repository":{"id":327284689,"uuid":"1107084431","full_name":"devdogukan/realtime-task-board","owner":"devdogukan","description":"A modern, Jira-like project management application with real-time task updates using Socket.io. Built with Node.js, Express and MongoDB.","archived":false,"fork":false,"pushed_at":"2025-12-04T12:11:33.000Z","size":7591,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-11T06:42:36.654Z","etag":null,"topics":["backend","express","nodejs","socket-io"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devdogukan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-30T14:51:38.000Z","updated_at":"2025-12-04T12:11:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/devdogukan/realtime-task-board","commit_stats":null,"previous_names":["devdogukan/task-board-backend"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/devdogukan/realtime-task-board","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdogukan%2Frealtime-task-board","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdogukan%2Frealtime-task-board/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdogukan%2Frealtime-task-board/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdogukan%2Frealtime-task-board/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devdogukan","download_url":"https://codeload.github.com/devdogukan/realtime-task-board/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdogukan%2Frealtime-task-board/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31671629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T17:19:37.612Z","status":"online","status_checked_at":"2026-04-11T02:00:05.776Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","express","nodejs","socket-io"],"created_at":"2025-12-24T09:36:50.000Z","updated_at":"2026-04-11T06:42:55.946Z","avatar_url":"https://github.com/devdogukan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TaskBoard - Real-time Task Management Application\n\nA modern, Jira-like project management application with real-time task updates using Socket.io. Built with React + TypeScript frontend and Node.js + Express + MongoDB backend.\n\n## Features\n\n### Core Features\n\n- **User Authentication**: Secure login and registration with JWT token management\n- **Dashboard Overview**: Centralized view showing statistics and folder organization\n- **Folder Management**: Organize projects into folders with member management\n- **Project Management**: Create and manage projects within folders\n- **Kanban Board**: Interactive drag-and-drop task management board with customizable columns\n- **Real-time Updates**: Live synchronization using Socket.io for collaborative task management\n- **Task Management**: Create, edit, assign, and track tasks with priorities and due dates\n- **Task Filtering**: Advanced filtering by assignee, priority, and due date range\n- **Member Management**: Add and remove members from folders and projects\n- **Responsive Design**: Modern UI that works seamlessly on desktop and mobile devices\n\n### User Interface Features\n\n- **Protected Routes**: Automatic redirect to login for unauthenticated users\n- **Form Validation**: Client-side validation using Zod schemas with React Hook Form\n- **Drag \u0026 Drop**: Intuitive task and column reordering with @dnd-kit\n- **Real-time Notifications**: Instant updates when tasks are created, updated, or moved\n- **Loading States**: Visual feedback during API operations\n- **Error Handling**: User-friendly error messages and fallback UI\n\n### Security Features\n\n- JWT token-based authentication\n- Password hashing with bcrypt\n- Route-based rate limiting for API protection (configurable per route type)\n- Helmet.js for security headers\n- CORS configuration\n- Input validation with Joi (backend) and Zod (frontend)\n\n### Testing\n\n- Comprehensive test suite with Vitest\n- Unit tests for services, controllers, and middlewares\n- Integration tests for API endpoints\n- Test coverage reporting\n- CI/CD with GitHub Actions\n\n## Tech Stack\n\n### Frontend\n\n- **React 18** - UI library for building user interfaces\n- **TypeScript** - Type-safe JavaScript for better developer experience\n- **Vite** - Fast build tool and development server\n- **React Router v6** - Client-side routing and navigation\n- **Zustand** - Lightweight state management library\n- **Axios** - HTTP client for API communication\n- **Socket.io Client** - Real-time bidirectional communication\n- **Tailwind CSS** - Utility-first CSS framework\n- **Shadcn UI** - High-quality React component library built on Radix UI\n- **Lucide React** - Beautiful icon library\n- **React Hook Form** - Performant form library with minimal re-renders\n- **Zod** - TypeScript-first schema validation\n- **@dnd-kit** - Modern drag-and-drop toolkit\n\n### Backend\n\n- **Node.js** (v20+) - JavaScript runtime\n- **Express.js** (v5) - Web framework\n- **MongoDB** - NoSQL database\n- **Mongoose** (v9) - MongoDB ODM\n- **Socket.io** (v4) - Real-time communication\n- **JWT** - Authentication tokens\n- **Joi** - Schema validation\n- **Winston** - Logging\n- **bcryptjs** - Password hashing\n- **Helmet** - Security headers\n- **express-rate-limit** - Rate limiting\n\n### DevOps\n\n- **Docker** - Containerization\n- **Docker Compose** - Multi-container orchestration\n- **GitHub Actions** - CI/CD pipeline\n\n## Project Structure\n\n```\nrealtime-task-board-app/\n├── .github/\n│   └── workflows/\n│       └── test.yml              # GitHub Actions CI/CD workflow\n├── client/                      # React frontend application\n│   ├── public/                  # Static assets\n│   ├── src/\n│   │   ├── api/                # API client functions\n│   │   ├── components/         # React components\n│   │   │   ├── ui/            # Shadcn UI components\n│   │   │   ├── AddMemberDialog.tsx\n│   │   │   ├── ColumnCard.tsx\n│   │   │   ├── ColumnForm.tsx\n│   │   │   ├── TaskCard.tsx\n│   │   │   └── ...\n│   │   ├── hooks/             # Custom React hooks\n│   │   ├── lib/               # Utility functions and configurations\n│   │   ├── pages/             # Page components\n│   │   │   ├── auth/\n│   │   │   ├── Dashboard.tsx\n│   │   │   ├── FolderDetail.tsx\n│   │   │   └── ProjectDetail.tsx\n│   │   ├── store/            # Zustand stores\n│   │   ├── App.tsx\n│   │   └── main.tsx\n│   ├── package.json\n│   ├── vite.config.ts\n│   └── ...\n├── server/                      # Node.js backend application\n│   ├── src/\n│   │   ├── config/            # Configuration files\n│   │   ├── controllers/       # Route controllers\n│   │   ├── middlewares/       # Express middlewares\n│   │   ├── models/            # Mongoose models\n│   │   ├── routes/            # API routes\n│   │   ├── services/          # Business logic layer\n│   │   ├── socket/            # Socket.io handlers\n│   │   ├── utils/             # Utility functions\n│   │   ├── validation/        # Joi validation schemas\n│   │   ├── app.js\n│   │   └── server.js\n│   ├── test/                  # Test files\n│   │   ├── unit/\n│   │   ├── integration/\n│   │   └── setup.js\n│   ├── coverage/              # Test coverage reports\n│   ├── package.json\n│   └── ...\n├── media/                      # Screenshots and demo videos\n│   ├── login.png\n│   ├── register.png\n│   ├── dashboard.png\n│   ├── folder-create-dialog.png\n│   ├── folder-detail.png\n│   ├── project-create-dialog.png\n│   ├── project-detail.png\n│   ├── column-create-dialog.png\n│   ├── create-task-dialog.png\n│   └── create-task-with-socket.mp4\n├── docker-compose.yml          # Docker Compose configuration\n└── README.md                   # This file\n```\n\n## Installation \u0026 Setup\n\n### Prerequisites\n\n- Node.js (v20 or higher)\n- MongoDB (v8.0 or higher) or MongoDB Atlas account\n- npm or yarn\n- Docker and Docker Compose (optional, for containerized setup)\n\n### Docker Setup (Recommended)\n\n1. **Clone the repository**\n   ```bash\n   git clone \u003crepository-url\u003e\n   cd realtime-task-board-app\n   ```\n\n2. **Start all services with Docker Compose**\n   ```bash\n   docker-compose up -d\n   ```\n\n   This will start:\n   - MongoDB container on port `27017`\n   - Backend server container on port `5000`\n   - Frontend client container on port `3000`\n\n3. **View logs**\n   ```bash\n   # View all logs\n   docker-compose logs -f\n   \n   # View specific service logs\n   docker-compose logs -f server\n   docker-compose logs -f client\n   ```\n\n4. **Stop containers**\n   ```bash\n   docker-compose down\n   ```\n\n### Local Development Setup\n\n#### Backend Setup\n\n1. **Navigate to server directory**\n   ```bash\n   cd server\n   ```\n\n2. **Install dependencies**\n   ```bash\n   npm install\n   ```\n\n3. **Create environment file**\n   \n   Create a `.env.development` file in the `server` directory:\n   ```env\n   NODE_ENV=development\n   PORT=5000\n   \n   # MongoDB Configuration\n   DB_URI=mongodb://localhost:27017/taskboard\n   # Or use MongoDB Atlas:\n   # DB_URI=mongodb+srv://username:password@cluster.mongodb.net/taskboard\n   \n   # JWT Configuration\n   JWT_SECRET=your-super-secret-jwt-key-change-in-production\n   JWT_EXPIRES_IN=7d\n   JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-in-production\n   JWT_REFRESH_EXPIRES_IN=30d\n   \n   # Frontend URL\n   FRONTEND_URL=http://localhost:3000\n   \n   # Rate Limiting Configuration\n   RATE_LIMIT_WINDOW=15m\n   RATE_LIMIT_MAX=100\n   ```\n\n4. **Start MongoDB** (if running locally)\n   ```bash\n   # Using Docker Compose (from root directory)\n   docker-compose up -d mongodb\n   \n   # Or start MongoDB service manually\n   ```\n\n5. **Run the development server**\n   ```bash\n   npm run dev\n   ```\n\n   The server will start on `http://localhost:5000`\n\n#### Frontend Setup\n\n1. **Navigate to client directory**\n   ```bash\n   cd client\n   ```\n\n2. **Install dependencies**\n   ```bash\n   npm install\n   ```\n\n3. **Create environment file**\n   \n   Create a `.env` file in the `client` directory:\n   ```env\n   VITE_API_BASE_URL=http://localhost:5000/api\n   VITE_SOCKET_URL=http://localhost:5000\n   ```\n\n4. **Start development server**\n   ```bash\n   npm run dev\n   ```\n\n   The application will be available at `http://localhost:3000`\n\n### Environment Variables\n\n#### Backend Environment Variables\n\n| Variable | Description | Required | Default |\n|----------|-------------|----------|---------|\n| `NODE_ENV` | Environment mode | ✅ | - |\n| `PORT` | Server port | ✅ | - |\n| `DB_URI` | MongoDB connection string | ✅ | - |\n| `JWT_SECRET` | JWT signing secret | ✅ | - |\n| `JWT_EXPIRES_IN` | JWT expiration time | ✅ | - |\n| `JWT_REFRESH_SECRET` | Refresh token secret | ✅ | - |\n| `JWT_REFRESH_EXPIRES_IN` | Refresh token expiration | ✅ | - |\n| `FRONTEND_URL` | Frontend application URL | ✅ | - |\n| `RATE_LIMIT_WINDOW` | Rate limit time window (format: number + unit, e.g., \"15m\", \"1h\") | ✅ | - |\n| `RATE_LIMIT_MAX` | Max requests per window for auth routes (base value) | ✅ | - |\n\n#### Frontend Environment Variables\n\n| Variable | Description | Required | Default |\n|----------|-------------|----------|---------|\n| `VITE_API_BASE_URL` | Backend API base URL | No | `http://localhost:5000/api` |\n| `VITE_SOCKET_URL` | Socket.io server URL | No | `http://localhost:5000` |\n\n## User Interface\n\n### Authentication Pages\n\n#### Login Page\n\nThe login page provides a clean, centered interface for user authentication.\n\n![Login Page](media/login.png)\n\n**Features:**\n- Email and password input fields with validation\n- Form validation with error messages\n- Link to registration page for new users\n- Automatic redirect to dashboard on successful login\n- Loading state during authentication\n\n**Form Fields:**\n- **Email**: Valid email address (required)\n- **Password**: Minimum 6 characters, maximum 32 characters (required)\n\n#### Register Page\n\nThe registration page allows new users to create an account.\n\n![Register Page](media/register.png)\n\n**Features:**\n- User registration form with email, first name, last name, and password\n- Client-side validation with Zod schemas\n- Success message and automatic redirect to login page\n- Link to login page for existing users\n\n**Form Fields:**\n- **Email**: Valid email address (required)\n- **First Name**: Required field\n- **Last Name**: Required field\n- **Password**: Minimum 6 characters, maximum 32 characters (required)\n\n### Dashboard\n\nThe dashboard provides an overview of all folders, projects, and tasks.\n\n![Dashboard](media/dashboard.png)\n\n**Features:**\n- **Statistics Cards**: Display total folders, projects, and tasks\n- **Folder Cards**: Visual representation of folders with project and member counts\n- **Quick Actions**: Create new folders directly from the dashboard\n- **Navigation**: Click on folder cards to view folder details\n\n**Statistics Display:**\n- Total Folders: Count of all folders owned by or shared with the user\n- Total Projects: Count of all projects across all folders\n- Total Tasks: Count of all tasks across all projects\n\n**Folder Card Information:**\n- Folder name and description\n- Number of projects in the folder\n- Number of members in the folder\n- Click to navigate to folder detail page\n\n### Folder Management\n\n#### Create Folder Dialog\n\nThe folder creation dialog allows users to create new folders for organizing projects.\n\n![Create Folder Dialog](media/folder-create-dialog.png)\n\n**Features:**\n- Modal dialog with form validation\n- Folder name input (required, max 100 characters)\n- Description input (required, max 500 characters)\n- Cancel and Create buttons\n\n**Usage:**\n- Click \"+ Add New Folder\" button in the sidebar or dashboard\n- Fill in folder name and description\n- Click \"Create\" to create the folder\n\n#### Folder Detail Page\n\nThe folder detail page displays folder information and member management.\n\n![Folder Detail Page](media/folder-detail.png)\n\n**Features:**\n- **Folder Information**: Display folder name and description\n- **Owner Section**: Shows folder owner with avatar and email\n- **Members Section**: List of all folder members\n- **Add Members**: Button to add new members (visible to folder owner only)\n- **Remove Members**: Remove members from folder (visible to folder owner only)\n\n**Member Management:**\n- View all members with avatars and email addresses\n- Add new members via dialog\n- Remove members (owner only)\n- See member count in the members section\n\n### Project Management\n\n#### Create Project Dialog\n\nThe project creation dialog allows users to create new projects within a folder.\n\n![Create Project Dialog](media/project-create-dialog.png)\n\n**Features:**\n- Modal dialog for creating projects\n- Project name input (required, max 100 characters)\n- Description input (required, max 500 characters)\n- Created within the context of the selected folder\n\n**Usage:**\n- Navigate to a folder in the sidebar\n- Click \"+ Add New Project\" under the folder\n- Fill in project name and description\n- Click \"Create\" to create the project\n\n#### Project Detail Page (Kanban Board)\n\nThe project detail page displays a full-featured Kanban board for task management.\n\n![Project Detail Page](media/project-detail.png)\n\n**Features:**\n- **Kanban Board**: Drag-and-drop task columns\n- **Column Management**: Create, reorder, and delete columns\n- **Task Cards**: Display tasks with assignees, due dates, and priorities\n- **Task Filtering**: Filter by assignee, priority, and due date range\n- **Real-time Updates**: Live synchronization with Socket.io\n- **Task Actions**: Create, edit, delete, and move tasks\n\n**Kanban Board Features:**\n- **Columns**: Customizable workflow columns (e.g., Pending, In Progress, Completed, Launched)\n- **Drag \u0026 Drop**: Move tasks between columns by dragging\n- **Column Reordering**: Drag columns to reorder them\n- **Task Cards**: Show task title, assignees, due date, and priority flag\n- **Column Headers**: Display column name with task count\n\n**Filtering Options:**\n- **Due Date Range**: Filter tasks by date range using date pickers\n- **Assignee**: Filter tasks by assigned user (dropdown with all users)\n- **Priority**: Filter tasks by priority level (Low, Medium, High)\n\n**Task Card Information:**\n- Task title\n- Assignee avatars (initials or images)\n- Due date and time\n- Priority indicator (color-coded flags)\n\n### Column Management\n\n#### Create Column Dialog\n\nThe column creation dialog allows users to add new columns to the Kanban board.\n\n![Create Column Dialog](media/column-create-dialog.png)\n\n**Features:**\n- Simple modal dialog for column creation\n- Column name input (required, max 50 characters)\n- Created within the context of the current project\n- Columns are automatically ordered\n\n**Usage:**\n- Navigate to a project detail page\n- Click the \"+\" icon in the column header or use the \"+ Add New\" button\n- Enter column name\n- Click \"Create\" to add the column\n\n**Column Features:**\n- Customizable column names\n- Automatic ordering (new columns appear at the end)\n- Drag-and-drop reordering\n- Delete option via column menu\n\n### Task Management\n\n#### Create/Edit Task Dialog\n\nThe task form dialog allows users to create and edit tasks with comprehensive options.\n\n![Create Task Dialog](media/create-task-dialog.png)\n\n**Features:**\n- **Side Drawer**: Opens from the right side of the screen\n- **Form Fields**:\n  - **Title**: Task title (required, max 200 characters)\n  - **Description**: Detailed task description (required, max 2000 characters)\n  - **Column**: Select target column from dropdown\n  - **Priority**: Choose priority level (Low, Medium, High)\n  - **Due Date**: Date and time picker for task deadline\n  - **Assignees**: Search and add multiple assignees with avatars\n\n**Assignee Management:**\n- Search users by name or email\n- Display user avatars with initials\n- Add multiple assignees to a task\n- Remove assignees with X button\n- Shows selected assignees as chips\n\n**Form Validation:**\n- Real-time validation with Zod schemas\n- Error messages displayed below fields\n- Required field indicators\n\n**Usage:**\n- Click \"+\" button in a column to create a task in that column\n- Click on an existing task card to edit it\n- Fill in task details\n- Click \"Create\" or \"Update\" to save\n\n### Real-time Features\n\nThe application uses Socket.io for real-time task updates. When a task is created, updated, moved, or deleted, all users viewing the same project will see the changes instantly.\n\n**Real-time Events:**\n- **Task Created**: New tasks appear immediately for all users\n- **Task Updated**: Task changes sync in real-time\n- **Task Moved**: Task column changes update instantly\n- **Task Deleted**: Task removal syncs across all clients\n\n**Video Demonstration:**\n\n\u003cvideo width=\"800\" controls\u003e\n  \u003csource src=\"media/create-task-with-socket.mp4\" type=\"video/mp4\"\u003e\n  Your browser does not support the video tag.\n\u003c/video\u003e\n\n## API Documentation\n\n### Base URL\n```\nhttp://localhost:5000/api\n```\n\n### Authentication Endpoints\n\n#### Register User\n```http\nPOST /api/auth/register\nContent-Type: application/json\n\n{\n  \"email\": \"user@example.com\",\n  \"password\": \"password123\",\n  \"firstName\": \"John\",\n  \"lastName\": \"Doe\"\n}\n```\n\n#### Login\n```http\nPOST /api/auth/login\nContent-Type: application/json\n\n{\n  \"email\": \"user@example.com\",\n  \"password\": \"password123\"\n}\n```\n\n#### Logout\n```http\nPOST /api/auth/logout\nCookie: token=\u003cjwt-token\u003e\n```\n\n### Folder Endpoints\n\n| Method | Endpoint | Description | Auth Required |\n|--------|----------|-------------|---------------|\n| GET | `/api/folders` | Get user's folders | ✅ |\n| GET | `/api/folders/:id` | Get folder by ID | ✅ |\n| POST | `/api/folders` | Create folder | ✅ |\n| PUT | `/api/folders/:id` | Update folder | ✅ |\n| DELETE | `/api/folders/:id` | Delete folder | ✅ |\n| POST | `/api/folders/:id/members` | Add member to folder | ✅ |\n| DELETE | `/api/folders/:id/members/:userId` | Remove member from folder | ✅ |\n\n### Project Endpoints\n\n| Method | Endpoint | Description | Auth Required |\n|--------|----------|-------------|---------------|\n| GET | `/api/folders/:folderId/projects` | Get projects in folder | ✅ |\n| GET | `/api/projects/:id` | Get project by ID | ✅ |\n| POST | `/api/folders/:folderId/projects` | Create project | ✅ |\n| PUT | `/api/projects/:id` | Update project | ✅ |\n| DELETE | `/api/projects/:id` | Delete project | ✅ |\n| PATCH | `/api/projects/:id/status` | Update project status | ✅ |\n| POST | `/api/projects/:id/members` | Add member to project | ✅ |\n| DELETE | `/api/projects/:id/members/:userId` | Remove member from project | ✅ |\n\n### Column Endpoints\n\n| Method | Endpoint | Description | Auth Required |\n|--------|----------|-------------|---------------|\n| GET | `/api/projects/:projectId/columns` | Get columns in project | ✅ |\n| GET | `/api/columns/:id` | Get column by ID | ✅ |\n| POST | `/api/projects/:projectId/columns` | Create column | ✅ |\n| PUT | `/api/columns/:id` | Update column | ✅ |\n| DELETE | `/api/columns/:id` | Delete column | ✅ |\n| PATCH | `/api/columns/:id/reorder` | Reorder column | ✅ |\n\n### Task Endpoints\n\n| Method | Endpoint | Description | Auth Required |\n|--------|----------|-------------|---------------|\n| GET | `/api/projects/:projectId/tasks` | Get tasks in project | ✅ |\n| GET | `/api/tasks/:id` | Get task by ID | ✅ |\n| POST | `/api/projects/:projectId/tasks` | Create task | ✅ |\n| PUT | `/api/tasks/:id` | Update task | ✅ |\n| DELETE | `/api/tasks/:id` | Delete task | ✅ |\n| PATCH | `/api/tasks/:id/move` | Move task to different column | ✅ |\n| PATCH | `/api/tasks/:id/reorder` | Reorder task | ✅ |\n| POST | `/api/tasks/:id/assignees` | Add assignee to task | ✅ |\n| DELETE | `/api/tasks/:id/assignees/:userId` | Remove assignee from task | ✅ |\n\n### Example: Create Task\n```http\nPOST /api/projects/:projectId/tasks\nContent-Type: application/json\nCookie: token=\u003cjwt-token\u003e\n\n{\n  \"columnId\": \"column-id\",\n  \"title\": \"Implement feature X\",\n  \"description\": \"Add new feature to the application\",\n  \"priority\": \"high\",\n  \"dueDate\": \"2024-12-31T23:59:59.000Z\",\n  \"assignees\": [\"user-id-1\", \"user-id-2\"]\n}\n```\n\n## Socket.io Events\n\n### Client → Server Events\n\n| Event | Payload | Description |\n|-------|---------|-------------|\n| `task:join-project` | `{ projectId: string }` | Join project room for real-time updates |\n| `task:leave-project` | `{ projectId: string }` | Leave project room |\n| `task:create` | `{ projectId, taskData }` | Create task (emits to room) |\n| `task:update` | `{ taskId, updates }` | Update task (emits to room) |\n| `task:delete` | `{ taskId, projectId }` | Delete task (emits to room) |\n| `task:move` | `{ taskId, newColumnId, orderIndex }` | Move task (emits to room) |\n| `task:reorder` | `{ taskId, newOrderIndex }` | Reorder task (emits to room) |\n\n### Server → Client Events\n\n| Event | Payload | Description |\n|-------|---------|-------------|\n| `task:created` | `{ task }` | Task created event |\n| `task:updated` | `{ task }` | Task updated event |\n| `task:deleted` | `{ taskId, projectId }` | Task deleted event |\n| `task:moved` | `{ task, oldColumnId, newColumnId }` | Task moved event |\n| `task:reordered` | `{ taskId, newOrderIndex }` | Task reordered event |\n| `task:error` | `{ error: string }` | Error event |\n| `task:joined-project` | `{ projectId }` | Confirmation of joining project |\n| `task:left-project` | `{ projectId }` | Confirmation of leaving project |\n\n### Example: Socket.io Client Usage\n```javascript\nimport io from 'socket.io-client';\n\nconst socket = io('http://localhost:5000', {\n  auth: {\n    token: 'your-jwt-token'\n  }\n});\n\n// Join project room\nsocket.emit('task:join-project', { projectId: 'project-id' });\n\n// Listen for task updates\nsocket.on('task:created', (data) =\u003e {\n  console.log('New task created:', data.task);\n});\n\nsocket.on('task:updated', (data) =\u003e {\n  console.log('Task updated:', data.task);\n});\n```\n\n## Database Models\n\n### User\n```javascript\n{\n  email: String (unique, required),\n  password: String (hashed, required),\n  firstName: String (required),\n  lastName: String (required),\n  avatar: String (optional),\n  createdAt: Date,\n  updatedAt: Date\n}\n```\n\n### Folder\n```javascript\n{\n  name: String (required),\n  description: String (optional),\n  owner: ObjectId (ref: User, required),\n  members: [ObjectId] (ref: User),\n  createdAt: Date,\n  updatedAt: Date\n}\n```\n\n### Project\n```javascript\n{\n  name: String (required),\n  description: String (optional),\n  folderId: ObjectId (ref: Folder, required),\n  owner: ObjectId (ref: User, required),\n  members: [ObjectId] (ref: User),\n  status: String (enum: ['active', 'archived'], default: 'active'),\n  createdAt: Date,\n  updatedAt: Date\n}\n```\n\n### Column\n```javascript\n{\n  name: String (required),\n  projectId: ObjectId (ref: Project, required),\n  orderIndex: Number (required, default: 0),\n  createdAt: Date,\n  updatedAt: Date\n}\n```\n\n### Task\n```javascript\n{\n  columnId: ObjectId (ref: Column, required),\n  projectId: ObjectId (ref: Project, required),\n  title: String (required),\n  description: String (required),\n  orderIndex: Number (required, default: 0),\n  assignees: [ObjectId] (ref: User),\n  priority: String (enum: ['low', 'medium', 'high'], default: 'medium'),\n  dueDate: Date (optional),\n  createdAt: Date,\n  updatedAt: Date\n}\n```\n\n## Rate Limiting\n\nThe application uses route-based rate limiting to protect API endpoints from abuse. Different route types have different rate limits based on their usage patterns.\n\n### Rate Limit Configuration\n\nRate limits are configured using environment variables:\n- `RATE_LIMIT_WINDOW`: Time window for rate limiting (format: `number + unit`)\n  - Supported units: `d` (days), `h` (hours), `m` (minutes), `s` (seconds)\n  - Examples: `\"15m\"`, `\"1h\"`, `\"30m\"`, `\"60s\"`\n- `RATE_LIMIT_MAX`: Base limit for auth routes (other routes use multipliers)\n\n### Route Type Limits\n\n| Route Type | Multiplier | Example Limit* |\n|------------|------------|-----------------|\n| `auth` | 1x (base) | 100 requests/15m |\n| `default` | 2x | 200 requests/15m |\n| `user` | 2x | 200 requests/15m |\n| `task` | 3x | 300 requests/15m |\n| `project` | 3x | 300 requests/15m |\n| `folder` | 3x | 300 requests/15m |\n| `column` | 3x | 300 requests/15m |\n\n*Based on default `RATE_LIMIT_MAX=100` and `RATE_LIMIT_WINDOW=15m`\n\n### Usage in Routes\n\nRate limiting is applied using the `rateLimit()` function:\n\n```javascript\nimport { rateLimit } from '#src/middlewares/rate.limiter.js';\n\n// Auth routes (stricter limits)\nrouter.post('/login', rateLimit('auth'), validate(loginSchema), authController.login);\n\n// Task routes (higher limits)\nrouter.post('/tasks', rateLimit('task'), authMiddleware, taskController.createTask);\n\n// Default limit\nrouter.get('/data', rateLimit('default'), authMiddleware, dataController.getData);\n// or simply\nrouter.get('/data', rateLimit(), authMiddleware, dataController.getData);\n```\n\n## State Management\n\nThe frontend application uses Zustand for state management with separate stores for different domains:\n\n### Auth Store (`client/src/store/authStore.ts`)\n\nManages user authentication state:\n- User information\n- Authentication token\n- Login/logout/register actions\n- Token refresh mechanism\n- Persistent storage with Zustand persist middleware\n\n### Folder Store (`client/src/store/folderStore.ts`)\n\nManages folder and project data:\n- Folder list\n- Projects by folder\n- Folder CRUD operations\n- Project CRUD operations\n- Member management\n- Expanded/collapsed folder state\n\n### Column Store (`client/src/store/columnStore.ts`)\n\nManages column data:\n- Columns by project\n- Column CRUD operations\n- Column reordering\n\n### Task Store (`client/src/store/taskStore.ts`)\n\nManages task data and Socket.io integration:\n- Tasks by project\n- Task CRUD operations\n- Task movement between columns\n- Socket.io event listeners\n- Real-time updates synchronization\n\n## Socket.io Integration\n\n### Connection Setup\n\nThe Socket.io client is initialized in `client/src/lib/socket.ts`:\n\n```typescript\nimport { io } from 'socket.io-client';\n\nconst socket = io(SOCKET_URL, {\n  auth: {\n    token: token || undefined,\n  },\n  withCredentials: true,\n  autoConnect: false,\n});\n```\n\n### Usage in Components\n\nThe task store initializes Socket.io listeners when a project is opened:\n\n```typescript\n// In ProjectDetail component\nuseEffect(() =\u003e {\n  if (id) {\n    initializeSocket();\n    const socket = getSocket();\n    if (socket) {\n      connectSocket();\n      socket.emit('task:join-project', id);\n      \n      return () =\u003e {\n        socket.emit('task:leave-project', id);\n        disconnectSocket();\n      };\n    }\n  }\n}, [id, initializeSocket]);\n```\n\n## Form Handling\n\nThe frontend application uses React Hook Form with Zod for form validation:\n\n### Example: Login Form\n\n```typescript\nconst loginSchema = z.object({\n  email: z.string().email('Invalid email address').min(1, 'Email is required'),\n  password: z.string().min(6, 'Password must be at least 6 characters'),\n});\n\nconst { register, handleSubmit, formState: { errors } } = useForm({\n  resolver: zodResolver(loginSchema),\n});\n```\n\n### Form Components\n\nAll forms use Shadcn UI form components:\n- `Form`: Form wrapper component\n- `FormField`: Field container\n- `FormLabel`: Accessible label\n- `FormMessage`: Error message display\n- `Input`: Text input component\n\n## Drag \u0026 Drop Implementation\n\nThe Kanban board uses @dnd-kit for drag-and-drop functionality:\n\n### Column Reordering\n\n```typescript\nimport { DndContext, closestCenter } from '@dnd-kit/core';\nimport { SortableContext, horizontalListSortingStrategy } from '@dnd-kit/sortable';\n\n\u003cDndContext onDragEnd={handleColumnDragEnd}\u003e\n  \u003cSortableContext items={columnIds} strategy={horizontalListSortingStrategy}\u003e\n    {columns.map(column =\u003e (\n      \u003cSortableColumn key={column._id} column={column} /\u003e\n    ))}\n  \u003c/SortableContext\u003e\n\u003c/DndContext\u003e\n```\n\n### Task Movement\n\nTasks can be dragged between columns and reordered within columns. The implementation handles:\n- Drag start/end events\n- Column detection\n- Order index calculation\n- Real-time updates via Socket.io\n\n## API Integration\n\n### Axios Configuration\n\nThe API client is configured in `client/src/lib/axios.ts`:\n\n- **Base URL**: Configurable via `VITE_API_BASE_URL`\n- **Credentials**: Cookies enabled for authentication\n- **Request Interceptor**: Adds JWT token to Authorization header\n- **Response Interceptor**: Handles token refresh on 401 errors\n\n### API Structure\n\nAPI functions are organized by domain:\n- `auth.api.ts`: Authentication endpoints\n- `folder.api.ts`: Folder endpoints\n- `project.api.ts`: Project endpoints\n- `column.api.ts`: Column endpoints\n- `task.api.ts`: Task endpoints\n- `user.api.ts`: User endpoints\n\n### Error Handling\n\n- Automatic token refresh on 401 errors\n- Request queuing during token refresh\n- Redirect to login on authentication failure\n- User-friendly error messages\n\n## Protected Routes\n\nThe frontend application uses a `ProtectedRoute` component to guard authenticated routes:\n\n```typescript\n\u003cRoute\n  path={ROUTES.DASHBOARD}\n  element={\n    \u003cProtectedRoute\u003e\n      \u003cDashboard /\u003e\n    \u003c/ProtectedRoute\u003e\n  }\n/\u003e\n```\n\n**Features:**\n- Checks authentication status\n- Attempts to restore session on mount\n- Redirects to login if not authenticated\n- Shows loading state during authentication check\n\n## Testing\n\n### Run Tests\n\n```bash\n# Navigate to server directory\ncd server\n\n# Run tests in watch mode\nnpm test\n\n# Run tests once\nnpm run test:run\n\n# Run tests with UI\nnpm run test:ui\n\n# Run tests with coverage\nnpm run test:coverage\n```\n\n### Test Coverage\n\nCoverage reports are generated in the `server/coverage/` directory. Open `server/coverage/index.html` in your browser to view detailed coverage reports.\n\n## Available Scripts\n\n### Backend Scripts\n\n| Script | Description |\n|--------|-------------|\n| `npm start` | Start production server |\n| `npm run dev` | Start development server with nodemon |\n| `npm test` | Run tests in watch mode |\n| `npm run test:run` | Run tests once |\n| `npm run test:ui` | Run tests with Vitest UI |\n| `npm run test:coverage` | Run tests with coverage report |\n| `npm run format` | Format code with Prettier |\n\n### Frontend Scripts\n\n| Script | Description |\n|--------|-------------|\n| `npm run dev` | Start development server with hot reload |\n| `npm run build` | Build production-ready application |\n| `npm run preview` | Preview production build locally |\n| `npm run lint` | Run ESLint to check code quality |\n\n## CI/CD\n\nThis project uses GitHub Actions for continuous integration. Every push triggers automated tests.\n\n### GitHub Actions Workflow\n- **Trigger**: On push and pull requests to any branch\n- **Jobs**:\n  - Run tests with Node.js 20.x\n  - Generate test coverage reports\n  - Validate code quality\n\nView workflow file: `.github/workflows/test.yml`\n\n## Development\n\n### Code Style\n\n- TypeScript strict mode enabled (frontend)\n- ESLint for code quality\n- Prettier for code formatting (via ESLint)\n- Consistent component structure\n\n### Best Practices\n\n- **Component Organization**: Components organized by feature/domain\n- **Type Safety**: Full TypeScript coverage (frontend)\n- **State Management**: Zustand stores for global state (frontend)\n- **Form Validation**: Zod schemas (frontend) and Joi schemas (backend) for type-safe validation\n- **Error Handling**: Centralized error handling in stores and controllers\n- **Loading States**: Loading indicators for async operations\n\n## Browser Support\n\n- Chrome (latest)\n- Firefox (latest)\n- Safari (latest)\n- Edge (latest)\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the ISC License.\n\n## Author\n\nDeveloped with ❤️ for efficient project management and team collaboration.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevdogukan%2Frealtime-task-board","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevdogukan%2Frealtime-task-board","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevdogukan%2Frealtime-task-board/lists"}