@flusys/nestjs-task-manager 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +245 -0
- package/cjs/config/index.js +19 -0
- package/cjs/config/message-keys.js +92 -0
- package/cjs/config/task-manager.constants.js +11 -0
- package/cjs/controllers/index.js +22 -0
- package/cjs/controllers/task-board.controller.js +219 -0
- package/cjs/controllers/task-comment.controller.js +103 -0
- package/cjs/controllers/task-label.controller.js +112 -0
- package/cjs/controllers/task-list.controller.js +158 -0
- package/cjs/controllers/task.controller.js +199 -0
- package/cjs/docs/index.js +18 -0
- package/cjs/docs/task-manager-swagger.config.js +43 -0
- package/cjs/dtos/index.js +22 -0
- package/cjs/dtos/task-board.dto.js +310 -0
- package/cjs/dtos/task-comment.dto.js +131 -0
- package/cjs/dtos/task-label.dto.js +120 -0
- package/cjs/dtos/task-list.dto.js +198 -0
- package/cjs/dtos/task.dto.js +367 -0
- package/cjs/entities/index.js +72 -0
- package/cjs/entities/task-activity.entity.js +98 -0
- package/cjs/entities/task-assignee.entity.js +67 -0
- package/cjs/entities/task-board-member.entity.js +94 -0
- package/cjs/entities/task-board-with-company.entity.js +57 -0
- package/cjs/entities/task-board.entity.js +88 -0
- package/cjs/entities/task-comment.entity.js +80 -0
- package/cjs/entities/task-label.entity.js +72 -0
- package/cjs/entities/task-list.entity.js +104 -0
- package/cjs/entities/task-task-label.entity.js +67 -0
- package/cjs/entities/task.entity.js +151 -0
- package/cjs/gateways/index.js +18 -0
- package/cjs/gateways/task-board.gateway.js +199 -0
- package/cjs/index.js +26 -0
- package/cjs/interfaces/index.js +19 -0
- package/cjs/interfaces/task-manager-module.interface.js +4 -0
- package/cjs/interfaces/task.interface.js +4 -0
- package/cjs/modules/index.js +18 -0
- package/cjs/modules/task-manager.module.js +131 -0
- package/cjs/services/index.js +25 -0
- package/cjs/services/task-activity.service.js +76 -0
- package/cjs/services/task-board.service.js +235 -0
- package/cjs/services/task-comment.service.js +103 -0
- package/cjs/services/task-label.service.js +97 -0
- package/cjs/services/task-list.service.js +115 -0
- package/cjs/services/task-manager-config.service.js +69 -0
- package/cjs/services/task-manager-datasource.provider.js +84 -0
- package/cjs/services/task.service.js +359 -0
- package/config/index.d.ts +2 -0
- package/config/message-keys.d.ts +65 -0
- package/config/task-manager.constants.d.ts +1 -0
- package/controllers/index.d.ts +5 -0
- package/controllers/task-board.controller.d.ts +27 -0
- package/controllers/task-comment.controller.d.ts +22 -0
- package/controllers/task-label.controller.d.ts +22 -0
- package/controllers/task-list.controller.d.ts +26 -0
- package/controllers/task.controller.d.ts +28 -0
- package/docs/index.d.ts +1 -0
- package/docs/task-manager-swagger.config.d.ts +2 -0
- package/dtos/index.d.ts +5 -0
- package/dtos/task-board.dto.d.ts +44 -0
- package/dtos/task-comment.dto.d.ts +16 -0
- package/dtos/task-label.dto.d.ts +16 -0
- package/dtos/task-list.dto.d.ts +26 -0
- package/dtos/task.dto.d.ts +48 -0
- package/entities/index.d.ts +22 -0
- package/entities/task-activity.entity.d.ts +9 -0
- package/entities/task-assignee.entity.d.ts +5 -0
- package/entities/task-board-member.entity.d.ts +12 -0
- package/entities/task-board-with-company.entity.d.ts +4 -0
- package/entities/task-board.entity.d.ts +8 -0
- package/entities/task-comment.entity.d.ts +7 -0
- package/entities/task-label.entity.d.ts +6 -0
- package/entities/task-list.entity.d.ts +9 -0
- package/entities/task-task-label.entity.d.ts +5 -0
- package/entities/task.entity.d.ts +23 -0
- package/fesm/config/index.js +2 -0
- package/fesm/config/message-keys.js +65 -0
- package/fesm/config/task-manager.constants.js +1 -0
- package/fesm/controllers/index.js +5 -0
- package/fesm/controllers/task-board.controller.js +209 -0
- package/fesm/controllers/task-comment.controller.js +93 -0
- package/fesm/controllers/task-label.controller.js +102 -0
- package/fesm/controllers/task-list.controller.js +148 -0
- package/fesm/controllers/task.controller.js +189 -0
- package/fesm/docs/index.js +1 -0
- package/fesm/docs/task-manager-swagger.config.js +33 -0
- package/fesm/dtos/index.js +5 -0
- package/fesm/dtos/task-board.dto.js +277 -0
- package/fesm/dtos/task-comment.dto.js +110 -0
- package/fesm/dtos/task-label.dto.js +99 -0
- package/fesm/dtos/task-list.dto.js +174 -0
- package/fesm/dtos/task.dto.js +337 -0
- package/fesm/entities/index.js +46 -0
- package/fesm/entities/task-activity.entity.js +88 -0
- package/fesm/entities/task-assignee.entity.js +57 -0
- package/fesm/entities/task-board-member.entity.js +76 -0
- package/fesm/entities/task-board-with-company.entity.js +47 -0
- package/fesm/entities/task-board.entity.js +78 -0
- package/fesm/entities/task-comment.entity.js +70 -0
- package/fesm/entities/task-label.entity.js +62 -0
- package/fesm/entities/task-list.entity.js +94 -0
- package/fesm/entities/task-task-label.entity.js +57 -0
- package/fesm/entities/task.entity.js +133 -0
- package/fesm/gateways/index.js +1 -0
- package/fesm/gateways/task-board.gateway.js +148 -0
- package/fesm/index.js +9 -0
- package/fesm/interfaces/index.js +2 -0
- package/fesm/interfaces/task-manager-module.interface.js +1 -0
- package/fesm/interfaces/task.interface.js +1 -0
- package/fesm/modules/index.js +1 -0
- package/fesm/modules/task-manager.module.js +121 -0
- package/fesm/services/index.js +8 -0
- package/fesm/services/task-activity.service.js +66 -0
- package/fesm/services/task-board.service.js +225 -0
- package/fesm/services/task-comment.service.js +93 -0
- package/fesm/services/task-label.service.js +87 -0
- package/fesm/services/task-list.service.js +105 -0
- package/fesm/services/task-manager-config.service.js +59 -0
- package/fesm/services/task-manager-datasource.provider.js +74 -0
- package/fesm/services/task.service.js +349 -0
- package/gateways/index.d.ts +1 -0
- package/gateways/task-board.gateway.d.ts +22 -0
- package/index.d.ts +9 -0
- package/interfaces/index.d.ts +2 -0
- package/interfaces/task-manager-module.interface.d.ts +19 -0
- package/interfaces/task.interface.d.ts +52 -0
- package/modules/index.d.ts +1 -0
- package/modules/task-manager.module.d.ts +8 -0
- package/package.json +91 -0
- package/services/index.d.ts +8 -0
- package/services/task-activity.service.d.ts +8 -0
- package/services/task-board.service.d.ts +32 -0
- package/services/task-comment.service.d.ts +18 -0
- package/services/task-label.service.d.ts +18 -0
- package/services/task-list.service.d.ts +19 -0
- package/services/task-manager-config.service.d.ts +12 -0
- package/services/task-manager-datasource.provider.d.ts +18 -0
- package/services/task.service.d.ts +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# @flusys/nestjs-task-manager
|
|
2
|
+
|
|
3
|
+
Task management module for NestJS — dynamic boards, fully user-defined lists (no hardcoded statuses), real-time collaboration via Socket.IO WebSocket, board-scoped membership and permission model, and full activity audit log.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@flusys/nestjs-task-manager)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Design Decisions
|
|
11
|
+
|
|
12
|
+
- **Board-first architecture** — A `TaskBoard` holds company context. `TaskList` and `Task` carry only a `boardId`; no `companyId` is needed on them.
|
|
13
|
+
- **Fully dynamic lists** — Users create their own lists (columns) with any name, color, and position. There are no hardcoded status enums.
|
|
14
|
+
- **Board-member assignee restriction** — Assignees are validated against `TaskBoardMember` at write time (both service layer and frontend).
|
|
15
|
+
- **Real-time** — `TaskBoardGateway` broadcasts all mutations to every client in a `board:{boardId}` Socket.IO room.
|
|
16
|
+
- **Append-only activity log** — Every mutation (create, move, assign, comment) writes to `TaskActivity` — never updated or deleted.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @flusys/nestjs-task-manager @flusys/nestjs-shared @flusys/nestjs-core
|
|
24
|
+
npm install @nestjs/platform-socket.io socket.io jsonwebtoken
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 1. Module Registration
|
|
30
|
+
|
|
31
|
+
### forRoot (sync)
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { TaskManagerModule } from '@flusys/nestjs-task-manager';
|
|
35
|
+
|
|
36
|
+
@Module({
|
|
37
|
+
imports: [
|
|
38
|
+
TaskManagerModule.forRoot({
|
|
39
|
+
global: true,
|
|
40
|
+
includeController: true,
|
|
41
|
+
bootstrapAppConfig: {
|
|
42
|
+
databaseMode: 'single',
|
|
43
|
+
enableCompanyFeature: true,
|
|
44
|
+
},
|
|
45
|
+
config: {
|
|
46
|
+
jwtSecret: process.env.JWT_SECRET,
|
|
47
|
+
defaultDatabaseConfig: {
|
|
48
|
+
type: 'postgres',
|
|
49
|
+
host: process.env.DB_HOST,
|
|
50
|
+
port: Number(process.env.DB_PORT ?? 5432),
|
|
51
|
+
username: process.env.DB_USER,
|
|
52
|
+
password: process.env.DB_PASSWORD,
|
|
53
|
+
database: process.env.DB_NAME,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
],
|
|
58
|
+
})
|
|
59
|
+
export class AppModule {}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### forRootAsync (factory)
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
66
|
+
import { TaskManagerModule } from '@flusys/nestjs-task-manager';
|
|
67
|
+
|
|
68
|
+
TaskManagerModule.forRootAsync({
|
|
69
|
+
global: true,
|
|
70
|
+
includeController: true,
|
|
71
|
+
bootstrapAppConfig: {
|
|
72
|
+
databaseMode: 'single',
|
|
73
|
+
enableCompanyFeature: true,
|
|
74
|
+
},
|
|
75
|
+
imports: [ConfigModule],
|
|
76
|
+
useFactory: (config: ConfigService) => ({
|
|
77
|
+
jwtSecret: config.get('JWT_SECRET'),
|
|
78
|
+
defaultDatabaseConfig: {
|
|
79
|
+
type: 'postgres',
|
|
80
|
+
host: config.get('DB_HOST'),
|
|
81
|
+
port: config.get<number>('DB_PORT'),
|
|
82
|
+
username: config.get('DB_USER'),
|
|
83
|
+
password: config.get('DB_PASSWORD'),
|
|
84
|
+
database: config.get('DB_NAME'),
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
inject: [ConfigService],
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 2. Register Entities
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { getTaskManagerEntitiesByConfig } from '@flusys/nestjs-task-manager/entities';
|
|
97
|
+
|
|
98
|
+
TypeOrmModule.forRoot({
|
|
99
|
+
entities: [
|
|
100
|
+
...getTaskManagerEntitiesByConfig(true), // pass enableCompanyFeature
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| `enableCompanyFeature` | Entities registered |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `false` | `TaskBoard`, `TaskBoardMember`, `TaskList`, `Task`, `TaskLabel`, `TaskTaskLabel`, `TaskComment`, `TaskActivity` |
|
|
108
|
+
| `true` | Same set + `TaskBoardWithCompany` (adds `companyId` column) |
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 3. Entities
|
|
113
|
+
|
|
114
|
+
| Entity | Table | Key Columns |
|
|
115
|
+
|---|---|---|
|
|
116
|
+
| `TaskBoard` | `task_board` | `name`, `description`, `color`, `isActive`, `settings` (JSON) |
|
|
117
|
+
| `TaskBoardWithCompany` | `task_board` | extends `TaskBoard` + `companyId` |
|
|
118
|
+
| `TaskBoardMember` | `task_board_member` | `boardId`, `userId`, `role` (OWNER/ADMIN/MEMBER/VIEWER) |
|
|
119
|
+
| `TaskList` | `task_list` | `boardId`, `name`, `color`, `position`, `isDoneList` |
|
|
120
|
+
| `Task` | `task` | `boardId`, `listId`, `title`, `priority`, `dueDate`, `position`, `assigneeId`, `reporterId`, `parentTaskId` |
|
|
121
|
+
| `TaskLabel` | `task_label` | `boardId`, `name`, `color` |
|
|
122
|
+
| `TaskTaskLabel` | `task_task_label` | `taskId`, `labelId` (junction) |
|
|
123
|
+
| `TaskComment` | `task_comment` | `taskId`, `userId`, `content`, `parentCommentId` |
|
|
124
|
+
| `TaskActivity` | `task_activity` | `taskId`, `boardId`, `userId`, `action`, `oldValue`, `newValue` — append-only |
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 4. API Endpoints
|
|
129
|
+
|
|
130
|
+
All endpoints are POST-only RPC. The base path is set by `includeController: true`.
|
|
131
|
+
|
|
132
|
+
### Boards (`/board`)
|
|
133
|
+
|
|
134
|
+
| Endpoint | Description |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `POST /board/insert` | Create a board; creator is auto-assigned as `OWNER` |
|
|
137
|
+
| `POST /board/update` | Update board metadata |
|
|
138
|
+
| `POST /board/delete` | Soft delete |
|
|
139
|
+
| `POST /board/get/:id` | Get board by ID |
|
|
140
|
+
| `POST /board/get-all` | Paginated list (filtered by `companyId` when enabled) |
|
|
141
|
+
| `POST /board/add-member` | Add a user to the board with a role |
|
|
142
|
+
| `POST /board/remove-member` | Remove a board member |
|
|
143
|
+
| `POST /board/get-members` | List all members of a board |
|
|
144
|
+
|
|
145
|
+
### Lists (`/task-list`)
|
|
146
|
+
|
|
147
|
+
| Endpoint | Description |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `POST /task-list/insert` | Create a list in a board |
|
|
150
|
+
| `POST /task-list/update` | Rename, recolor, or toggle `isDoneList` |
|
|
151
|
+
| `POST /task-list/delete` | Soft delete |
|
|
152
|
+
| `POST /task-list/get-board-lists` | All lists for a board, ordered by `position` |
|
|
153
|
+
| `POST /task-list/reorder` | Bulk-reorder lists (gap strategy: `position = i * 100`) |
|
|
154
|
+
|
|
155
|
+
### Tasks (`/task`)
|
|
156
|
+
|
|
157
|
+
| Endpoint | Description |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `POST /task/insert` | Create a task; `assigneeId` must be a board member |
|
|
160
|
+
| `POST /task/update` | Update task fields |
|
|
161
|
+
| `POST /task/delete` | Soft delete |
|
|
162
|
+
| `POST /task/get-board-tasks` | All tasks for a board with labels |
|
|
163
|
+
| `POST /task/move` | Move task to another list + set position |
|
|
164
|
+
| `POST /task/assign` | Assign task to a board member |
|
|
165
|
+
|
|
166
|
+
### Labels (`/task-label`)
|
|
167
|
+
|
|
168
|
+
| Endpoint | Description |
|
|
169
|
+
|---|---|
|
|
170
|
+
| `POST /task-label/insert` | Create a board-scoped label |
|
|
171
|
+
| `POST /task-label/update` | Update label |
|
|
172
|
+
| `POST /task-label/delete` | Delete label |
|
|
173
|
+
| `POST /task-label/get-board-labels` | All labels for a board |
|
|
174
|
+
|
|
175
|
+
### Comments (`/task-comment`)
|
|
176
|
+
|
|
177
|
+
| Endpoint | Description |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `POST /task-comment/insert` | Add a comment (supports threading via `parentCommentId`) |
|
|
180
|
+
| `POST /task-comment/update` | Edit own comment (throws `ForbiddenException` otherwise) |
|
|
181
|
+
| `POST /task-comment/delete` | Soft delete |
|
|
182
|
+
| `POST /task-comment/get-task-comments` | All comments for a task, ordered by `createdAt ASC` |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 5. WebSocket Gateway
|
|
187
|
+
|
|
188
|
+
**Namespace:** `/task-boards`
|
|
189
|
+
**Auth:** JWT verified on connection via `Authorization` header (uses `jwtSecret` from module config).
|
|
190
|
+
|
|
191
|
+
### Client events (emit)
|
|
192
|
+
|
|
193
|
+
| Event | Payload | Description |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
| `board:join` | `{ boardId: string }` | Subscribe to real-time events for this board |
|
|
196
|
+
| `board:leave` | `{ boardId: string }` | Unsubscribe |
|
|
197
|
+
|
|
198
|
+
### Server events (listen)
|
|
199
|
+
|
|
200
|
+
| Event | Payload type | Emitted when |
|
|
201
|
+
|---|---|---|
|
|
202
|
+
| `board:event` | `ITaskBoardSocketEvent` | Any mutation on the board |
|
|
203
|
+
|
|
204
|
+
### `ITaskBoardSocketEvent`
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
interface ITaskBoardSocketEvent {
|
|
208
|
+
type:
|
|
209
|
+
| 'task:created' | 'task:updated' | 'task:moved' | 'task:deleted'
|
|
210
|
+
| 'list:created' | 'list:updated' | 'list:deleted' | 'list:reordered';
|
|
211
|
+
boardId: string;
|
|
212
|
+
payload: unknown; // the updated entity or reorder array
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## 6. Board Member Roles
|
|
219
|
+
|
|
220
|
+
| Role | Capabilities |
|
|
221
|
+
|---|---|
|
|
222
|
+
| `OWNER` | Full control including deleting the board and managing members |
|
|
223
|
+
| `ADMIN` | Create/edit/delete tasks and lists, manage members |
|
|
224
|
+
| `MEMBER` | Create and edit tasks |
|
|
225
|
+
| `VIEWER` | Read-only access |
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 7. Services Reference
|
|
230
|
+
|
|
231
|
+
| Service | Scope | Key Methods |
|
|
232
|
+
|---|---|---|
|
|
233
|
+
| `TaskBoardService` | REQUEST | `addMember()`, `removeMember()`, `getBoardMembers()`, `isBoardMember()` |
|
|
234
|
+
| `TaskListService` | REQUEST | `getListsForBoard()`, `reorderLists()` |
|
|
235
|
+
| `TaskService` | REQUEST | `getTasksForBoard()`, `moveTask()`, `assignTask()` |
|
|
236
|
+
| `TaskLabelService` | REQUEST | `getLabelsForBoard()` |
|
|
237
|
+
| `TaskCommentService` | REQUEST | `getCommentsForTask()` |
|
|
238
|
+
| `TaskActivityService` | REQUEST | `log()`, `getForTask()` |
|
|
239
|
+
| `TaskBoardGateway` | singleton | `emitToBoardRoom(boardId, event)` |
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## License
|
|
244
|
+
|
|
245
|
+
MIT © FLUSYS
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./task-manager.constants"), exports);
|
|
6
|
+
_export_star(require("./message-keys"), exports);
|
|
7
|
+
function _export_star(from, to) {
|
|
8
|
+
Object.keys(from).forEach(function(k) {
|
|
9
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
10
|
+
Object.defineProperty(to, k, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function() {
|
|
13
|
+
return from[k];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return from;
|
|
19
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get TASK_BOARD_MESSAGES () {
|
|
13
|
+
return TASK_BOARD_MESSAGES;
|
|
14
|
+
},
|
|
15
|
+
get TASK_COMMENT_MESSAGES () {
|
|
16
|
+
return TASK_COMMENT_MESSAGES;
|
|
17
|
+
},
|
|
18
|
+
get TASK_LABEL_MESSAGES () {
|
|
19
|
+
return TASK_LABEL_MESSAGES;
|
|
20
|
+
},
|
|
21
|
+
get TASK_LIST_MESSAGES () {
|
|
22
|
+
return TASK_LIST_MESSAGES;
|
|
23
|
+
},
|
|
24
|
+
get TASK_MESSAGES () {
|
|
25
|
+
return TASK_MESSAGES;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const TASK_BOARD_MESSAGES = {
|
|
29
|
+
NOT_FOUND: 'task.board.not.found',
|
|
30
|
+
CREATE_SUCCESS: 'task.board.create.success',
|
|
31
|
+
CREATE_MANY_SUCCESS: 'task.board.create.many.success',
|
|
32
|
+
GET_SUCCESS: 'task.board.get.success',
|
|
33
|
+
GET_ALL_SUCCESS: 'task.board.get.all.success',
|
|
34
|
+
UPDATE_SUCCESS: 'task.board.update.success',
|
|
35
|
+
UPDATE_MANY_SUCCESS: 'task.board.update.many.success',
|
|
36
|
+
DELETE_SUCCESS: 'task.board.delete.success',
|
|
37
|
+
RESTORE_SUCCESS: 'task.board.restore.success',
|
|
38
|
+
MEMBER_ADDED: 'task.board.member.added',
|
|
39
|
+
MEMBER_REMOVED: 'task.board.member.removed',
|
|
40
|
+
MEMBER_NOT_FOUND: 'task.board.member.not.found',
|
|
41
|
+
MEMBER_ALREADY_EXISTS: 'task.board.member.already.exists',
|
|
42
|
+
MEMBER_GET_ALL_SUCCESS: 'task.board.member.get.all.success'
|
|
43
|
+
};
|
|
44
|
+
const TASK_LIST_MESSAGES = {
|
|
45
|
+
NOT_FOUND: 'task.list.not.found',
|
|
46
|
+
CREATE_SUCCESS: 'task.list.create.success',
|
|
47
|
+
CREATE_MANY_SUCCESS: 'task.list.create.many.success',
|
|
48
|
+
GET_SUCCESS: 'task.list.get.success',
|
|
49
|
+
GET_ALL_SUCCESS: 'task.list.get.all.success',
|
|
50
|
+
UPDATE_SUCCESS: 'task.list.update.success',
|
|
51
|
+
UPDATE_MANY_SUCCESS: 'task.list.update.many.success',
|
|
52
|
+
DELETE_SUCCESS: 'task.list.delete.success',
|
|
53
|
+
RESTORE_SUCCESS: 'task.list.restore.success',
|
|
54
|
+
REORDER_SUCCESS: 'task.list.reorder.success'
|
|
55
|
+
};
|
|
56
|
+
const TASK_MESSAGES = {
|
|
57
|
+
NOT_FOUND: 'task.not.found',
|
|
58
|
+
CREATE_SUCCESS: 'task.create.success',
|
|
59
|
+
CREATE_MANY_SUCCESS: 'task.create.many.success',
|
|
60
|
+
GET_SUCCESS: 'task.get.success',
|
|
61
|
+
GET_ALL_SUCCESS: 'task.get.all.success',
|
|
62
|
+
UPDATE_SUCCESS: 'task.update.success',
|
|
63
|
+
UPDATE_MANY_SUCCESS: 'task.update.many.success',
|
|
64
|
+
DELETE_SUCCESS: 'task.delete.success',
|
|
65
|
+
RESTORE_SUCCESS: 'task.restore.success',
|
|
66
|
+
MOVE_SUCCESS: 'task.move.success',
|
|
67
|
+
ASSIGN_SUCCESS: 'task.assign.success',
|
|
68
|
+
ASSIGNEE_NOT_BOARD_MEMBER: 'task.assignee.not.board.member'
|
|
69
|
+
};
|
|
70
|
+
const TASK_LABEL_MESSAGES = {
|
|
71
|
+
NOT_FOUND: 'task.label.not.found',
|
|
72
|
+
CREATE_SUCCESS: 'task.label.create.success',
|
|
73
|
+
CREATE_MANY_SUCCESS: 'task.label.create.many.success',
|
|
74
|
+
GET_SUCCESS: 'task.label.get.success',
|
|
75
|
+
GET_ALL_SUCCESS: 'task.label.get.all.success',
|
|
76
|
+
UPDATE_SUCCESS: 'task.label.update.success',
|
|
77
|
+
UPDATE_MANY_SUCCESS: 'task.label.update.many.success',
|
|
78
|
+
DELETE_SUCCESS: 'task.label.delete.success',
|
|
79
|
+
RESTORE_SUCCESS: 'task.label.restore.success'
|
|
80
|
+
};
|
|
81
|
+
const TASK_COMMENT_MESSAGES = {
|
|
82
|
+
NOT_FOUND: 'task.comment.not.found',
|
|
83
|
+
CREATE_SUCCESS: 'task.comment.create.success',
|
|
84
|
+
CREATE_MANY_SUCCESS: 'task.comment.create.many.success',
|
|
85
|
+
GET_SUCCESS: 'task.comment.get.success',
|
|
86
|
+
GET_ALL_SUCCESS: 'task.comment.get.all.success',
|
|
87
|
+
UPDATE_SUCCESS: 'task.comment.update.success',
|
|
88
|
+
UPDATE_MANY_SUCCESS: 'task.comment.update.many.success',
|
|
89
|
+
DELETE_SUCCESS: 'task.comment.delete.success',
|
|
90
|
+
RESTORE_SUCCESS: 'task.comment.restore.success',
|
|
91
|
+
FORBIDDEN: 'task.comment.forbidden'
|
|
92
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "TASK_MANAGER_MODULE_OPTIONS", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return TASK_MANAGER_MODULE_OPTIONS;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const TASK_MANAGER_MODULE_OPTIONS = 'TASK_MANAGER_MODULE_OPTIONS';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./task-board.controller"), exports);
|
|
6
|
+
_export_star(require("./task-list.controller"), exports);
|
|
7
|
+
_export_star(require("./task.controller"), exports);
|
|
8
|
+
_export_star(require("./task-label.controller"), exports);
|
|
9
|
+
_export_star(require("./task-comment.controller"), exports);
|
|
10
|
+
function _export_star(from, to) {
|
|
11
|
+
Object.keys(from).forEach(function(k) {
|
|
12
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
13
|
+
Object.defineProperty(to, k, {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function() {
|
|
16
|
+
return from[k];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return from;
|
|
22
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "TaskBoardController", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return TaskBoardController;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nestjsshared = require("@flusys/nestjs-shared");
|
|
12
|
+
const _classes = require("@flusys/nestjs-shared/classes");
|
|
13
|
+
const _decorators = require("@flusys/nestjs-shared/decorators");
|
|
14
|
+
const _dtos = require("@flusys/nestjs-shared/dtos");
|
|
15
|
+
const _guards = require("@flusys/nestjs-shared/guards");
|
|
16
|
+
const _interfaces = require("@flusys/nestjs-shared/interfaces");
|
|
17
|
+
const _common = require("@nestjs/common");
|
|
18
|
+
const _swagger = require("@nestjs/swagger");
|
|
19
|
+
const _classtransformer = require("class-transformer");
|
|
20
|
+
const _config = require("../config");
|
|
21
|
+
const _dtos1 = require("../dtos");
|
|
22
|
+
const _taskboardservice = require("../services/task-board.service");
|
|
23
|
+
function _define_property(obj, key, value) {
|
|
24
|
+
if (key in obj) {
|
|
25
|
+
Object.defineProperty(obj, key, {
|
|
26
|
+
value: value,
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
obj[key] = value;
|
|
33
|
+
}
|
|
34
|
+
return obj;
|
|
35
|
+
}
|
|
36
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
37
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
38
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
39
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
40
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
41
|
+
}
|
|
42
|
+
function _ts_metadata(k, v) {
|
|
43
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
44
|
+
}
|
|
45
|
+
function _ts_param(paramIndex, decorator) {
|
|
46
|
+
return function(target, key) {
|
|
47
|
+
decorator(target, key, paramIndex);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
let TaskBoardController = class TaskBoardController extends (0, _classes.createApiController)(_dtos1.CreateTaskBoardDto, _dtos1.UpdateTaskBoardDto, _dtos1.TaskBoardResponseDto, {
|
|
51
|
+
entityName: 'task.board',
|
|
52
|
+
enabledEndpoints: [
|
|
53
|
+
'insert',
|
|
54
|
+
'insertMany',
|
|
55
|
+
'getById',
|
|
56
|
+
'getAll',
|
|
57
|
+
'update',
|
|
58
|
+
'updateMany',
|
|
59
|
+
'delete'
|
|
60
|
+
],
|
|
61
|
+
security: {
|
|
62
|
+
insert: {
|
|
63
|
+
level: 'permission',
|
|
64
|
+
permissions: [
|
|
65
|
+
_nestjsshared.TASK_BOARD_PERMISSIONS.CREATE
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
insertMany: {
|
|
69
|
+
level: 'permission',
|
|
70
|
+
permissions: [
|
|
71
|
+
_nestjsshared.TASK_BOARD_PERMISSIONS.CREATE
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
getById: {
|
|
75
|
+
level: 'permission',
|
|
76
|
+
permissions: [
|
|
77
|
+
_nestjsshared.TASK_BOARD_PERMISSIONS.READ
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
getAll: {
|
|
81
|
+
level: 'permission',
|
|
82
|
+
permissions: [
|
|
83
|
+
_nestjsshared.TASK_BOARD_PERMISSIONS.READ
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
update: {
|
|
87
|
+
level: 'permission',
|
|
88
|
+
permissions: [
|
|
89
|
+
_nestjsshared.TASK_BOARD_PERMISSIONS.UPDATE
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
updateMany: {
|
|
93
|
+
level: 'permission',
|
|
94
|
+
permissions: [
|
|
95
|
+
_nestjsshared.TASK_BOARD_PERMISSIONS.UPDATE
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
delete: {
|
|
99
|
+
level: 'permission',
|
|
100
|
+
permissions: [
|
|
101
|
+
_nestjsshared.TASK_BOARD_PERMISSIONS.DELETE
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}) {
|
|
106
|
+
async addMember(dto, user) {
|
|
107
|
+
const member = await this.boardService.addMember(dto, user);
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
message: 'Member added to board',
|
|
111
|
+
messageKey: _config.TASK_BOARD_MESSAGES.MEMBER_ADDED,
|
|
112
|
+
data: (0, _classtransformer.plainToInstance)(_dtos1.TaskBoardMemberResponseDto, member, {
|
|
113
|
+
excludeExtraneousValues: true
|
|
114
|
+
})
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async removeMember(dto) {
|
|
118
|
+
await this.boardService.removeMember(dto);
|
|
119
|
+
return {
|
|
120
|
+
success: true,
|
|
121
|
+
message: 'Member removed',
|
|
122
|
+
messageKey: _config.TASK_BOARD_MESSAGES.MEMBER_REMOVED
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async getMembers(dto) {
|
|
126
|
+
const members = await this.boardService.getMembers(dto.boardId);
|
|
127
|
+
const data = (0, _classtransformer.plainToInstance)(_dtos1.TaskBoardMemberResponseDto, members, {
|
|
128
|
+
excludeExtraneousValues: true
|
|
129
|
+
});
|
|
130
|
+
return {
|
|
131
|
+
success: true,
|
|
132
|
+
message: 'Board members retrieved',
|
|
133
|
+
messageKey: _config.TASK_BOARD_MESSAGES.MEMBER_GET_ALL_SUCCESS,
|
|
134
|
+
data,
|
|
135
|
+
meta: {
|
|
136
|
+
total: data.length,
|
|
137
|
+
page: 0,
|
|
138
|
+
pageSize: data.length,
|
|
139
|
+
count: data.length
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
constructor(boardService){
|
|
144
|
+
super(boardService), _define_property(this, "boardService", void 0), this.boardService = boardService;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
_ts_decorate([
|
|
148
|
+
(0, _common.Post)('add-member'),
|
|
149
|
+
(0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
|
|
150
|
+
(0, _swagger.ApiBearerAuth)(),
|
|
151
|
+
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
152
|
+
(0, _decorators.RequirePermission)(_nestjsshared.TASK_BOARD_PERMISSIONS.MANAGE_MEMBERS),
|
|
153
|
+
(0, _swagger.ApiOperation)({
|
|
154
|
+
summary: 'Add user to board'
|
|
155
|
+
}),
|
|
156
|
+
(0, _swagger.ApiBody)({
|
|
157
|
+
type: _dtos1.AddBoardMemberDto
|
|
158
|
+
}),
|
|
159
|
+
(0, _decorators.ApiResponseDto)(_dtos1.TaskBoardMemberResponseDto),
|
|
160
|
+
_ts_param(0, (0, _common.Body)()),
|
|
161
|
+
_ts_param(1, (0, _decorators.CurrentUser)()),
|
|
162
|
+
_ts_metadata("design:type", Function),
|
|
163
|
+
_ts_metadata("design:paramtypes", [
|
|
164
|
+
typeof _dtos1.AddBoardMemberDto === "undefined" ? Object : _dtos1.AddBoardMemberDto,
|
|
165
|
+
typeof _interfaces.ILoggedUserInfo === "undefined" ? Object : _interfaces.ILoggedUserInfo
|
|
166
|
+
]),
|
|
167
|
+
_ts_metadata("design:returntype", Promise)
|
|
168
|
+
], TaskBoardController.prototype, "addMember", null);
|
|
169
|
+
_ts_decorate([
|
|
170
|
+
(0, _common.Post)('remove-member'),
|
|
171
|
+
(0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard),
|
|
172
|
+
(0, _swagger.ApiBearerAuth)(),
|
|
173
|
+
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
174
|
+
(0, _decorators.RequirePermission)(_nestjsshared.TASK_BOARD_PERMISSIONS.MANAGE_MEMBERS),
|
|
175
|
+
(0, _swagger.ApiOperation)({
|
|
176
|
+
summary: 'Remove user from board'
|
|
177
|
+
}),
|
|
178
|
+
(0, _swagger.ApiBody)({
|
|
179
|
+
type: _dtos1.RemoveBoardMemberDto
|
|
180
|
+
}),
|
|
181
|
+
(0, _swagger.ApiResponse)({
|
|
182
|
+
status: 200,
|
|
183
|
+
type: _dtos.MessageResponseDto
|
|
184
|
+
}),
|
|
185
|
+
_ts_param(0, (0, _common.Body)()),
|
|
186
|
+
_ts_metadata("design:type", Function),
|
|
187
|
+
_ts_metadata("design:paramtypes", [
|
|
188
|
+
typeof _dtos1.RemoveBoardMemberDto === "undefined" ? Object : _dtos1.RemoveBoardMemberDto
|
|
189
|
+
]),
|
|
190
|
+
_ts_metadata("design:returntype", Promise)
|
|
191
|
+
], TaskBoardController.prototype, "removeMember", null);
|
|
192
|
+
_ts_decorate([
|
|
193
|
+
(0, _common.Post)('get-members'),
|
|
194
|
+
(0, _common.UseGuards)(_guards.JwtAuthGuard),
|
|
195
|
+
(0, _swagger.ApiBearerAuth)(),
|
|
196
|
+
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
197
|
+
(0, _swagger.ApiOperation)({
|
|
198
|
+
summary: 'Get all board members'
|
|
199
|
+
}),
|
|
200
|
+
(0, _swagger.ApiBody)({
|
|
201
|
+
type: _dtos1.GetBoardMembersDto
|
|
202
|
+
}),
|
|
203
|
+
(0, _decorators.ApiResponseDto)(_dtos1.TaskBoardMemberResponseDto, true),
|
|
204
|
+
_ts_param(0, (0, _common.Body)()),
|
|
205
|
+
_ts_metadata("design:type", Function),
|
|
206
|
+
_ts_metadata("design:paramtypes", [
|
|
207
|
+
typeof _dtos1.GetBoardMembersDto === "undefined" ? Object : _dtos1.GetBoardMembersDto
|
|
208
|
+
]),
|
|
209
|
+
_ts_metadata("design:returntype", Promise)
|
|
210
|
+
], TaskBoardController.prototype, "getMembers", null);
|
|
211
|
+
TaskBoardController = _ts_decorate([
|
|
212
|
+
(0, _swagger.ApiTags)('Task Manager - Boards'),
|
|
213
|
+
(0, _common.Controller)('task-manager/board'),
|
|
214
|
+
_ts_param(0, (0, _common.Inject)(_taskboardservice.TaskBoardService)),
|
|
215
|
+
_ts_metadata("design:type", Function),
|
|
216
|
+
_ts_metadata("design:paramtypes", [
|
|
217
|
+
typeof _taskboardservice.TaskBoardService === "undefined" ? Object : _taskboardservice.TaskBoardService
|
|
218
|
+
])
|
|
219
|
+
], TaskBoardController);
|