rez_core 6.5.72 → 6.5.73
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/dist/module/app_master/service/app-master.service.d.ts +3 -3
- package/dist/module/app_master/service/app-master.service.js +5 -5
- package/dist/module/app_master/service/app-master.service.js.map +1 -1
- package/dist/module/enterprise/controller/organization.controller.d.ts +1 -1
- package/dist/module/enterprise/controller/organization.controller.js +5 -1
- package/dist/module/enterprise/controller/organization.controller.js.map +1 -1
- package/dist/module/enterprise/service/organization.service.d.ts +9 -1
- package/dist/module/enterprise/service/organization.service.js +72 -7
- package/dist/module/enterprise/service/organization.service.js.map +1 -1
- package/dist/module/user/service/user-role-mapping.service.d.ts +3 -0
- package/dist/module/user/service/user-role-mapping.service.js +3 -0
- package/dist/module/user/service/user-role-mapping.service.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/app_master/service/app-master.service.ts +3 -2
- package/src/module/enterprise/controller/organization.controller.ts +9 -2
- package/src/module/enterprise/service/organization.service.ts +117 -11
- package/src/module/user/service/user-role-mapping.service.ts +8 -0
- package/.claude/settings.local.json +0 -26
- package/.idea/250218_nodejs_core.iml +0 -9
- package/.idea/codeStyles/Project.xml +0 -59
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/copilot.data.migration.agent.xml +0 -6
- package/.idea/copilot.data.migration.ask.xml +0 -6
- package/.idea/copilot.data.migration.ask2agent.xml +0 -6
- package/.idea/copilot.data.migration.edit.xml +0 -6
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/prettier.xml +0 -6
- package/.idea/vcs.xml +0 -6
- package/server.log +0 -850
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
2
|
import { UserRoleMappingRepository } from 'src/module/user/repository/user-role-mapping.repository';
|
|
3
3
|
import { AppMasterRespository } from '../repository/app-master.repository';
|
|
4
|
+
import { UserRoleMappingService } from 'src/module/user/service/user-role-mapping.service';
|
|
4
5
|
|
|
5
6
|
@Injectable()
|
|
6
7
|
export class AppMasterService {
|
|
7
8
|
constructor(
|
|
8
9
|
private readonly appMasterRepository: AppMasterRespository,
|
|
9
|
-
private readonly
|
|
10
|
+
private readonly userRoleMappingService:UserRoleMappingService
|
|
10
11
|
) {}
|
|
11
12
|
|
|
12
13
|
async getAppMasterDataByAppCode(userId: number) {
|
|
13
14
|
const app_code =
|
|
14
|
-
await this.
|
|
15
|
+
await this.userRoleMappingService.findDistinctAppcodeByUserId(userId);
|
|
15
16
|
|
|
16
17
|
const finalResult: any[] = [];
|
|
17
18
|
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
HttpCode,
|
|
13
13
|
HttpStatus,
|
|
14
14
|
ParseIntPipe,
|
|
15
|
+
BadRequestException,
|
|
15
16
|
} from '@nestjs/common';
|
|
16
17
|
import { Request } from 'express';
|
|
17
18
|
import { JwtAuthGuard } from 'src/module/auth/guards/jwt.guard';
|
|
@@ -79,9 +80,15 @@ export class OrganizationController {
|
|
|
79
80
|
@Param('id', ParseIntPipe) id: number,
|
|
80
81
|
@Body() organizationDto: Partial<OrganizationData>,
|
|
81
82
|
@Req() req: Request & { user: any },
|
|
82
|
-
): Promise<OrganizationData
|
|
83
|
+
): Promise<OrganizationData> {
|
|
83
84
|
const loggedInUser = req.user.userData;
|
|
84
|
-
|
|
85
|
+
const result = await this.orgService.update(id, organizationDto, loggedInUser);
|
|
86
|
+
|
|
87
|
+
if (!result.success) {
|
|
88
|
+
throw new BadRequestException(result.error);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return result.data;
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
@Delete(':id')
|
|
@@ -10,6 +10,11 @@ import { SchoolRepository } from '../repository/school.repository';
|
|
|
10
10
|
import { WBSCodeGenService } from 'src/utils/service/wbsCodeGen.service';
|
|
11
11
|
import { StatusConstant } from '../../../constant/status.constant';
|
|
12
12
|
|
|
13
|
+
// Type for update operation result
|
|
14
|
+
export type UpdateResult<T> =
|
|
15
|
+
| { success: true; data: T }
|
|
16
|
+
| { success: false; error: string };
|
|
17
|
+
|
|
13
18
|
@Injectable()
|
|
14
19
|
export class OrganizationService {
|
|
15
20
|
constructor(
|
|
@@ -138,7 +143,7 @@ export class OrganizationService {
|
|
|
138
143
|
organizationDto: Partial<OrganizationData>,
|
|
139
144
|
loggedInUser?: any,
|
|
140
145
|
manager?: EntityManager,
|
|
141
|
-
): Promise<OrganizationData
|
|
146
|
+
): Promise<UpdateResult<OrganizationData>> {
|
|
142
147
|
const repo = manager
|
|
143
148
|
? manager.getRepository(OrganizationData)
|
|
144
149
|
: this.organizationRepository;
|
|
@@ -146,12 +151,18 @@ export class OrganizationService {
|
|
|
146
151
|
// Get existing organization
|
|
147
152
|
const existingOrg = await repo.findOne({ where: { id } });
|
|
148
153
|
if (!existingOrg) {
|
|
149
|
-
|
|
154
|
+
return {
|
|
155
|
+
success: false,
|
|
156
|
+
error: `Organization with id ${id} not found.`,
|
|
157
|
+
};
|
|
150
158
|
}
|
|
151
159
|
|
|
152
160
|
// Prevent circular reference - check if trying to set itself as parent
|
|
153
161
|
if (organizationDto.parent_id === id) {
|
|
154
|
-
|
|
162
|
+
return {
|
|
163
|
+
success: false,
|
|
164
|
+
error: 'Organization cannot be its own parent.',
|
|
165
|
+
};
|
|
155
166
|
}
|
|
156
167
|
|
|
157
168
|
// Check if parent_id is being changed
|
|
@@ -161,7 +172,19 @@ export class OrganizationService {
|
|
|
161
172
|
|
|
162
173
|
// If parent_id is being set or changed, recalculate WBS code
|
|
163
174
|
if (parentIdChanged) {
|
|
175
|
+
// VALIDATION: Cannot change parent of organizations with WBS code length 5 or 11
|
|
176
|
+
const wbsCodeLength = existingOrg.wbs_code?.length || 0;
|
|
177
|
+
if (wbsCodeLength === 5 || wbsCodeLength === 11) {
|
|
178
|
+
return {
|
|
179
|
+
success: false,
|
|
180
|
+
error:
|
|
181
|
+
`Cannot change parent of organization with WBS code length ${wbsCodeLength}. ` +
|
|
182
|
+
`Organizations at this level (${existingOrg.wbs_code}) are locked and cannot be moved.`,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
164
186
|
const newParentId = organizationDto.parent_id;
|
|
187
|
+
const oldWbsCode = existingOrg.wbs_code;
|
|
165
188
|
|
|
166
189
|
if (newParentId) {
|
|
167
190
|
// Sub-org case: parent_id is being set
|
|
@@ -170,18 +193,39 @@ export class OrganizationService {
|
|
|
170
193
|
});
|
|
171
194
|
|
|
172
195
|
if (!parentOrg) {
|
|
173
|
-
|
|
196
|
+
return {
|
|
197
|
+
success: false,
|
|
198
|
+
error: 'Parent organization not found.',
|
|
199
|
+
};
|
|
174
200
|
}
|
|
175
201
|
|
|
176
202
|
if (!parentOrg.wbs_code) {
|
|
177
|
-
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
error: 'Parent organization must have a WBS code.',
|
|
206
|
+
};
|
|
178
207
|
}
|
|
179
208
|
|
|
180
|
-
// Prevent setting a descendant as parent
|
|
181
|
-
if
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
)
|
|
209
|
+
// CIRCULAR DEPENDENCY CHECK: Prevent setting a descendant as parent
|
|
210
|
+
// This checks if the proposed parent is actually a child/descendant of the current org
|
|
211
|
+
if (existingOrg.wbs_code && parentOrg.wbs_code) {
|
|
212
|
+
// Check if parent's WBS starts with current org's WBS (parent is a descendant)
|
|
213
|
+
if (parentOrg.wbs_code.startsWith(existingOrg.wbs_code + '.')) {
|
|
214
|
+
return {
|
|
215
|
+
success: false,
|
|
216
|
+
error:
|
|
217
|
+
`Cannot set organization ${parentOrg.wbs_code} as parent. ` +
|
|
218
|
+
`It is a descendant of ${existingOrg.wbs_code} (circular reference).`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Also check if they're the same (redundant with earlier check, but explicit)
|
|
223
|
+
if (parentOrg.wbs_code === existingOrg.wbs_code) {
|
|
224
|
+
return {
|
|
225
|
+
success: false,
|
|
226
|
+
error: 'Organization cannot be its own parent (circular reference).',
|
|
227
|
+
};
|
|
228
|
+
}
|
|
185
229
|
}
|
|
186
230
|
|
|
187
231
|
// Find existing sub-orgs with the same parent_id (excluding current org)
|
|
@@ -235,6 +279,17 @@ export class OrganizationService {
|
|
|
235
279
|
|
|
236
280
|
organizationDto.wbs_code = this.wbcCodeGenService.padCode(nextOrgCode);
|
|
237
281
|
}
|
|
282
|
+
|
|
283
|
+
// CASCADE UPDATE: Update all descendant organizations' WBS codes
|
|
284
|
+
const newWbsCode = organizationDto.wbs_code;
|
|
285
|
+
if (oldWbsCode && newWbsCode && oldWbsCode !== newWbsCode) {
|
|
286
|
+
await this.updateDescendantWbsCodes(
|
|
287
|
+
repo,
|
|
288
|
+
oldWbsCode,
|
|
289
|
+
newWbsCode,
|
|
290
|
+
loggedInUser,
|
|
291
|
+
);
|
|
292
|
+
}
|
|
238
293
|
}
|
|
239
294
|
|
|
240
295
|
// Set modified_by
|
|
@@ -243,7 +298,19 @@ export class OrganizationService {
|
|
|
243
298
|
}
|
|
244
299
|
|
|
245
300
|
await repo.update(id, organizationDto);
|
|
246
|
-
|
|
301
|
+
const updatedOrg = await repo.findOne({ where: { id } });
|
|
302
|
+
|
|
303
|
+
if (!updatedOrg) {
|
|
304
|
+
return {
|
|
305
|
+
success: false,
|
|
306
|
+
error: 'Failed to retrieve updated organization.',
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
success: true,
|
|
312
|
+
data: updatedOrg,
|
|
313
|
+
};
|
|
247
314
|
}
|
|
248
315
|
|
|
249
316
|
async remove(id: number, manager?: EntityManager): Promise<void> {
|
|
@@ -254,6 +321,45 @@ export class OrganizationService {
|
|
|
254
321
|
await repo.delete(id);
|
|
255
322
|
}
|
|
256
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Recursively updates WBS codes for all descendant organizations
|
|
326
|
+
* when a parent organization's WBS code changes
|
|
327
|
+
*/
|
|
328
|
+
private async updateDescendantWbsCodes(
|
|
329
|
+
repo: Repository<OrganizationData>,
|
|
330
|
+
oldWbsCode: string,
|
|
331
|
+
newWbsCode: string,
|
|
332
|
+
loggedInUser?: any,
|
|
333
|
+
): Promise<void> {
|
|
334
|
+
// Find all organizations whose WBS code starts with the old WBS code
|
|
335
|
+
// This will get all direct and indirect descendants
|
|
336
|
+
const descendants = await repo
|
|
337
|
+
.createQueryBuilder('org')
|
|
338
|
+
.where('org.wbs_code LIKE :pattern', { pattern: `${oldWbsCode}.%` })
|
|
339
|
+
.getMany();
|
|
340
|
+
|
|
341
|
+
// Update each descendant's WBS code
|
|
342
|
+
for (const descendant of descendants) {
|
|
343
|
+
if (descendant.wbs_code) {
|
|
344
|
+
// Replace the old WBS prefix with the new one
|
|
345
|
+
const updatedWbsCode = descendant.wbs_code.replace(
|
|
346
|
+
oldWbsCode,
|
|
347
|
+
newWbsCode,
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
const updateData: Partial<OrganizationData> = {
|
|
351
|
+
wbs_code: updatedWbsCode,
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
if (loggedInUser) {
|
|
355
|
+
updateData.modified_by = loggedInUser.id;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
await repo.update(descendant.id, updateData);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
257
363
|
async getOrganizationHierarchy(
|
|
258
364
|
userId: number,
|
|
259
365
|
appCode: string,
|
|
@@ -117,4 +117,12 @@ export class UserRoleMappingService {
|
|
|
117
117
|
// Let's assume it's a UserRoleMapping compatible object.
|
|
118
118
|
return await this.assignUserRole(data);
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
async findDistinctAppcodeByUserId(
|
|
122
|
+
userId: number,
|
|
123
|
+
): Promise<{ appcode: string[] }> {
|
|
124
|
+
return await this.userRoleMappingRepository.findDistinctAppcodeByUserId(
|
|
125
|
+
userId,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
120
128
|
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(npm run build:*)",
|
|
5
|
-
"Bash(npm install)",
|
|
6
|
-
"Bash(npm run lint)",
|
|
7
|
-
"Bash(npm install:*)",
|
|
8
|
-
"Bash(curl:*)",
|
|
9
|
-
"Bash(npm run start:dev:*)",
|
|
10
|
-
"Bash(mkdir:*)",
|
|
11
|
-
"Bash(lsof:*)",
|
|
12
|
-
"Bash(kill:*)",
|
|
13
|
-
"Bash(npx eslint:*)",
|
|
14
|
-
"Read(/Users/admin/yash/**)",
|
|
15
|
-
"Bash(timeout 15 npm run start:dev)",
|
|
16
|
-
"Read(/Users/admin/yash/**)",
|
|
17
|
-
"Bash(find:*)",
|
|
18
|
-
"Bash(sed:*)",
|
|
19
|
-
"Bash(git checkout:*)",
|
|
20
|
-
"Read(//Users/admin/yash/**)",
|
|
21
|
-
"Bash(npx tsc:*)"
|
|
22
|
-
],
|
|
23
|
-
"deny": [],
|
|
24
|
-
"ask": []
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="JAVA_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
-
<exclude-output />
|
|
5
|
-
<content url="file://$MODULE_DIR$" />
|
|
6
|
-
<orderEntry type="inheritedJdk" />
|
|
7
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
8
|
-
</component>
|
|
9
|
-
</module>
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
<component name="ProjectCodeStyleConfiguration">
|
|
2
|
-
<code_scheme name="Project" version="173">
|
|
3
|
-
<HTMLCodeStyleSettings>
|
|
4
|
-
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
|
5
|
-
</HTMLCodeStyleSettings>
|
|
6
|
-
<JSCodeStyleSettings version="0">
|
|
7
|
-
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
8
|
-
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
9
|
-
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
10
|
-
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
11
|
-
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
|
|
12
|
-
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
13
|
-
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
14
|
-
</JSCodeStyleSettings>
|
|
15
|
-
<TypeScriptCodeStyleSettings version="0">
|
|
16
|
-
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
17
|
-
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
|
18
|
-
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
19
|
-
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
20
|
-
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
|
|
21
|
-
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
22
|
-
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
23
|
-
</TypeScriptCodeStyleSettings>
|
|
24
|
-
<VueCodeStyleSettings>
|
|
25
|
-
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
|
26
|
-
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
|
27
|
-
</VueCodeStyleSettings>
|
|
28
|
-
<codeStyleSettings language="HTML">
|
|
29
|
-
<option name="SOFT_MARGINS" value="80" />
|
|
30
|
-
<indentOptions>
|
|
31
|
-
<option name="INDENT_SIZE" value="2" />
|
|
32
|
-
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
33
|
-
<option name="TAB_SIZE" value="2" />
|
|
34
|
-
</indentOptions>
|
|
35
|
-
</codeStyleSettings>
|
|
36
|
-
<codeStyleSettings language="JavaScript">
|
|
37
|
-
<option name="SOFT_MARGINS" value="80" />
|
|
38
|
-
<indentOptions>
|
|
39
|
-
<option name="INDENT_SIZE" value="2" />
|
|
40
|
-
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
41
|
-
<option name="TAB_SIZE" value="2" />
|
|
42
|
-
</indentOptions>
|
|
43
|
-
</codeStyleSettings>
|
|
44
|
-
<codeStyleSettings language="TypeScript">
|
|
45
|
-
<option name="SOFT_MARGINS" value="80" />
|
|
46
|
-
<indentOptions>
|
|
47
|
-
<option name="INDENT_SIZE" value="2" />
|
|
48
|
-
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
49
|
-
<option name="TAB_SIZE" value="2" />
|
|
50
|
-
</indentOptions>
|
|
51
|
-
</codeStyleSettings>
|
|
52
|
-
<codeStyleSettings language="Vue">
|
|
53
|
-
<option name="SOFT_MARGINS" value="80" />
|
|
54
|
-
<indentOptions>
|
|
55
|
-
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
56
|
-
</indentOptions>
|
|
57
|
-
</codeStyleSettings>
|
|
58
|
-
</code_scheme>
|
|
59
|
-
</component>
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<component name="InspectionProjectProfileManager">
|
|
2
|
-
<profile version="1.0">
|
|
3
|
-
<option name="myName" value="Project Default" />
|
|
4
|
-
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
|
5
|
-
</profile>
|
|
6
|
-
</component>
|
package/.idea/misc.xml
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
|
4
|
-
<output url="file://$PROJECT_DIR$/out" />
|
|
5
|
-
</component>
|
|
6
|
-
</project>
|
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/250218_nodejs_core.iml" filepath="$PROJECT_DIR$/.idea/250218_nodejs_core.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
package/.idea/prettier.xml
DELETED