@flusys/nestjs-task-manager 7.1.0 → 8.0.0-beta.1

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.
Files changed (163) hide show
  1. package/config/index.d.ts +3 -3
  2. package/controllers/index.d.ts +5 -5
  3. package/controllers/task-board.controller.d.ts +3 -3
  4. package/controllers/task-comment.controller.d.ts +2 -2
  5. package/controllers/task-label.controller.d.ts +2 -2
  6. package/controllers/task-list.controller.d.ts +3 -3
  7. package/controllers/task.controller.d.ts +4 -4
  8. package/docs/index.d.ts +1 -1
  9. package/docs/task-manager-swagger.config.d.ts +1 -1
  10. package/dtos/index.d.ts +5 -5
  11. package/dtos/task-board.dto.d.ts +1 -1
  12. package/dtos/task.dto.d.ts +2 -2
  13. package/entities/index.d.ts +19 -19
  14. package/entities/task-board-with-company.entity.d.ts +1 -1
  15. package/fesm/234.js +1393 -0
  16. package/fesm/431.js +981 -0
  17. package/fesm/827.js +1054 -0
  18. package/fesm/988.js +881 -0
  19. package/fesm/config/index.js +156 -3
  20. package/fesm/controllers/index.js +21 -5
  21. package/fesm/docs/index.js +58 -1
  22. package/fesm/dtos/index.js +280 -5
  23. package/fesm/entities/index.js +26 -46
  24. package/fesm/gateways/index.js +288 -1
  25. package/fesm/index.js +440 -9
  26. package/fesm/interfaces/index.js +16 -2
  27. package/fesm/modules/index.js +210 -1
  28. package/fesm/runtime.js +85 -0
  29. package/fesm/services/index.js +53 -8
  30. package/gateways/index.d.ts +1 -1
  31. package/gateways/task-board.gateway.d.ts +3 -3
  32. package/index.d.ts +9 -9
  33. package/interfaces/index.d.ts +2 -2
  34. package/interfaces/task-manager-module.interface.d.ts +3 -3
  35. package/interfaces/task.interface.d.ts +2 -2
  36. package/modules/index.d.ts +1 -1
  37. package/modules/task-manager.module.d.ts +2 -2
  38. package/package.json +26 -36
  39. package/services/index.d.ts +8 -8
  40. package/services/task-activity.service.d.ts +1 -1
  41. package/services/task-board.service.d.ts +5 -5
  42. package/services/task-comment.service.d.ts +4 -4
  43. package/services/task-label.service.d.ts +4 -4
  44. package/services/task-list.service.d.ts +4 -4
  45. package/services/task-manager-config.service.d.ts +3 -3
  46. package/services/task-manager-datasource.provider.d.ts +3 -3
  47. package/services/task.service.d.ts +7 -7
  48. package/cjs/config/event-actions.js +0 -37
  49. package/cjs/config/index.js +0 -20
  50. package/cjs/config/message-keys.js +0 -92
  51. package/cjs/config/task-manager.constants.js +0 -11
  52. package/cjs/controllers/index.js +0 -22
  53. package/cjs/controllers/task-board.controller.js +0 -219
  54. package/cjs/controllers/task-board.controller.spec.js +0 -132
  55. package/cjs/controllers/task-comment.controller.js +0 -103
  56. package/cjs/controllers/task-comment.controller.spec.js +0 -86
  57. package/cjs/controllers/task-label.controller.js +0 -112
  58. package/cjs/controllers/task-label.controller.spec.js +0 -88
  59. package/cjs/controllers/task-list.controller.js +0 -158
  60. package/cjs/controllers/task-list.controller.spec.js +0 -112
  61. package/cjs/controllers/task.controller.js +0 -199
  62. package/cjs/controllers/task.controller.spec.js +0 -131
  63. package/cjs/docs/index.js +0 -18
  64. package/cjs/docs/task-manager-swagger.config.js +0 -43
  65. package/cjs/docs/task-manager-swagger.config.spec.js +0 -28
  66. package/cjs/dtos/index.js +0 -22
  67. package/cjs/dtos/task-board.dto.js +0 -310
  68. package/cjs/dtos/task-comment.dto.js +0 -131
  69. package/cjs/dtos/task-label.dto.js +0 -120
  70. package/cjs/dtos/task-list.dto.js +0 -198
  71. package/cjs/dtos/task.dto.js +0 -367
  72. package/cjs/entities/index.js +0 -72
  73. package/cjs/entities/index.spec.js +0 -30
  74. package/cjs/entities/task-activity.entity.js +0 -98
  75. package/cjs/entities/task-assignee.entity.js +0 -67
  76. package/cjs/entities/task-board-member.entity.js +0 -94
  77. package/cjs/entities/task-board-with-company.entity.js +0 -57
  78. package/cjs/entities/task-board.entity.js +0 -88
  79. package/cjs/entities/task-comment.entity.js +0 -80
  80. package/cjs/entities/task-label.entity.js +0 -72
  81. package/cjs/entities/task-list.entity.js +0 -104
  82. package/cjs/entities/task-task-label.entity.js +0 -67
  83. package/cjs/entities/task.entity.js +0 -151
  84. package/cjs/gateways/index.js +0 -18
  85. package/cjs/gateways/task-board.gateway.js +0 -167
  86. package/cjs/gateways/task-board.gateway.spec.js +0 -243
  87. package/cjs/index.js +0 -26
  88. package/cjs/interfaces/index.js +0 -19
  89. package/cjs/interfaces/task-manager-module.interface.js +0 -4
  90. package/cjs/interfaces/task.interface.js +0 -4
  91. package/cjs/modules/index.js +0 -18
  92. package/cjs/modules/task-manager.module.js +0 -135
  93. package/cjs/modules/task-manager.module.spec.js +0 -144
  94. package/cjs/services/index.js +0 -25
  95. package/cjs/services/task-activity.service.js +0 -76
  96. package/cjs/services/task-activity.service.spec.js +0 -125
  97. package/cjs/services/task-board.service.js +0 -247
  98. package/cjs/services/task-board.service.spec.js +0 -465
  99. package/cjs/services/task-comment.service.js +0 -103
  100. package/cjs/services/task-comment.service.spec.js +0 -160
  101. package/cjs/services/task-label.service.js +0 -97
  102. package/cjs/services/task-label.service.spec.js +0 -138
  103. package/cjs/services/task-list.service.js +0 -130
  104. package/cjs/services/task-list.service.spec.js +0 -284
  105. package/cjs/services/task-manager-config.service.js +0 -69
  106. package/cjs/services/task-manager-config.service.spec.js +0 -98
  107. package/cjs/services/task-manager-datasource.provider.js +0 -84
  108. package/cjs/services/task-manager-datasource.provider.spec.js +0 -131
  109. package/cjs/services/task.service.js +0 -398
  110. package/cjs/services/task.service.spec.js +0 -700
  111. package/fesm/config/event-actions.js +0 -16
  112. package/fesm/config/message-keys.js +0 -65
  113. package/fesm/config/task-manager.constants.js +0 -1
  114. package/fesm/controllers/task-board.controller.js +0 -209
  115. package/fesm/controllers/task-board.controller.spec.js +0 -128
  116. package/fesm/controllers/task-comment.controller.js +0 -93
  117. package/fesm/controllers/task-comment.controller.spec.js +0 -82
  118. package/fesm/controllers/task-label.controller.js +0 -102
  119. package/fesm/controllers/task-label.controller.spec.js +0 -84
  120. package/fesm/controllers/task-list.controller.js +0 -148
  121. package/fesm/controllers/task-list.controller.spec.js +0 -108
  122. package/fesm/controllers/task.controller.js +0 -189
  123. package/fesm/controllers/task.controller.spec.js +0 -127
  124. package/fesm/docs/task-manager-swagger.config.js +0 -33
  125. package/fesm/docs/task-manager-swagger.config.spec.js +0 -24
  126. package/fesm/dtos/task-board.dto.js +0 -277
  127. package/fesm/dtos/task-comment.dto.js +0 -110
  128. package/fesm/dtos/task-label.dto.js +0 -99
  129. package/fesm/dtos/task-list.dto.js +0 -174
  130. package/fesm/dtos/task.dto.js +0 -337
  131. package/fesm/entities/index.spec.js +0 -26
  132. package/fesm/entities/task-activity.entity.js +0 -88
  133. package/fesm/entities/task-assignee.entity.js +0 -57
  134. package/fesm/entities/task-board-member.entity.js +0 -76
  135. package/fesm/entities/task-board-with-company.entity.js +0 -47
  136. package/fesm/entities/task-board.entity.js +0 -78
  137. package/fesm/entities/task-comment.entity.js +0 -70
  138. package/fesm/entities/task-label.entity.js +0 -62
  139. package/fesm/entities/task-list.entity.js +0 -94
  140. package/fesm/entities/task-task-label.entity.js +0 -57
  141. package/fesm/entities/task.entity.js +0 -133
  142. package/fesm/gateways/task-board.gateway.js +0 -157
  143. package/fesm/gateways/task-board.gateway.spec.js +0 -239
  144. package/fesm/interfaces/task-manager-module.interface.js +0 -1
  145. package/fesm/interfaces/task.interface.js +0 -1
  146. package/fesm/modules/task-manager.module.js +0 -125
  147. package/fesm/modules/task-manager.module.spec.js +0 -140
  148. package/fesm/services/task-activity.service.js +0 -66
  149. package/fesm/services/task-activity.service.spec.js +0 -121
  150. package/fesm/services/task-board.service.js +0 -237
  151. package/fesm/services/task-board.service.spec.js +0 -461
  152. package/fesm/services/task-comment.service.js +0 -93
  153. package/fesm/services/task-comment.service.spec.js +0 -156
  154. package/fesm/services/task-label.service.js +0 -87
  155. package/fesm/services/task-label.service.spec.js +0 -134
  156. package/fesm/services/task-list.service.js +0 -120
  157. package/fesm/services/task-list.service.spec.js +0 -280
  158. package/fesm/services/task-manager-config.service.js +0 -59
  159. package/fesm/services/task-manager-config.service.spec.js +0 -94
  160. package/fesm/services/task-manager-datasource.provider.js +0 -74
  161. package/fesm/services/task-manager-datasource.provider.spec.js +0 -127
  162. package/fesm/services/task.service.js +0 -388
  163. package/fesm/services/task.service.spec.js +0 -696
@@ -1,156 +0,0 @@
1
- import { Test } from '@nestjs/testing';
2
- import { UtilsService } from '@flusys/nestjs-shared/modules';
3
- import { createMockDataSourceProvider, createMockQueryBuilder, createMockRepository } from '@test-utils/mocks/repository.mock';
4
- import { buildMockUser } from '@test-utils/mocks/logged-user.mock';
5
- import { TaskCommentService } from './task-comment.service';
6
- import { TaskManagerDataSourceProvider } from './task-manager-datasource.provider';
7
- function buildTaskComment(overrides = {}) {
8
- return {
9
- id: 'comment-uuid-1',
10
- taskId: 'task-uuid-1',
11
- userId: 'user-uuid-1',
12
- content: 'Original comment',
13
- parentCommentId: null,
14
- createdAt: new Date(),
15
- updatedAt: new Date(),
16
- deletedAt: null,
17
- createdById: null,
18
- updatedById: null,
19
- deletedById: null,
20
- ...overrides
21
- };
22
- }
23
- function mockQueryRunner(repo) {
24
- const qr = {
25
- connect: jest.fn().mockResolvedValue(undefined),
26
- startTransaction: jest.fn().mockResolvedValue(undefined),
27
- commitTransaction: jest.fn().mockResolvedValue(undefined),
28
- rollbackTransaction: jest.fn().mockResolvedValue(undefined),
29
- release: jest.fn().mockResolvedValue(undefined),
30
- manager: {
31
- save: jest.fn((_target, entities)=>Promise.resolve(entities))
32
- }
33
- };
34
- repo.manager.connection.createQueryRunner.mockReturnValue(qr);
35
- return qr;
36
- }
37
- describe('TaskCommentService', ()=>{
38
- let service;
39
- let mockRepo;
40
- beforeEach(async ()=>{
41
- mockRepo = createMockRepository();
42
- const mockDataSourceProvider = createMockDataSourceProvider(mockRepo);
43
- const module = await Test.createTestingModule({
44
- providers: [
45
- TaskCommentService,
46
- {
47
- provide: 'CACHE_INSTANCE',
48
- useValue: {}
49
- },
50
- {
51
- provide: UtilsService,
52
- useValue: {
53
- clearCache: jest.fn(),
54
- getCacheKey: jest.fn(),
55
- trackCacheKey: jest.fn()
56
- }
57
- },
58
- {
59
- provide: TaskManagerDataSourceProvider,
60
- useValue: mockDataSourceProvider
61
- }
62
- ]
63
- }).compile();
64
- service = await module.resolve(TaskCommentService);
65
- });
66
- describe('convertSingleDtoToEntity (via insert)', ()=>{
67
- it('creates a top-level comment authored by the current user', async ()=>{
68
- mockQueryRunner(mockRepo);
69
- const user = buildMockUser({
70
- id: 'author-1'
71
- });
72
- const result = await service.insert({
73
- taskId: 'task-1',
74
- content: 'Nice work'
75
- }, user);
76
- expect(result).toEqual(expect.objectContaining({
77
- taskId: 'task-1',
78
- userId: 'author-1',
79
- content: 'Nice work',
80
- parentCommentId: null
81
- }));
82
- });
83
- it('creates a reply comment carrying the parentCommentId', async ()=>{
84
- mockQueryRunner(mockRepo);
85
- const result = await service.insert({
86
- taskId: 'task-1',
87
- content: 'Reply',
88
- parentCommentId: 'comment-parent-1'
89
- }, buildMockUser());
90
- expect(result).toEqual(expect.objectContaining({
91
- parentCommentId: 'comment-parent-1'
92
- }));
93
- });
94
- });
95
- describe('convertSingleDtoToEntity (via update)', ()=>{
96
- it('throws NotFoundException when the comment does not exist', async ()=>{
97
- mockQueryRunner(mockRepo);
98
- mockRepo.findOne.mockResolvedValue(null);
99
- await expect(service.update({
100
- id: 'missing',
101
- content: 'Edited'
102
- }, buildMockUser())).rejects.toThrow();
103
- });
104
- it('throws ForbiddenException when editing a comment authored by another user', async ()=>{
105
- mockQueryRunner(mockRepo);
106
- const existing = buildTaskComment({
107
- id: 'comment-1',
108
- userId: 'someone-else'
109
- });
110
- mockRepo.findOne.mockResolvedValue(existing);
111
- await expect(service.update({
112
- id: 'comment-1',
113
- content: 'Edited'
114
- }, buildMockUser({
115
- id: 'not-the-author'
116
- }))).rejects.toThrow();
117
- });
118
- it('allows the original author to edit their own comment', async ()=>{
119
- mockQueryRunner(mockRepo);
120
- const existing = buildTaskComment({
121
- id: 'comment-1',
122
- userId: 'author-1',
123
- content: 'Old'
124
- });
125
- mockRepo.findOne.mockResolvedValue(existing);
126
- const result = await service.update({
127
- id: 'comment-1',
128
- content: 'Updated content'
129
- }, buildMockUser({
130
- id: 'author-1'
131
- }));
132
- expect(result).toEqual(expect.objectContaining({
133
- id: 'comment-1',
134
- content: 'Updated content'
135
- }));
136
- });
137
- });
138
- describe('getFilterQuery', ()=>{
139
- it('filters by taskId when supplied', async ()=>{
140
- const qb = createMockQueryBuilder();
141
- const { query, isRaw } = await service.getFilterQuery(qb, {
142
- taskId: 'task-1'
143
- }, buildMockUser());
144
- expect(qb.andWhere).toHaveBeenCalledWith('task_comment.taskId = :taskId', {
145
- taskId: 'task-1'
146
- });
147
- expect(isRaw).toBe(false);
148
- expect(query).toBe(qb);
149
- });
150
- it('applies no filter when taskId is absent', async ()=>{
151
- const qb = createMockQueryBuilder();
152
- await service.getFilterQuery(qb, {}, buildMockUser());
153
- expect(qb.andWhere).not.toHaveBeenCalled();
154
- });
155
- });
156
- });
@@ -1,87 +0,0 @@
1
- function _define_property(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
- return obj;
13
- }
14
- function _ts_decorate(decorators, target, key, desc) {
15
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
- 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;
18
- return c > 3 && r && Object.defineProperty(target, key, r), r;
19
- }
20
- function _ts_metadata(k, v) {
21
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
- }
23
- function _ts_param(paramIndex, decorator) {
24
- return function(target, key) {
25
- decorator(target, key, paramIndex);
26
- };
27
- }
28
- import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
29
- import { UtilsService } from '@flusys/nestjs-shared/modules';
30
- import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common';
31
- import { TASK_LABEL_MESSAGES, TASK_MANAGER_EVENT_ENTITIES, TASK_MANAGER_EVENT_MODULE } from '../config';
32
- import { TaskLabel } from '../entities';
33
- import { TaskManagerDataSourceProvider } from './task-manager-datasource.provider';
34
- export class TaskLabelService extends ApiService {
35
- async convertSingleDtoToEntity(dto, _user) {
36
- await this.ensureDataSourceRepository();
37
- let entity = {};
38
- if ('id' in dto && dto.id) {
39
- const existing = await this.repository.findOne({
40
- where: {
41
- id: dto.id
42
- }
43
- });
44
- if (!existing) throw new NotFoundException({
45
- message: 'Label not found',
46
- messageKey: TASK_LABEL_MESSAGES.NOT_FOUND
47
- });
48
- entity = existing;
49
- }
50
- return {
51
- ...entity,
52
- boardId: dto.boardId ?? entity.boardId,
53
- name: dto.name ?? entity.name,
54
- color: dto.color ?? entity.color ?? '#10B981'
55
- };
56
- }
57
- async getFilterQuery(query, filter, _user) {
58
- for (const [key, value] of Object.entries(filter)){
59
- if (key === 'boardId') {
60
- query.andWhere('task_label.boardId = :boardId', {
61
- boardId: value
62
- });
63
- }
64
- }
65
- return {
66
- query,
67
- isRaw: false
68
- };
69
- }
70
- constructor(cacheManager, utilsService, dataSourceProvider){
71
- super(TASK_MANAGER_EVENT_ENTITIES.TASK_LABEL, cacheManager, utilsService, TaskLabelService.name, true, TASK_MANAGER_EVENT_MODULE, dataSourceProvider, TaskLabel), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider;
72
- }
73
- }
74
- TaskLabelService = _ts_decorate([
75
- Injectable({
76
- scope: Scope.REQUEST
77
- }),
78
- _ts_param(0, Inject('CACHE_INSTANCE')),
79
- _ts_param(1, Inject(UtilsService)),
80
- _ts_param(2, Inject(TaskManagerDataSourceProvider)),
81
- _ts_metadata("design:type", Function),
82
- _ts_metadata("design:paramtypes", [
83
- typeof HybridCache === "undefined" ? Object : HybridCache,
84
- typeof UtilsService === "undefined" ? Object : UtilsService,
85
- typeof TaskManagerDataSourceProvider === "undefined" ? Object : TaskManagerDataSourceProvider
86
- ])
87
- ], TaskLabelService);
@@ -1,134 +0,0 @@
1
- import { Test } from '@nestjs/testing';
2
- import { UtilsService } from '@flusys/nestjs-shared/modules';
3
- import { createMockDataSourceProvider, createMockQueryBuilder, createMockRepository } from '@test-utils/mocks/repository.mock';
4
- import { buildMockUser } from '@test-utils/mocks/logged-user.mock';
5
- import { TaskLabelService } from './task-label.service';
6
- import { TaskManagerDataSourceProvider } from './task-manager-datasource.provider';
7
- function buildTaskLabel(overrides = {}) {
8
- return {
9
- id: 'label-uuid-1',
10
- boardId: 'board-uuid-1',
11
- name: 'Bug',
12
- color: '#10B981',
13
- createdAt: new Date(),
14
- updatedAt: new Date(),
15
- deletedAt: null,
16
- createdById: null,
17
- updatedById: null,
18
- deletedById: null,
19
- ...overrides
20
- };
21
- }
22
- function mockQueryRunner(repo) {
23
- const qr = {
24
- connect: jest.fn().mockResolvedValue(undefined),
25
- startTransaction: jest.fn().mockResolvedValue(undefined),
26
- commitTransaction: jest.fn().mockResolvedValue(undefined),
27
- rollbackTransaction: jest.fn().mockResolvedValue(undefined),
28
- release: jest.fn().mockResolvedValue(undefined),
29
- manager: {
30
- save: jest.fn((_target, entities)=>Promise.resolve(entities))
31
- }
32
- };
33
- repo.manager.connection.createQueryRunner.mockReturnValue(qr);
34
- return qr;
35
- }
36
- describe('TaskLabelService', ()=>{
37
- let service;
38
- let mockRepo;
39
- beforeEach(async ()=>{
40
- mockRepo = createMockRepository();
41
- const mockDataSourceProvider = createMockDataSourceProvider(mockRepo);
42
- const module = await Test.createTestingModule({
43
- providers: [
44
- TaskLabelService,
45
- {
46
- provide: 'CACHE_INSTANCE',
47
- useValue: {}
48
- },
49
- {
50
- provide: UtilsService,
51
- useValue: {
52
- clearCache: jest.fn(),
53
- getCacheKey: jest.fn(),
54
- trackCacheKey: jest.fn()
55
- }
56
- },
57
- {
58
- provide: TaskManagerDataSourceProvider,
59
- useValue: mockDataSourceProvider
60
- }
61
- ]
62
- }).compile();
63
- service = await module.resolve(TaskLabelService);
64
- });
65
- describe('convertSingleDtoToEntity (via insert/update)', ()=>{
66
- it('creates a label applying the default color when none is given', async ()=>{
67
- mockQueryRunner(mockRepo);
68
- const result = await service.insert({
69
- boardId: 'board-1',
70
- name: 'Bug'
71
- }, buildMockUser());
72
- expect(result).toEqual(expect.objectContaining({
73
- boardId: 'board-1',
74
- name: 'Bug',
75
- color: '#10B981'
76
- }));
77
- });
78
- it('respects an explicit color on create', async ()=>{
79
- mockQueryRunner(mockRepo);
80
- const result = await service.insert({
81
- boardId: 'board-1',
82
- name: 'Urgent',
83
- color: '#EF4444'
84
- }, buildMockUser());
85
- expect(result).toEqual(expect.objectContaining({
86
- color: '#EF4444'
87
- }));
88
- });
89
- it('throws NotFoundException when updating a non-existent label', async ()=>{
90
- mockQueryRunner(mockRepo);
91
- mockRepo.findOne.mockResolvedValue(null);
92
- await expect(service.update({
93
- id: 'missing',
94
- name: 'Renamed'
95
- }, buildMockUser())).rejects.toThrow();
96
- });
97
- it('merges update fields onto the existing entity', async ()=>{
98
- mockQueryRunner(mockRepo);
99
- const existing = buildTaskLabel({
100
- id: 'label-1',
101
- name: 'Old',
102
- color: '#000000'
103
- });
104
- mockRepo.findOne.mockResolvedValue(existing);
105
- const result = await service.update({
106
- id: 'label-1',
107
- name: 'New'
108
- }, buildMockUser());
109
- expect(result).toEqual(expect.objectContaining({
110
- id: 'label-1',
111
- name: 'New',
112
- color: '#000000'
113
- }));
114
- });
115
- });
116
- describe('getFilterQuery', ()=>{
117
- it('filters by boardId when supplied', async ()=>{
118
- const qb = createMockQueryBuilder();
119
- const { query, isRaw } = await service.getFilterQuery(qb, {
120
- boardId: 'board-1'
121
- }, buildMockUser());
122
- expect(qb.andWhere).toHaveBeenCalledWith('task_label.boardId = :boardId', {
123
- boardId: 'board-1'
124
- });
125
- expect(isRaw).toBe(false);
126
- expect(query).toBe(qb);
127
- });
128
- it('applies no filter when boardId is absent', async ()=>{
129
- const qb = createMockQueryBuilder();
130
- await service.getFilterQuery(qb, {}, buildMockUser());
131
- expect(qb.andWhere).not.toHaveBeenCalled();
132
- });
133
- });
134
- });
@@ -1,120 +0,0 @@
1
- function _define_property(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
- return obj;
13
- }
14
- function _ts_decorate(decorators, target, key, desc) {
15
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
- 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;
18
- return c > 3 && r && Object.defineProperty(target, key, r), r;
19
- }
20
- function _ts_metadata(k, v) {
21
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
- }
23
- function _ts_param(paramIndex, decorator) {
24
- return function(target, key) {
25
- decorator(target, key, paramIndex);
26
- };
27
- }
28
- import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
29
- import { UtilsService } from '@flusys/nestjs-shared/modules';
30
- import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common';
31
- import { TASK_LIST_MESSAGES, TASK_MANAGER_EVENT_ACTIONS, TASK_MANAGER_EVENT_ENTITIES, TASK_MANAGER_EVENT_MODULE } from '../config';
32
- import { TaskList } from '../entities';
33
- import { TaskManagerDataSourceProvider } from './task-manager-datasource.provider';
34
- export class TaskListService extends ApiService {
35
- /** Boards cache denormalized `total_tasks` / `total_lists`, so board caches go stale on any write here. */ async clearCacheForAll() {
36
- await super.clearCacheForAll();
37
- await this.utilsService.clearCache(TASK_MANAGER_EVENT_ENTITIES.TASK_BOARD, this.cacheManager);
38
- }
39
- async convertSingleDtoToEntity(dto, _user) {
40
- await this.ensureDataSourceRepository();
41
- let entity = {};
42
- if ('id' in dto && dto.id) {
43
- const existing = await this.repository.findOne({
44
- where: {
45
- id: dto.id
46
- }
47
- });
48
- if (!existing) throw new NotFoundException({
49
- message: 'List not found',
50
- messageKey: TASK_LIST_MESSAGES.NOT_FOUND
51
- });
52
- entity = existing;
53
- }
54
- return {
55
- ...entity,
56
- boardId: dto.boardId ?? entity.boardId,
57
- name: dto.name ?? entity.name,
58
- color: dto.color ?? entity.color ?? '#6B7280',
59
- position: dto.position ?? entity.position ?? 0,
60
- isDoneList: ('isDoneList' in dto ? dto.isDoneList : undefined) ?? entity.isDoneList ?? false,
61
- isActive: ('isActive' in dto ? dto.isActive : undefined) ?? entity.isActive ?? true
62
- };
63
- }
64
- async getFilterQuery(query, filter, _user) {
65
- for (const [key, value] of Object.entries(filter)){
66
- if (key === 'boardId') {
67
- query.andWhere('task_list.boardId = :boardId', {
68
- boardId: value
69
- });
70
- } else if (key === 'isActive' && typeof value === 'boolean') {
71
- query.andWhere('task_list.isActive = :isActive', {
72
- isActive: value
73
- });
74
- }
75
- }
76
- query.orderBy('task_list.position', 'ASC');
77
- return {
78
- query,
79
- isRaw: false
80
- };
81
- }
82
- async reorderLists(dto) {
83
- await this.ensureDataSourceRepository();
84
- await Promise.all(dto.orderedIds.map((id, i)=>this.repository.update({
85
- id,
86
- boardId: dto.boardId
87
- }, {
88
- position: i * 100
89
- })));
90
- await Promise.all([
91
- this.clearCacheForAll(),
92
- this.clearCacheForId(dto.orderedIds.map((id)=>({
93
- id
94
- })))
95
- ]);
96
- await this.publishDomainAction(TASK_MANAGER_EVENT_ACTIONS.REORDERED, {
97
- ids: dto.orderedIds,
98
- metadata: {
99
- boardId: dto.boardId
100
- }
101
- });
102
- }
103
- constructor(cacheManager, utilsService, dataSourceProvider){
104
- super(TASK_MANAGER_EVENT_ENTITIES.TASK_LIST, cacheManager, utilsService, TaskListService.name, true, TASK_MANAGER_EVENT_MODULE, dataSourceProvider, TaskList), _define_property(this, "cacheManager", void 0), _define_property(this, "utilsService", void 0), _define_property(this, "dataSourceProvider", void 0), this.cacheManager = cacheManager, this.utilsService = utilsService, this.dataSourceProvider = dataSourceProvider;
105
- }
106
- }
107
- TaskListService = _ts_decorate([
108
- Injectable({
109
- scope: Scope.REQUEST
110
- }),
111
- _ts_param(0, Inject('CACHE_INSTANCE')),
112
- _ts_param(1, Inject(UtilsService)),
113
- _ts_param(2, Inject(TaskManagerDataSourceProvider)),
114
- _ts_metadata("design:type", Function),
115
- _ts_metadata("design:paramtypes", [
116
- typeof HybridCache === "undefined" ? Object : HybridCache,
117
- typeof UtilsService === "undefined" ? Object : UtilsService,
118
- typeof TaskManagerDataSourceProvider === "undefined" ? Object : TaskManagerDataSourceProvider
119
- ])
120
- ], TaskListService);