Skip to content

Commit 73b27cc

Browse files
conflicts resolve
2 parents 3d493a3 + f1754ac commit 73b27cc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1666
-404
lines changed

.talismanrc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,18 @@ ignoreconfig:
1212
- filename: api/src/services/wordpress.service.ts
1313
checksum: 24f3cf7587ccdd439e837a70cd4e13c4a63a9b6f6c211a91de10a278dbbf23e4
1414
version: "1.0.1-beta"
15+
16+
fileignoreconfig:
17+
- filename: ui/package-lock.json
18+
checksum: dcb09583feb62c9000ea89fb380a562baa3c9dfac72bc8c68357c7bfd6374fe4
19+
- filename: api/src/utils/content-type-creator.utils.ts
20+
checksum: 672ce6b09cb7993fbe6dbad2ed78082ba140b9b68026771ebe056bcdcabdc40c
21+
- filename: api/src/services/migration.service.ts
22+
checksum: 5459ca2e9c6f8067f9acae91bd8af126aef893e8baaccc8a05ad6bd7162e994f
23+
- filename: ui/src/components/AuditLogs/auditLogs.interface.ts
24+
checksum: e9ba5046479507dd11a369246fb7779edfac00ae5df859cc1ba81ed7d61be19b
25+
- filename: ui/src/components/ContentMapper/index.tsx
26+
checksum: 6743142fce18f945d55fc61d7d774118db400b72ccc7a0b5e089ccc8aed20340
27+
- filename: ui/src/components/AuditLogs/index.tsx
28+
checksum: 8cad311f527241fcb0fd587da28bbe776e0147a3da0d372ceb447b0076a5aeba
29+
version: "1.0"

api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"p-limit": "^6.2.0",
4949
"path-to-regexp": "^8.2.0",
5050
"router": "^2.0.0",
51-
"shelljs": "^0.8.5",
51+
"shelljs": "^0.9.0",
5252
"socket.io": "^4.7.5",
5353
"uuid": "^9.0.1",
5454
"winston": "^3.11.0"

api/src/constants/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ export const LOCALE_MAPPER: any = {
177177
masterLocale: {
178178
"en-us": "en",
179179
},
180-
locales:{fr: "fr-fr",}
180+
locales: { fr: "fr-fr", }
181181
};
182182
export const CHUNK_SIZE = 1048576;
183183

@@ -277,3 +277,13 @@ export const MIGRATION_DATA_CONFIG = {
277277

278278
EXPORT_INFO_FILE: "export-info.json",
279279
};
280+
281+
export const GET_AUDIT_DATA = {
282+
MIGRATION: "migration-v2",
283+
API_DIR: "api",
284+
MIGRATION_DATA_DIR: "migration-data",
285+
LOGS_DIR: "logs",
286+
AUDIT_DIR: "audit",
287+
AUDIT_REPORT: "audit-report",
288+
FILTERALL: "all",
289+
}

api/src/controllers/migration.controller.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,13 @@ const deleteTestStack = async (req: Request, res: Response): Promise<void> => {
4949
const resp = await migrationService.deleteTestStack(req);
5050
res.status(200).json(resp);
5151
};
52-
52+
const getAuditData = async (req: Request, res: Response): Promise<void> => {
53+
const resp = await migrationService.getAuditData(req);
54+
res.status(resp?.status).json(resp);
55+
};
5356
const getLogs = async (req: Request, res: Response): Promise<void> => {
5457
const resp = await migrationService.getLogs(req);
55-
res.status(200).json(resp);
58+
res.status(resp?.status).json(resp);
5659
};
5760

5861
const saveLocales = async (req: Request, res: Response): Promise<void> => {
@@ -72,5 +75,6 @@ export const migrationController = {
7275
startMigration,
7376
getLogs,
7477
saveLocales,
75-
saveMappedLocales
78+
saveMappedLocales,
79+
getAuditData
7680
};

api/src/routes/migration.routes.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ router.post(
2020
"/test-stack/:orgId/:projectId",
2121
asyncRouter(migrationController.startTestMigration)
2222
);
23-
23+
router.get(
24+
"/get_audit_data/:orgId/:projectId/:stackId/:moduleName/:skip/:limit/:startIndex/:stopIndex/:searchText/:filter",
25+
asyncRouter(migrationController.getAuditData)
26+
)
2427
/**
2528
* Route for deleting a test stack.
2629
* @route POST /test-stack/:projectId

api/src/services/migration.service.ts

Lines changed: 177 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import https from "../utils/https.utils.js";
77
import { LoginServiceType } from "../models/types.js";
88
import getAuthtoken from "../utils/auth.utils.js";
99
import logger from "../utils/logger.js";
10+
import { GET_AUDIT_DATA } from "../constants/index.js";
1011
import {
1112
HTTP_TEXTS,
1213
HTTP_CODES,
@@ -118,12 +119,10 @@ const createTestStack = async (req: Request): Promise<LoginServiceType> => {
118119
}
119120
return {
120121
data: {
121-
data: res.data,
122-
url: `${
123-
config.CS_URL[token_payload?.region as keyof typeof config.CS_URL]
124-
}/stack/${res.data.stack.api_key}/dashboard`,
122+
data: res?.data,
123+
url: `${config?.CS_URL[token_payload?.region as keyof typeof config.CS_URL]}/stack/${res?.data?.stack?.api_key}/dashboard`,
125124
},
126-
status: res.status,
125+
status: res?.status,
127126
};
128127
} catch (error: any) {
129128
logger.error(
@@ -135,13 +134,158 @@ const createTestStack = async (req: Request): Promise<LoginServiceType> => {
135134
)
136135
);
137136

137+
throw new ExceptionFunction(
138+
error?.message || HTTP_TEXTS?.INTERNAL_ERROR,
139+
error?.statusCode || error?.status || HTTP_CODES.SERVER_ERROR
140+
);
141+
}
142+
};
143+
144+
const getAuditData = async (req: Request): Promise<any> => {
145+
const projectId = path?.basename(req?.params?.projectId);
146+
const stackId = path?.basename(req?.params?.stackId);
147+
const moduleName = path.basename(req?.params?.moduleName);
148+
const limit = parseInt(req?.params?.limit);
149+
const startIndex = parseInt(req?.params?.startIndex);
150+
const stopIndex = startIndex + limit;
151+
const searchText = req?.params?.searchText;
152+
const filter = req?.params?.filter;
153+
const srcFunc = "getAuditData";
154+
155+
if (projectId?.includes('..') || stackId?.includes('..') || moduleName?.includes('..')) {
156+
throw new BadRequestError("Invalid projectId, stackId, or moduleName");
157+
}
158+
159+
try {
160+
const mainPath = process?.cwd()?.split?.(GET_AUDIT_DATA?.MIGRATION)?.[0];
161+
const logsDir = path.join(mainPath, GET_AUDIT_DATA?.MIGRATION, GET_AUDIT_DATA?.API_DIR, GET_AUDIT_DATA?.MIGRATION_DATA_DIR);
162+
163+
const stackFolders = fs.readdirSync(logsDir);
164+
165+
const stackFolder = stackFolders?.find(folder => folder?.startsWith?.(stackId));
166+
if (!stackFolder) {
167+
throw new BadRequestError("Migration data not found for this stack");
168+
}
169+
170+
const auditLogPath = path?.resolve(logsDir, stackFolder, GET_AUDIT_DATA?.LOGS_DIR, GET_AUDIT_DATA?.AUDIT_DIR, GET_AUDIT_DATA?.AUDIT_REPORT);
171+
if (!fs.existsSync(auditLogPath)) {
172+
throw new BadRequestError("Audit log path not found");
173+
}
174+
175+
176+
// Read and parse the JSON file for the module
177+
const filePath = path?.resolve(auditLogPath, `${moduleName}.json`);
178+
let fileData;
179+
if (fs?.existsSync(filePath)) {
180+
const fileContent = await fsPromises.readFile(filePath, 'utf8');
181+
try {
182+
if (typeof fileContent === 'string') {
183+
fileData = JSON?.parse(fileContent);
184+
}
185+
} catch (error) {
186+
logger.error(`Error parsing JSON from file ${filePath}:`, error);
187+
throw new BadRequestError('Invalid JSON format in audit file');
188+
}
189+
}
190+
191+
if (!fileData) {
192+
throw new BadRequestError(`No audit data found for module: ${moduleName}`);
193+
}
194+
let transformedData = transformAndFlattenData(fileData);
195+
if (filter != GET_AUDIT_DATA?.FILTERALL) {
196+
const filters = filter?.split("-");
197+
moduleName === 'Entries_Select_feild' ? transformedData = transformedData?.filter((log) => {
198+
return filters?.some((filter) => {
199+
return (
200+
log?.display_type?.toLowerCase()?.includes(filter?.toLowerCase())
201+
);
202+
});
203+
}) : transformedData = transformedData?.filter((log) => {
204+
return filters?.some((filter) => {
205+
return (
206+
log?.data_type?.toLowerCase()?.includes(filter?.toLowerCase())
207+
);
208+
});
209+
});
210+
211+
}
212+
if (searchText && searchText !== null && searchText !== "null") {
213+
transformedData = transformedData?.filter((item: any) => {
214+
return Object?.values(item)?.some(value =>
215+
value &&
216+
typeof value === 'string' &&
217+
value?.toLowerCase?.()?.includes(searchText?.toLowerCase())
218+
);
219+
});
220+
}
221+
const paginatedData = transformedData?.slice?.(startIndex, stopIndex);
222+
223+
return {
224+
data: paginatedData,
225+
totalCount: transformedData?.length,
226+
status: HTTP_CODES?.OK
227+
};
228+
229+
} catch (error: any) {
230+
logger.error(
231+
getLogMessage(
232+
srcFunc,
233+
`Error getting audit log data for module: ${moduleName}`,
234+
error
235+
)
236+
);
138237
throw new ExceptionFunction(
139238
error?.message || HTTP_TEXTS.INTERNAL_ERROR,
140239
error?.statusCode || error?.status || HTTP_CODES.SERVER_ERROR
141240
);
142241
}
143242
};
243+
/**
244+
* Transforms and flattens nested data structure into an array of items
245+
* with sequential tuid values
246+
*/
247+
const transformAndFlattenData = (data: any): Array<{ [key: string]: any, id: number }> => {
248+
try {
249+
const flattenedItems: Array<{ [key: string]: any }> = [];
250+
251+
// Handle the data based on its structure
252+
if (Array.isArray(data)) {
253+
// If data is already an array, use it directly
254+
data?.forEach((item, index) => {
255+
flattenedItems?.push({
256+
...item ?? {},
257+
uid: item?.uid || `item-${index}`
258+
});
259+
});
260+
} else if (typeof data === 'object' && data !== null) {
261+
Object?.entries?.(data)?.forEach(([key, value]) => {
262+
if (Array.isArray(value)) {
263+
value?.forEach((item, index) => {
264+
flattenedItems?.push({
265+
...item ?? {},
266+
parentKey: key,
267+
uid: item?.uid || `${key}-${index}`
268+
});
269+
});
270+
} else if (typeof value === 'object' && value !== null) {
271+
flattenedItems?.push({
272+
...value,
273+
key,
274+
uid: (value as any)?.uid || key
275+
});
276+
}
277+
});
278+
}
144279

280+
return flattenedItems?.map((item, index) => ({
281+
...item ?? {},
282+
id: index + 1
283+
}));
284+
} catch (error) {
285+
console.error('Error transforming data:', error);
286+
return [];
287+
}
288+
};
145289
/**
146290
* Deletes a test stack.
147291
* @param req - The request object.
@@ -531,7 +675,7 @@ const startMigration = async (req: Request): Promise<any> => {
531675
.findIndex({ id: projectId })
532676
.value();
533677
if (index > -1) {
534-
ProjectModelLowdb.update((data: any) => {
678+
await ProjectModelLowdb.update((data: any) => {
535679
data.projects[index].isMigrationStarted = true;
536680
});
537681
}
@@ -547,6 +691,18 @@ const startMigration = async (req: Request): Promise<any> => {
547691
projectId,
548692
`${project?.destination_stack_id}.log`
549693
);
694+
const message = getLogMessage(
695+
'start Migration',
696+
'Starting Migration...',
697+
{}
698+
);
699+
await customLogger(
700+
projectId,
701+
project?.destination_stack_id,
702+
'info',
703+
message
704+
);
705+
550706
await setLogFilePath(loggerPath);
551707

552708
const copyLogsToStack = async (
@@ -800,7 +956,6 @@ const startMigration = async (req: Request): Promise<any> => {
800956
}
801957
};
802958

803-
804959
const getLogs = async (req: Request): Promise<any> => {
805960
const projectId = req?.params?.projectId ? path?.basename(req.params.projectId) : "";
806961
const stackId = req?.params?.stackId ? path?.basename(req.params.stackId) : "";
@@ -809,9 +964,7 @@ const getLogs = async (req: Request): Promise<any> => {
809964
const stopIndex = startIndex + limit;
810965
const searchText = req?.params?.searchText ?? null;
811966
const filter = req?.params?.filter ?? "all";
812-
813967
const srcFunc = "getLogs";
814-
815968
if (
816969
!projectId ||
817970
!stackId ||
@@ -820,40 +973,44 @@ const getLogs = async (req: Request): Promise<any> => {
820973
) {
821974
throw new BadRequestError("Invalid projectId or stackId");
822975
}
823-
824976
try {
825977
const mainPath = process?.cwd()?.split("migration-v2")?.[0];
826978
if (!mainPath) {
827979
throw new BadRequestError("Invalid application path");
828980
}
829-
830981
const logsDir = path?.join(mainPath, "migration-v2", "api", "logs");
831982
const loggerPath = path?.join(logsDir, projectId, `${stackId}.log`);
832983
const absolutePath = path?.resolve(loggerPath);
833-
834984
if (!absolutePath?.startsWith(logsDir)) {
835985
throw new BadRequestError("Access to this file is not allowed.");
836986
}
837-
838987
if (fs.existsSync(absolutePath)) {
988+
let index = 0;
839989
const logs = await fs.promises.readFile(absolutePath, "utf8");
840990
let logEntries = logs
841991
?.split("\n")
842992
?.map((line) => {
843993
try {
844-
return line ? JSON?.parse(line) : null;
994+
const parsedLine = JSON?.parse(line)
995+
parsedLine['id'] = index;
996+
++index;
997+
return parsedLine ? parsedLine : null;
845998
} catch (error) {
846999
return null;
8471000
}
8481001
})
8491002
?.filter?.((entry) => entry !== null);
850-
8511003
if (!logEntries?.length) {
8521004
return { logs: [], total: 0 };
8531005
}
854-
1006+
const filterOptions = Array?.from(new Set(logEntries?.map((log) => log?.level)));
1007+
const auditStartIndex = logEntries?.findIndex?.(log => log?.message?.includes("Starting audit process"));
1008+
const auditEndIndex = logEntries?.findIndex?.(log => log?.message?.includes("Audit process completed"));
1009+
logEntries = [
1010+
...logEntries.slice(0, auditStartIndex),
1011+
...logEntries.slice(auditEndIndex + 1)
1012+
]
8551013
logEntries = logEntries?.slice?.(1, logEntries?.length - 2);
856-
8571014
if (filter !== "all") {
8581015
const filters = filter?.split("-") ?? [];
8591016
logEntries = logEntries?.filter((log) => {
@@ -864,17 +1021,17 @@ const getLogs = async (req: Request): Promise<any> => {
8641021
});
8651022
});
8661023
}
867-
8681024
if (searchText && searchText !== "null") {
8691025
logEntries = logEntries?.filter?.((log) =>
8701026
matchesSearchText(log, searchText)
8711027
);
8721028
}
873-
8741029
const paginatedLogs = logEntries?.slice?.(startIndex, stopIndex) ?? [];
8751030
return {
8761031
logs: paginatedLogs,
8771032
total: logEntries?.length ?? 0,
1033+
filterOptions: filterOptions,
1034+
status: HTTP_CODES?.OK
8781035
};
8791036
} else {
8801037
logger.error(getLogMessage(srcFunc, HTTP_TEXTS.LOGS_NOT_FOUND));
@@ -989,4 +1146,5 @@ export const migrationService = {
9891146
getLogs,
9901147
createSourceLocales,
9911148
updateLocaleMapper,
1149+
getAuditData
9921150
};

0 commit comments

Comments
 (0)