fix(media): resolve UTF-8 Persian/Arabic filename encoding issue in uploads
This commit is contained in:
parent
5f58ba8258
commit
73029c06c4
@ -8,9 +8,28 @@ export class MediaService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async getAllMedia() {
|
||||
return this.prisma.media.findMany({
|
||||
const items = await this.prisma.media.findMany({
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
|
||||
return items.map((item) => {
|
||||
let cleanFilename = item.filename;
|
||||
// Check if filename contains common mojibake patterns from latin1 decoding
|
||||
if (cleanFilename && /[ØÙÚÛ]/.test(cleanFilename)) {
|
||||
try {
|
||||
const decoded = Buffer.from(cleanFilename, 'latin1').toString('utf8');
|
||||
if (decoded && !decoded.includes('')) {
|
||||
cleanFilename = decoded;
|
||||
}
|
||||
} catch {
|
||||
// Keep original if decoding fails
|
||||
}
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
filename: cleanFilename,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async uploadFile(file: Express.Multer.File) {
|
||||
@ -23,8 +42,16 @@ export class MediaService {
|
||||
fs.mkdirSync(uploadDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Fix Multer/Busboy ISO-8859-1 (latin1) to UTF-8 filename encoding for Persian/Arabic/Unicode characters
|
||||
let originalname = file.originalname;
|
||||
try {
|
||||
originalname = Buffer.from(file.originalname, 'latin1').toString('utf8');
|
||||
} catch {
|
||||
originalname = file.originalname;
|
||||
}
|
||||
|
||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
|
||||
const ext = path.extname(file.originalname);
|
||||
const ext = path.extname(originalname);
|
||||
const filename = `${uniqueSuffix}${ext}`;
|
||||
const filePath = path.join(uploadDir, filename);
|
||||
|
||||
@ -35,7 +62,7 @@ export class MediaService {
|
||||
|
||||
const media = await this.prisma.media.create({
|
||||
data: {
|
||||
filename: file.originalname,
|
||||
filename: originalname,
|
||||
url,
|
||||
mimetype: file.mimetype,
|
||||
size: file.size,
|
||||
|
||||
@ -183,7 +183,7 @@
|
||||
"181": "⚙️ Backend Technical Review (05_dev_backend)",
|
||||
"182": "🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)",
|
||||
"183": "🚀 SEO & Content Strategy Review (12_seo_content)",
|
||||
"184": "RedisService",
|
||||
"184": "MetricsController",
|
||||
"185": "@eslint/eslintrc",
|
||||
"186": "seed-ui-texts.ts",
|
||||
"187": "seed-wiki.ts",
|
||||
@ -230,7 +230,7 @@
|
||||
"228": "rules/graphify.md",
|
||||
"229": ".agents/workflows/graphify.md",
|
||||
"230": "instructions.md",
|
||||
"231": "eslint-config-prettier",
|
||||
"231": "RevalidationService",
|
||||
"232": "helmet",
|
||||
"233": "tailwindcss",
|
||||
"234": "@nestjs/schematics",
|
||||
@ -322,6 +322,7 @@
|
||||
"320": "@testing-library/react",
|
||||
"321": "orders/page.tsx",
|
||||
"322": "pets/page.tsx",
|
||||
"323": "@types/react-dom",
|
||||
"323": "eslint",
|
||||
"324": "eslint-config-next",
|
||||
"327": "eslint-plugin-react-refresh"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -147,7 +147,7 @@
|
||||
"145": "admin.service.ts",
|
||||
"146": "System Discovery",
|
||||
"147": "HomeClient.tsx",
|
||||
"148": "bcrypt",
|
||||
"148": "@nestjs/swagger",
|
||||
"149": "SmsSettingsPage.tsx",
|
||||
"150": "Product Requirement Document (PRD)",
|
||||
"151": "class-transformer",
|
||||
@ -318,8 +318,8 @@
|
||||
"316": "prettier",
|
||||
"317": "revalidate/route.ts",
|
||||
"318": "MaskableField.tsx",
|
||||
"319": "eslint-config-next",
|
||||
"320": "eslint",
|
||||
"319": "@eslint/js",
|
||||
"320": "@testing-library/react",
|
||||
"321": "orders/page.tsx",
|
||||
"322": "pets/page.tsx",
|
||||
"323": "@types/react-dom",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Graph Report - canina (2026-08-26)
|
||||
|
||||
## Corpus Check
|
||||
- 589 files · ~1,333,629 words
|
||||
- 589 files · ~1,333,778 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
@ -10,7 +10,7 @@
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `e797cf91`
|
||||
- Built from commit: `3109e30f`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@ -163,7 +163,7 @@
|
||||
- admin.service.ts
|
||||
- System Discovery
|
||||
- HomeClient.tsx
|
||||
- bcrypt
|
||||
- @nestjs/swagger
|
||||
- SmsSettingsPage.tsx
|
||||
- Product Requirement Document (PRD)
|
||||
- class-transformer
|
||||
@ -316,8 +316,8 @@
|
||||
- prettier
|
||||
- revalidate/route.ts
|
||||
- MaskableField.tsx
|
||||
- eslint-config-next
|
||||
- eslint
|
||||
- @eslint/js
|
||||
- @testing-library/react
|
||||
- @types/react-dom
|
||||
- eslint-plugin-react-refresh
|
||||
|
||||
@ -390,7 +390,7 @@ Nodes (14): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty,
|
||||
|
||||
### Community 9 - "devDependencies"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): devDependencies, @eslint/js, @types/bcryptjs, @types/node, typescript, @eslint/js, @types/node, typescript (+1 more)
|
||||
Nodes (9): devDependencies, eslint, @types/bcryptjs, @types/node, typescript, eslint, @types/node, typescript (+1 more)
|
||||
|
||||
### Community 10 - "reviews.controller.ts"
|
||||
Cohesion: 0.07
|
||||
@ -545,7 +545,7 @@ Cohesion: 0.13
|
||||
Nodes (14): IngredientsController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Delete, Get (+6 more)
|
||||
|
||||
### Community 48 - "UsersController"
|
||||
Cohesion: 0.19
|
||||
Cohesion: 0.21
|
||||
Nodes (16): ApiBadRequestResponse, ApiBearerAuth, ApiCreatedResponse, ApiOkResponse, ApiOperation, ApiTags, Body, Controller (+8 more)
|
||||
|
||||
### Community 49 - "devDependencies"
|
||||
@ -554,7 +554,7 @@ Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, glo
|
||||
|
||||
### Community 50 - "devDependencies"
|
||||
Cohesion: 0.13
|
||||
Nodes (15): devDependencies, eslint, jsdom, tailwindcss, @tailwindcss/postcss, @testing-library/react, @types/node, @vitejs/plugin-react (+7 more)
|
||||
Nodes (15): eslint-config-next, devDependencies, eslint, eslint-config-next, jsdom, tailwindcss, @tailwindcss/postcss, @types/node (+7 more)
|
||||
|
||||
### Community 51 - "BlogsController"
|
||||
Cohesion: 0.07
|
||||
@ -602,7 +602,7 @@ Nodes (7): ProductDto, ApiPropertyOptional, IsArray, IsBoolean, IsNumber, IsOpti
|
||||
|
||||
### Community 63 - "dependencies"
|
||||
Cohesion: 0.09
|
||||
Nodes (23): dependencies, bcryptjs, class-validator, compression, ioredis, @nestjs/common, @nestjs/passport, @nestjs/platform-express (+15 more)
|
||||
Nodes (23): dependencies, bcrypt, bcryptjs, class-validator, compression, ioredis, @nestjs/common, @nestjs/passport (+15 more)
|
||||
|
||||
### Community 64 - "compilerOptions"
|
||||
Cohesion: 0.10
|
||||
|
||||
@ -6040,6 +6040,30 @@
|
||||
"community_name": "UsersService",
|
||||
"norm_label": ".validate()"
|
||||
},
|
||||
{
|
||||
"label": ".constructor()",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/src/users/users.controller.ts",
|
||||
"source_location": "L44",
|
||||
"_callable": true,
|
||||
"_origin": "ast",
|
||||
"id": "backend_src_users_users_controller_userscontroller_constructor",
|
||||
"community": 106,
|
||||
"community_name": "UsersService",
|
||||
"norm_label": ".constructor()"
|
||||
},
|
||||
{
|
||||
"label": ".addAddress()",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/src/users/users.service.ts",
|
||||
"source_location": "L210",
|
||||
"_callable": true,
|
||||
"_origin": "ast",
|
||||
"id": "backend_src_users_users_service_usersservice_addaddress",
|
||||
"community": 106,
|
||||
"community_name": "UsersService",
|
||||
"norm_label": ".addaddress()"
|
||||
},
|
||||
{
|
||||
"label": ".constructor()",
|
||||
"file_type": "code",
|
||||
@ -7460,7 +7484,7 @@
|
||||
"label": "handleClickOutside()",
|
||||
"file_type": "code",
|
||||
"source_file": "frontend/application/components/Header.tsx",
|
||||
"source_location": "L181",
|
||||
"source_location": "L182",
|
||||
"_callable": true,
|
||||
"_origin": "ast",
|
||||
"id": "frontend_application_components_header_header_handleclickoutside",
|
||||
@ -13012,18 +13036,6 @@
|
||||
"community_name": "UsersController",
|
||||
"norm_label": ".addaddress()"
|
||||
},
|
||||
{
|
||||
"label": ".constructor()",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/src/users/users.controller.ts",
|
||||
"source_location": "L44",
|
||||
"_callable": true,
|
||||
"_origin": "ast",
|
||||
"id": "backend_src_users_users_controller_userscontroller_constructor",
|
||||
"community": 48,
|
||||
"community_name": "UsersController",
|
||||
"norm_label": ".constructor()"
|
||||
},
|
||||
{
|
||||
"label": ".deleteAddress()",
|
||||
"file_type": "code",
|
||||
@ -13096,18 +13108,6 @@
|
||||
"community_name": "UsersController",
|
||||
"norm_label": ".updateprofile()"
|
||||
},
|
||||
{
|
||||
"label": ".addAddress()",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/src/users/users.service.ts",
|
||||
"source_location": "L210",
|
||||
"_callable": true,
|
||||
"_origin": "ast",
|
||||
"id": "backend_src_users_users_service_usersservice_addaddress",
|
||||
"community": 48,
|
||||
"community_name": "UsersController",
|
||||
"norm_label": ".addaddress()"
|
||||
},
|
||||
{
|
||||
"label": ".constructor()",
|
||||
"file_type": "code",
|
||||
@ -24719,26 +24719,26 @@
|
||||
"norm_label": "types.ts"
|
||||
},
|
||||
{
|
||||
"label": "bcrypt",
|
||||
"label": "@nestjs/swagger",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L33",
|
||||
"source_location": "L30",
|
||||
"_origin": "ast",
|
||||
"id": "backend_package_dependencies_bcrypt",
|
||||
"id": "backend_package_dependencies_nestjs_swagger",
|
||||
"community": 148,
|
||||
"community_name": "bcrypt",
|
||||
"norm_label": "bcrypt"
|
||||
"community_name": "@nestjs/swagger",
|
||||
"norm_label": "@nestjs/swagger"
|
||||
},
|
||||
{
|
||||
"label": "bcrypt",
|
||||
"label": "@nestjs/swagger",
|
||||
"file_type": "concept",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L33",
|
||||
"source_location": "L30",
|
||||
"_origin": "ast",
|
||||
"id": "bcrypt",
|
||||
"id": "nestjs_swagger",
|
||||
"community": 148,
|
||||
"community_name": "bcrypt",
|
||||
"norm_label": "bcrypt"
|
||||
"community_name": "@nestjs/swagger",
|
||||
"norm_label": "@nestjs/swagger"
|
||||
},
|
||||
{
|
||||
"label": "SmsSettingsPage.tsx",
|
||||
@ -34426,26 +34426,26 @@
|
||||
"norm_label": "maskablefield.tsx"
|
||||
},
|
||||
{
|
||||
"label": "eslint-config-next",
|
||||
"label": "@eslint/js",
|
||||
"file_type": "code",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L30",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L49",
|
||||
"_origin": "ast",
|
||||
"id": "frontend_application_package_devdependencies_eslint_config_next",
|
||||
"id": "backend_package_devdependencies_eslint_js",
|
||||
"community": 319,
|
||||
"community_name": "eslint-config-next",
|
||||
"norm_label": "eslint-config-next"
|
||||
"community_name": "@eslint/js",
|
||||
"norm_label": "@eslint/js"
|
||||
},
|
||||
{
|
||||
"label": "eslint-config-next",
|
||||
"label": "@eslint/js",
|
||||
"file_type": "concept",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L30",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L49",
|
||||
"_origin": "ast",
|
||||
"id": "eslint_config_next",
|
||||
"id": "backend_package_json_eslint_js",
|
||||
"community": 319,
|
||||
"community_name": "eslint-config-next",
|
||||
"norm_label": "eslint-config-next"
|
||||
"community_name": "@eslint/js",
|
||||
"norm_label": "@eslint/js"
|
||||
},
|
||||
{
|
||||
"label": "App.tsx",
|
||||
@ -34646,26 +34646,26 @@
|
||||
"norm_label": "lazywithretry.ts"
|
||||
},
|
||||
{
|
||||
"label": "eslint",
|
||||
"label": "@testing-library/react",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L63",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L24",
|
||||
"_origin": "ast",
|
||||
"id": "backend_package_devdependencies_eslint",
|
||||
"id": "frontend_application_package_devdependencies_testing_library_react",
|
||||
"community": 320,
|
||||
"community_name": "eslint",
|
||||
"norm_label": "eslint"
|
||||
"community_name": "@testing-library/react",
|
||||
"norm_label": "@testing-library/react"
|
||||
},
|
||||
{
|
||||
"label": "eslint",
|
||||
"label": "@testing-library/react",
|
||||
"file_type": "concept",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L63",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L24",
|
||||
"_origin": "ast",
|
||||
"id": "backend_package_json_eslint",
|
||||
"id": "testing_library_react",
|
||||
"community": 320,
|
||||
"community_name": "eslint",
|
||||
"norm_label": "eslint"
|
||||
"community_name": "@testing-library/react",
|
||||
"norm_label": "@testing-library/react"
|
||||
},
|
||||
{
|
||||
"label": "orders/page.tsx",
|
||||
@ -38022,6 +38022,17 @@
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "eslint"
|
||||
},
|
||||
{
|
||||
"label": "eslint-config-next",
|
||||
"file_type": "code",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L30",
|
||||
"_origin": "ast",
|
||||
"id": "frontend_application_package_devdependencies_eslint_config_next",
|
||||
"community": 50,
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "eslint-config-next"
|
||||
},
|
||||
{
|
||||
"label": "jsdom",
|
||||
"file_type": "code",
|
||||
@ -38055,17 +38066,6 @@
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "@tailwindcss/postcss"
|
||||
},
|
||||
{
|
||||
"label": "@testing-library/react",
|
||||
"file_type": "code",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L24",
|
||||
"_origin": "ast",
|
||||
"id": "frontend_application_package_devdependencies_testing_library_react",
|
||||
"community": 50,
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "@testing-library/react"
|
||||
},
|
||||
{
|
||||
"label": "@types/node",
|
||||
"file_type": "code",
|
||||
@ -38088,6 +38088,17 @@
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "@vitejs/plugin-react"
|
||||
},
|
||||
{
|
||||
"label": "eslint-config-next",
|
||||
"file_type": "concept",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L30",
|
||||
"_origin": "ast",
|
||||
"id": "eslint_config_next",
|
||||
"community": 50,
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "eslint-config-next"
|
||||
},
|
||||
{
|
||||
"label": "eslint",
|
||||
"file_type": "concept",
|
||||
@ -38154,17 +38165,6 @@
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "jsdom"
|
||||
},
|
||||
{
|
||||
"label": "@testing-library/react",
|
||||
"file_type": "concept",
|
||||
"source_file": "frontend/application/package.json",
|
||||
"source_location": "L24",
|
||||
"_origin": "ast",
|
||||
"id": "testing_library_react",
|
||||
"community": 50,
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "@testing-library/react"
|
||||
},
|
||||
{
|
||||
"label": "ApiBearerAuth",
|
||||
"file_type": "code",
|
||||
@ -40134,6 +40134,17 @@
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "dependencies"
|
||||
},
|
||||
{
|
||||
"label": "bcrypt",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L33",
|
||||
"_origin": "ast",
|
||||
"id": "backend_package_dependencies_bcrypt",
|
||||
"community": 63,
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "bcrypt"
|
||||
},
|
||||
{
|
||||
"label": "bcryptjs",
|
||||
"file_type": "code",
|
||||
@ -40211,17 +40222,6 @@
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "@nestjs/platform-express"
|
||||
},
|
||||
{
|
||||
"label": "@nestjs/swagger",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L30",
|
||||
"_origin": "ast",
|
||||
"id": "backend_package_dependencies_nestjs_swagger",
|
||||
"community": 63,
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "@nestjs/swagger"
|
||||
},
|
||||
{
|
||||
"label": "passport-jwt",
|
||||
"file_type": "code",
|
||||
@ -40255,6 +40255,17 @@
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "rxjs"
|
||||
},
|
||||
{
|
||||
"label": "bcrypt",
|
||||
"file_type": "concept",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L33",
|
||||
"_origin": "ast",
|
||||
"id": "bcrypt",
|
||||
"community": 63,
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "bcrypt"
|
||||
},
|
||||
{
|
||||
"label": "bcryptjs",
|
||||
"file_type": "concept",
|
||||
@ -40332,17 +40343,6 @@
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "@nestjs/platform-express"
|
||||
},
|
||||
{
|
||||
"label": "@nestjs/swagger",
|
||||
"file_type": "concept",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L30",
|
||||
"_origin": "ast",
|
||||
"id": "nestjs_swagger",
|
||||
"community": 63,
|
||||
"community_name": "dependencies",
|
||||
"norm_label": "@nestjs/swagger"
|
||||
},
|
||||
{
|
||||
"label": "passport-jwt",
|
||||
"file_type": "concept",
|
||||
@ -45085,15 +45085,15 @@
|
||||
"norm_label": "devdependencies"
|
||||
},
|
||||
{
|
||||
"label": "@eslint/js",
|
||||
"label": "eslint",
|
||||
"file_type": "code",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L49",
|
||||
"source_location": "L63",
|
||||
"_origin": "ast",
|
||||
"id": "backend_package_devdependencies_eslint_js",
|
||||
"id": "backend_package_devdependencies_eslint",
|
||||
"community": 9,
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "@eslint/js"
|
||||
"norm_label": "eslint"
|
||||
},
|
||||
{
|
||||
"label": "@types/bcryptjs",
|
||||
@ -45129,15 +45129,15 @@
|
||||
"norm_label": "typescript"
|
||||
},
|
||||
{
|
||||
"label": "@eslint/js",
|
||||
"label": "eslint",
|
||||
"file_type": "concept",
|
||||
"source_file": "backend/package.json",
|
||||
"source_location": "L49",
|
||||
"source_location": "L63",
|
||||
"_origin": "ast",
|
||||
"id": "backend_package_json_eslint_js",
|
||||
"id": "backend_package_json_eslint",
|
||||
"community": 9,
|
||||
"community_name": "devDependencies",
|
||||
"norm_label": "@eslint/js"
|
||||
"norm_label": "eslint"
|
||||
},
|
||||
{
|
||||
"label": "@types/node",
|
||||
@ -50368,7 +50368,7 @@
|
||||
"confidence": "EXTRACTED",
|
||||
"confidence_score": 1.0,
|
||||
"source_file": "frontend/application/components/Header.tsx",
|
||||
"source_location": "L142",
|
||||
"source_location": "L143",
|
||||
"weight": 1.0,
|
||||
"_origin": "ast",
|
||||
"source": "frontend_application_components_header_header",
|
||||
@ -50380,7 +50380,7 @@
|
||||
"confidence": "EXTRACTED",
|
||||
"confidence_score": 1.0,
|
||||
"source_file": "frontend/application/components/Header.tsx",
|
||||
"source_location": "L143",
|
||||
"source_location": "L144",
|
||||
"weight": 1.0,
|
||||
"_origin": "ast",
|
||||
"source": "frontend_application_components_header_header",
|
||||
@ -50392,7 +50392,7 @@
|
||||
"confidence": "EXTRACTED",
|
||||
"confidence_score": 1.0,
|
||||
"source_file": "frontend/application/components/Header.tsx",
|
||||
"source_location": "L144",
|
||||
"source_location": "L145",
|
||||
"weight": 1.0,
|
||||
"_origin": "ast",
|
||||
"source": "frontend_application_components_header_header",
|
||||
@ -50404,7 +50404,7 @@
|
||||
"confidence": "EXTRACTED",
|
||||
"confidence_score": 1.0,
|
||||
"source_file": "frontend/application/components/Header.tsx",
|
||||
"source_location": "L261",
|
||||
"source_location": "L264",
|
||||
"weight": 1.0,
|
||||
"_origin": "ast",
|
||||
"source": "frontend_application_components_header_header",
|
||||
@ -129830,7 +129830,7 @@
|
||||
"relation": "indirect_call",
|
||||
"confidence": "INFERRED",
|
||||
"source_file": "frontend/application/components/Header.tsx",
|
||||
"source_location": "L186",
|
||||
"source_location": "L187",
|
||||
"weight": 1.0,
|
||||
"_origin": "ast",
|
||||
"context": "argument",
|
||||
@ -133268,5 +133268,5 @@
|
||||
}
|
||||
],
|
||||
"hyperedges": [],
|
||||
"built_at_commit": "e797cf9167e1c4fefbbad815ac5c19dd6812d805"
|
||||
"built_at_commit": "3109e30fd7d4e1133f46f6fb2faa827dfbbb4ceb"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,16 @@
|
||||
# Graph Report - canina (2026-08-26)
|
||||
|
||||
## Corpus Check
|
||||
- 589 files · ~1,333,778 words
|
||||
- 589 files · ~1,333,704 words
|
||||
- Verdict: corpus is large enough that graph structure adds value.
|
||||
|
||||
## Summary
|
||||
- 4114 nodes · 7414 edges · 325 communities (206 shown, 119 thin omitted)
|
||||
- 4114 nodes · 7414 edges · 326 communities (207 shown, 119 thin omitted)
|
||||
- Extraction: 96% EXTRACTED · 4% INFERRED · 0% AMBIGUOUS · INFERRED: 281 edges (avg confidence: 0.79)
|
||||
- Token cost: 0 input · 0 output
|
||||
|
||||
## Graph Freshness
|
||||
- Built from commit: `3109e30f`
|
||||
- Built from commit: `5f58ba82`
|
||||
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
|
||||
- Run `graphify update .` after code changes (no API cost).
|
||||
|
||||
@ -198,7 +198,7 @@
|
||||
- ⚙️ Backend Technical Review (05_dev_backend)
|
||||
- 🎨 Frontend & Admin Panel Technical Review (06_dev_frontend)
|
||||
- 🚀 SEO & Content Strategy Review (12_seo_content)
|
||||
- RedisService
|
||||
- MetricsController
|
||||
- @eslint/eslintrc
|
||||
- seed-ui-texts.ts
|
||||
- seed-wiki.ts
|
||||
@ -245,7 +245,7 @@
|
||||
- rules/graphify.md
|
||||
- .agents/workflows/graphify.md
|
||||
- instructions.md
|
||||
- eslint-config-prettier
|
||||
- RevalidationService
|
||||
- helmet
|
||||
- tailwindcss
|
||||
- @nestjs/schematics
|
||||
@ -318,7 +318,8 @@
|
||||
- MaskableField.tsx
|
||||
- @eslint/js
|
||||
- @testing-library/react
|
||||
- @types/react-dom
|
||||
- eslint
|
||||
- eslint-config-next
|
||||
- eslint-plugin-react-refresh
|
||||
|
||||
## God Nodes (most connected - your core abstractions)
|
||||
@ -346,19 +347,19 @@
|
||||
backend/src/orders/orders.controller.ts → frontend/admin-panel/src/types/admin.ts
|
||||
|
||||
## Import Cycles
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/api.ts`
|
||||
- 3-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/services/authService.ts -> frontend/application/lib/services/api.ts`
|
||||
- 4-file cycle: `frontend/application/lib/services/api.ts -> frontend/application/lib/store/userStore.ts -> frontend/application/lib/store/cartStore.ts -> frontend/application/lib/services/orderService.ts -> frontend/application/lib/services/api.ts`
|
||||
|
||||
## Communities (325 total, 119 thin omitted)
|
||||
## Communities (326 total, 119 thin omitted)
|
||||
|
||||
### Community 0 - "Roles"
|
||||
Cohesion: 0.24
|
||||
Nodes (13): Roles(), PaymentController, ApiBearerAuth, ApiOperation, ApiTags, Body, Controller, Get (+5 more)
|
||||
|
||||
### Community 1 - "app.module.ts"
|
||||
Cohesion: 0.06
|
||||
Nodes (41): B2BModule, Module, BannersModule, Module, CmsModule, Module, RevalidationModule, Global (+33 more)
|
||||
Cohesion: 0.07
|
||||
Nodes (38): B2BModule, Module, BannersModule, Module, CmsModule, Module, SmsModule, Global (+30 more)
|
||||
|
||||
### Community 2 - "SmsService"
|
||||
Cohesion: 0.06
|
||||
@ -390,7 +391,7 @@ Nodes (14): AddressDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty,
|
||||
|
||||
### Community 9 - "devDependencies"
|
||||
Cohesion: 0.22
|
||||
Nodes (9): devDependencies, eslint, @types/bcryptjs, @types/node, typescript, eslint, @types/node, typescript (+1 more)
|
||||
Nodes (9): devDependencies, eslint-config-prettier, @types/bcryptjs, @types/node, typescript, @types/node, typescript, eslint-config-prettier (+1 more)
|
||||
|
||||
### Community 10 - "reviews.controller.ts"
|
||||
Cohesion: 0.07
|
||||
@ -437,8 +438,8 @@ Cohesion: 0.07
|
||||
Nodes (32): CreateVideoDto, ApiProperty, ApiPropertyOptional, IsBoolean, IsNotEmpty, IsOptional, IsString, UpdateVideoDto (+24 more)
|
||||
|
||||
### Community 21 - "admin.module.ts"
|
||||
Cohesion: 0.07
|
||||
Nodes (20): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+12 more)
|
||||
Cohesion: 0.06
|
||||
Nodes (23): AdminModule, Module, PetQuery, PetsService, Injectable, ReportsController, ApiBearerAuth, ApiOperation (+15 more)
|
||||
|
||||
### Community 22 - "FeaturedProducts.tsx"
|
||||
Cohesion: 0.14
|
||||
@ -554,7 +555,7 @@ Nodes (19): autoprefixer, devDependencies, autoprefixer, eslint, @eslint/js, glo
|
||||
|
||||
### Community 50 - "devDependencies"
|
||||
Cohesion: 0.13
|
||||
Nodes (15): eslint-config-next, devDependencies, eslint, eslint-config-next, jsdom, tailwindcss, @tailwindcss/postcss, @types/node (+7 more)
|
||||
Nodes (15): devDependencies, eslint, jsdom, tailwindcss, @tailwindcss/postcss, @types/node, @types/react-dom, @vitejs/plugin-react (+7 more)
|
||||
|
||||
### Community 51 - "BlogsController"
|
||||
Cohesion: 0.07
|
||||
@ -773,8 +774,8 @@ Cohesion: 0.06
|
||||
Nodes (33): PaginationDto, SortOrder, ApiPropertyOptional, IsEnum, IsInt, IsOptional, IsString, Min (+25 more)
|
||||
|
||||
### Community 108 - "PrismaService"
|
||||
Cohesion: 0.07
|
||||
Nodes (19): CategoryQuery, RevalidationService, Injectable, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery (+11 more)
|
||||
Cohesion: 0.08
|
||||
Nodes (17): CategoryQuery, MeliPayamakPattern, MeliPayamakResponse, SendPatternSmsOptions, SmsConfig, SmsLogQuery, CreateContactSubmissionDto, UpdateContactInfoItemDto (+9 more)
|
||||
|
||||
### Community 109 - "1. Summary of Integrity Repairs Performed"
|
||||
Cohesion: 0.17
|
||||
@ -1036,9 +1037,9 @@ Nodes (3): Architectural Overview, Critical Review Findings & Required Enhanceme
|
||||
Cohesion: 0.50
|
||||
Nodes (3): Overview & Content Foundation, SEO & Content Requirements, 🚀 SEO & Content Strategy Review (12_seo_content)
|
||||
|
||||
### Community 184 - "RedisService"
|
||||
Cohesion: 0.10
|
||||
Nodes (10): ApiExcludeController, MetricsController, Controller, Get, Res, RedisModule, Global, Module (+2 more)
|
||||
### Community 184 - "MetricsController"
|
||||
Cohesion: 0.20
|
||||
Nodes (5): ApiExcludeController, MetricsController, Controller, Get, Res
|
||||
|
||||
### Community 191 - "graphify reference: add a URL and watch a folder"
|
||||
Cohesion: 0.50
|
||||
@ -1084,6 +1085,10 @@ Nodes (3): ADR-AUTH-001: Admin Panel Authentication Architecture & Token Managem
|
||||
Cohesion: 0.67
|
||||
Nodes (3): Shabnam Font README, Shabnam Font Sample, Vazir Font
|
||||
|
||||
### Community 231 - "RevalidationService"
|
||||
Cohesion: 0.12
|
||||
Nodes (7): RevalidationModule, Global, Module, RevalidationService, Injectable, RedisService, Injectable
|
||||
|
||||
### Community 298 - ".initiateOrderPayment"
|
||||
Cohesion: 0.20
|
||||
Nodes (10): ApiPropertyOptional, IsOptional, IsString, ZibalCallbackQueryDto, ApiBadRequestResponse, ApiOkResponse, Req, Res (+2 more)
|
||||
@ -1113,7 +1118,7 @@ _Questions this graph is uniquely positioned to answer:_
|
||||
- **What connects `$schema`, `collection`, `sourceRoot` to the rest of the system?**
|
||||
_1337 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||
- **Should `app.module.ts` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.059562841530054644 - nodes in this community are weakly interconnected._
|
||||
_Cohesion score 0.06516290726817042 - nodes in this community are weakly interconnected._
|
||||
- **Should `SmsService` be split into smaller, more focused modules?**
|
||||
_Cohesion score 0.055040197897340756 - nodes in this community are weakly interconnected._
|
||||
- **Should `ProductService` be split into smaller, more focused modules?**
|
||||
|
||||
2
graphify-out/cache/stat-index.json
vendored
2
graphify-out/cache/stat-index.json
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user