rez_core 3.1.199 → 3.1.201
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/meta/controller/media.controller.d.ts +3 -0
- package/dist/module/meta/controller/media.controller.js +15 -0
- package/dist/module/meta/controller/media.controller.js.map +1 -1
- package/dist/module/meta/entity/entity-master.entity.d.ts +2 -0
- package/dist/module/meta/entity/entity-master.entity.js +8 -0
- package/dist/module/meta/entity/entity-master.entity.js.map +1 -1
- package/dist/module/meta/service/media-data.service.d.ts +5 -1
- package/dist/module/meta/service/media-data.service.js +59 -2
- package/dist/module/meta/service/media-data.service.js.map +1 -1
- package/dist/module/notification/service/notification.service.js +1 -1
- package/dist/module/workflow/repository/activity-log.repository.js +1 -1
- package/dist/module/workflow/service/stage-group.service.js +1 -1
- package/dist/module/workflow/service/task.service.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/module/meta/controller/media.controller.ts +10 -0
- package/src/module/meta/entity/entity-master.entity.ts +6 -0
- package/src/module/meta/service/media-data.service.ts +92 -1
- package/src/module/notification/service/notification.service.ts +1 -1
- package/src/module/workflow/repository/activity-log.repository.ts +1 -1
- package/src/module/workflow/service/stage-group.service.ts +1 -1
- package/src/module/workflow/service/task.service.ts +1 -1
package/package.json
CHANGED
|
@@ -79,4 +79,14 @@ export class MediaController {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
+
|
|
83
|
+
@Post('generateUploadPath')
|
|
84
|
+
async generateUploadPath(@Req() req: Request & { user: any }, @Query('mapped_entity_type') mapped_entity_type: string,
|
|
85
|
+
@Query('mapped_entity_id') mapped_entity_id?: number,
|
|
86
|
+
@Query('parent_id') parent_id?: number,
|
|
87
|
+
@Query('parent_type') parent_type?: string,
|
|
88
|
+
) {
|
|
89
|
+
const loggedInUser = req.user.userData;
|
|
90
|
+
return this.mediaDataService.buildUploadPathGeneric(mapped_entity_type, loggedInUser, mapped_entity_id,parent_id, parent_type)
|
|
91
|
+
}
|
|
82
92
|
}
|
|
@@ -75,4 +75,10 @@ export class EntityMaster extends BaseEntity {
|
|
|
75
75
|
|
|
76
76
|
@Column({ name: 'is_workflow', nullable: true })
|
|
77
77
|
is_workflow: boolean;
|
|
78
|
+
|
|
79
|
+
@Column({ name: 'doc_upload_path', nullable: true, length:50 })
|
|
80
|
+
doc_upload_path: string;
|
|
81
|
+
|
|
82
|
+
@Column({name: 'overwrite_path', type: 'tinyint', nullable: true})
|
|
83
|
+
overwrite_path: number;
|
|
78
84
|
}
|
|
@@ -9,12 +9,16 @@ import {
|
|
|
9
9
|
STATUS_PENDING,
|
|
10
10
|
} from '../../../constant/global.constant';
|
|
11
11
|
import { v4 as uuidv4 } from 'uuid';
|
|
12
|
+
import { OrganizationService } from '../../enterprise/service/organization.service';
|
|
13
|
+
import { EntityMasterService } from './entity-master.service';
|
|
14
|
+
import { DataSource } from 'typeorm';
|
|
12
15
|
|
|
13
16
|
@Injectable()
|
|
14
17
|
export class MediaDataService extends EntityServiceImpl {
|
|
15
18
|
constructor(
|
|
16
19
|
private readonly configService: ConfigService,
|
|
17
20
|
private readonly mediaRepository: MediaDataRepository,
|
|
21
|
+
private dataSource: DataSource,
|
|
18
22
|
) {
|
|
19
23
|
super();
|
|
20
24
|
}
|
|
@@ -44,6 +48,8 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
44
48
|
const ext = fileName.split('.').pop()?.toLowerCase() ?? '';
|
|
45
49
|
|
|
46
50
|
const id = uuidv4();
|
|
51
|
+
|
|
52
|
+
//TODO:
|
|
47
53
|
const s3Key = `uploads/${id}.${ext}`;
|
|
48
54
|
|
|
49
55
|
const uploadUrl = await this.s3.getSignedUrlPromise('putObject', {
|
|
@@ -140,10 +146,95 @@ export class MediaDataService extends EntityServiceImpl {
|
|
|
140
146
|
Key: mediaData.media_url,
|
|
141
147
|
Expires: Number(expiresIn) || 60 * 5,
|
|
142
148
|
});
|
|
143
|
-
return { signedUrl, fileName: mediaData.file_name, id: mediaData.id, size: fileSize};
|
|
149
|
+
return { signedUrl, fileName: mediaData.file_name, id: mediaData.id, size: fileSize };
|
|
144
150
|
} catch (error) {
|
|
145
151
|
console.error('Error generating signed URL for media:', error);
|
|
146
152
|
throw new Error('Failed to generate signed URL');
|
|
147
153
|
}
|
|
148
154
|
}
|
|
155
|
+
|
|
156
|
+
public async buildUploadPathGeneric(
|
|
157
|
+
mappedEntityType: string,
|
|
158
|
+
loggedInUser,
|
|
159
|
+
mappedEntityId?: number,
|
|
160
|
+
parentId?: number,
|
|
161
|
+
parentType?: string,
|
|
162
|
+
) {
|
|
163
|
+
// 1️⃣ Fetch entity metadata
|
|
164
|
+
const entityMaster = await this.entityMasterService.getEntityData(mappedEntityType, loggedInUser);
|
|
165
|
+
if (!entityMaster) {
|
|
166
|
+
throw new Error(`Entity master not found for ${mappedEntityType}`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let pathTemplate = entityMaster.doc_upload_path ?? '';
|
|
170
|
+
const entityOverwrite = entityMaster.overwrite_path ?? 0;
|
|
171
|
+
|
|
172
|
+
if (!pathTemplate) {
|
|
173
|
+
throw new Error(`doc_upload_path not defined for ${mappedEntityType}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// 2️⃣ Prepare replacement map
|
|
177
|
+
const replacements: Record<string, string | null> = {};
|
|
178
|
+
|
|
179
|
+
// --- ORG ---
|
|
180
|
+
let organizationData = await this.dataSource.query('SELECT * FROM sso_organization WHERE id = ?', [loggedInUser.organization_id]);
|
|
181
|
+
replacements['org_code'] = organizationData[0].code;
|
|
182
|
+
|
|
183
|
+
// --- LEVEL CODE ---
|
|
184
|
+
// Determine which entity to use for level_code
|
|
185
|
+
const levelEntityId = entityOverwrite ? mappedEntityId : loggedInUser.level_id;
|
|
186
|
+
const levelEntityData = await super.getEntityData(loggedInUser.level_type, levelEntityId, loggedInUser);
|
|
187
|
+
if (levelEntityData?.code) {
|
|
188
|
+
replacements['level_code'] = levelEntityData.code; // universal alias
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// --- Dynamic variables inside path ---
|
|
192
|
+
const matches = pathTemplate.match(/\$\{(\w+)\}/g) || [];
|
|
193
|
+
|
|
194
|
+
for (const variable of matches) {
|
|
195
|
+
const key = variable.replace(/\$\{|\}/g, '');
|
|
196
|
+
if (replacements[key]) continue; // already resolved
|
|
197
|
+
|
|
198
|
+
if (key === 'org_code') continue; // already set
|
|
199
|
+
if (key.endsWith('_code')) {
|
|
200
|
+
// derive entity type dynamically
|
|
201
|
+
const entityType = key.replace('_code', '').toUpperCase();
|
|
202
|
+
|
|
203
|
+
let entityId: number | undefined;
|
|
204
|
+
if (parentType?.toUpperCase() === entityType && parentId) {
|
|
205
|
+
entityId = parentId;
|
|
206
|
+
} else {
|
|
207
|
+
entityId = mappedEntityId;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Generic lookup
|
|
211
|
+
if (entityId) {
|
|
212
|
+
const entityData = await super.getEntityData(entityType, entityId, loggedInUser);
|
|
213
|
+
replacements[key] = entityData?.code ?? null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// --- ORG special case ---
|
|
219
|
+
// If ORG level & overwrite = 0 → remove level_code variable
|
|
220
|
+
if (loggedInUser.level_type === 'ORG' && entityOverwrite === 0) {
|
|
221
|
+
replacements['level_code'] = null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 3️⃣ Final substitution and cleanup
|
|
225
|
+
if (pathTemplate) {
|
|
226
|
+
const finalPath = this.resolveUploadPath(pathTemplate, replacements);
|
|
227
|
+
return finalPath;
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Replace placeholders with actual values, remove missing variables
|
|
234
|
+
*/
|
|
235
|
+
private resolveUploadPath(template: string, replacements: Record<string, string | null>) {
|
|
236
|
+
let path = template;
|
|
237
|
+
path = path.replace(/\$\{(\w+)\}/g, (_, key) => replacements[key] || '');
|
|
238
|
+
return path.replace(/\/+/g, '/').replace(/\/$/, '');
|
|
239
|
+
}
|
|
149
240
|
}
|
|
@@ -127,7 +127,7 @@ export class NotificationsService {
|
|
|
127
127
|
|
|
128
128
|
// Make the GET request with query parameters
|
|
129
129
|
const response = await axios.get(
|
|
130
|
-
`${baseUrl}/users/profile-image-url/${notification?.user_id}?entity_type=
|
|
130
|
+
`${baseUrl}/users/profile-image-url/${notification?.user_id}?entity_type=USR&${queryParams}`,
|
|
131
131
|
{
|
|
132
132
|
headers: {
|
|
133
133
|
'Content-Type': 'application/json',
|
|
@@ -68,7 +68,7 @@ export class ActivityLogRepository {
|
|
|
68
68
|
|
|
69
69
|
// Make the GET request with query parameters
|
|
70
70
|
const response = await axios.get(
|
|
71
|
-
`${baseUrl}/users/profile-image-url/${param?.created_by}?entity_type=
|
|
71
|
+
`${baseUrl}/users/profile-image-url/${param?.created_by}?entity_type=USR&${queryParams}`,
|
|
72
72
|
{
|
|
73
73
|
headers: {
|
|
74
74
|
'Content-Type': 'application/json',
|
|
@@ -222,7 +222,7 @@ export class StageGroupService extends EntityServiceImpl {
|
|
|
222
222
|
|
|
223
223
|
// Make the GET request with query parameters
|
|
224
224
|
const response = await axios.get(
|
|
225
|
-
`${baseUrl}/users/profile-image-url/${userId}?entity_type=
|
|
225
|
+
`${baseUrl}/users/profile-image-url/${userId}?entity_type=USR&${queryParams}`,
|
|
226
226
|
{
|
|
227
227
|
headers: {
|
|
228
228
|
'Content-Type': 'application/json',
|
|
@@ -320,7 +320,7 @@ export class TaskService extends EntityServiceImpl {
|
|
|
320
320
|
|
|
321
321
|
// Make the GET request with query parameters
|
|
322
322
|
const response = await axios.get(
|
|
323
|
-
`${baseUrl}/users/profile-image-url/${param?.task_owner}?entity_type=
|
|
323
|
+
`${baseUrl}/users/profile-image-url/${param?.task_owner}?entity_type=USR&${queryParams}`,
|
|
324
324
|
{
|
|
325
325
|
headers: {
|
|
326
326
|
'Content-Type': 'application/json',
|