Add AST cache for AdminLogsTest.php with extracted nodes and edges

This commit is contained in:
hamed
2026-07-10 09:48:45 +03:30
parent 9d2023a72f
commit 11efed4100
13 changed files with 1133 additions and 791 deletions
+34
View File
@@ -83,8 +83,42 @@ export const api = {
put: <T>(path: string, body: unknown) =>
request<T>(path, { method: 'PUT', body: JSON.stringify(body) }),
delete: <T>(path: string) => request<T>(path, { method: 'DELETE' }),
download: (path: string) => downloadFile(path),
};
// دانلود فایل با ارسال توکن JWT در هدر و ذخیره روی دیسک کاربر
async function downloadFile(path: string, retry = true): Promise<void> {
const token = getToken();
const headers: Record<string, string> = {};
if (token) headers['Authorization'] = `Bearer ${token}`;
const res = await fetch(`${BASE_URL}${path}`, { headers });
if (!res.ok) {
if (res.status === 401 && retry) {
const newToken = await refreshOnce();
if (newToken) return downloadFile(path, false);
useAuthStore.getState().logout();
window.location.replace('/admin/login');
}
throw new ApiError(res.status, 'ERR_DOWNLOAD', 'دانلود ناموفق بود');
}
const blob = await res.blob();
const disposition = res.headers.get('Content-Disposition') ?? '';
const match = disposition.match(/filename="?([^"]+)"?/);
const filename = match ? match[1] : 'download';
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}
export interface ApiResponse<T> {
success: boolean;
data: T;
+24 -1
View File
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { TrashIcon } from '@heroicons/react/24/outline';
import { TrashIcon, ArrowDownTrayIcon } from '@heroicons/react/24/outline';
import { api } from '../lib/api';
import type { PaginatedResponse, ApiResponse } from '../lib/api';
import type { AppLog } from '../types';
@@ -38,9 +38,22 @@ export default function LogsPage() {
const [search, setSearch] = useState('');
const [viewLog, setViewLog] = useState<AppLog | null>(null);
const [confirmClear, setConfirmClear] = useState(false);
const [downloading, setDownloading] = useState(false);
const limit = 25;
const queryClient = useQueryClient();
const handleDownload = async () => {
setDownloading(true);
try {
const qs =
(level ? `&level=${level}` : '') +
(search ? `&search=${encodeURIComponent(search)}` : '');
await api.download(`/api/v1/admin/logs/export?${qs}`);
} finally {
setDownloading(false);
}
};
const logsQuery = useQuery({
queryKey: ['admin-logs', page, level, search],
queryFn: () =>
@@ -95,6 +108,15 @@ export default function LogsPage() {
<div className="muted">رویدادهای ثبتشدهی سیستم (اخطار و بالاتر)</div>
</div>
{tab === 'logs' && (
<div style={{ display: 'flex', gap: 8 }}>
<button
className="btn ghost sm"
onClick={handleDownload}
disabled={downloading || (logsQuery.data?.meta?.totalRecords ?? 0) === 0}
>
<ArrowDownTrayIcon style={{ width: 16, height: 16 }} />
{downloading ? 'در حال دانلود...' : 'دانلود همه لاگ‌ها'}
</button>
<button
className="btn danger sm"
onClick={() => setConfirmClear(true)}
@@ -103,6 +125,7 @@ export default function LogsPage() {
<TrashIcon style={{ width: 16, height: 16 }} />
حذف همه لاگها
</button>
</div>
)}
</div>
+19
View File
@@ -1216,6 +1216,25 @@ Notes:
- `context` is a JSON string (or `null`); a `Throwable` in the context is stored as a compact `Class: message @ file:line` string, never the raw object.
- `created_at` is a Unix timestamp (integer).
### GET `/api/v1/admin/logs/export`
Export **all** matching logs as a CSV file (no pagination). Respects the same `level`, `search`, `from`, `to` filters as the list endpoint. Ordered newest first (`id DESC`).
**Permission:** `ROLE_ADMIN`
### Query Parameters
| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `level` | string | ❌ | Exact PSR level: `warning`, `error`, `critical`, `alert`, `emergency` |
| `search` | string | ❌ | Substring match on the message |
| `from` | integer | ❌ | Unix timestamp lower bound (`created_at >=`) |
| `to` | integer | ❌ | Unix timestamp upper bound (`created_at <=`) |
#### Response `200`
- `Content-Type: text/csv; charset=UTF-8`
- `Content-Disposition: attachment; filename="logs-YYYYMMDD-HHMMSS.csv"`
- Streamed CSV with a UTF-8 BOM (Excel-friendly for Persian). Columns: `id, level, message, context, channel, path, created_at`. `created_at` is formatted as `Y-m-d H:i:s`.
### DELETE `/api/v1/admin/logs`
Delete **all** persisted logs (truncate the `app_log` table). Irreversible.
-15
View File
@@ -693,37 +693,26 @@
"691": "Community 691",
"692": "Community 692",
"693": "Community 693",
"694": "Community 694",
"695": "Community 695",
"696": "Community 696",
"697": "Community 697",
"698": "Community 698",
"699": "Community 699",
"700": "Community 700",
"701": "Community 701",
"702": "Community 702",
"703": "Community 703",
"704": "Community 704",
"705": "Community 705",
"706": "Community 706",
"707": "Community 707",
"708": "Community 708",
"709": "Community 709",
"710": "Community 710",
"711": "Community 711",
"712": "Community 712",
"713": "Community 713",
"714": "Community 714",
"715": "Community 715",
"716": "Community 716",
"717": "Community 717",
"718": "Community 718",
"719": "Community 719",
"720": "Community 720",
"721": "Community 721",
"722": "Community 722",
"723": "Community 723",
"724": "Community 724",
"725": "Community 725",
"726": "Community 726",
"727": "Community 727",
@@ -731,9 +720,5 @@
"729": "Community 729",
"730": "Community 730",
"731": "Community 731",
"732": "Community 732",
"733": "Community 733",
"734": "Community 734",
"735": "Community 735",
"738": "Community 738"
}
+125 -176
View File
@@ -1,16 +1,16 @@
# Graph Report - clinicpro (2026-07-09)
# Graph Report - clinicpro (2026-07-10)
## Corpus Check
- 728 files · ~537,442 words
- 728 files · ~538,154 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 9196 nodes · 12725 edges · 737 communities (586 shown, 151 thin omitted)
- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 278 edges (avg confidence: 0.8)
- 9204 nodes · 12739 edges · 722 communities (577 shown, 145 thin omitted)
- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 279 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `0750bc98`
- Built from commit: `9d2023a7`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@@ -694,37 +694,26 @@
- [[_COMMUNITY_Community 691|Community 691]]
- [[_COMMUNITY_Community 692|Community 692]]
- [[_COMMUNITY_Community 693|Community 693]]
- [[_COMMUNITY_Community 694|Community 694]]
- [[_COMMUNITY_Community 695|Community 695]]
- [[_COMMUNITY_Community 696|Community 696]]
- [[_COMMUNITY_Community 697|Community 697]]
- [[_COMMUNITY_Community 698|Community 698]]
- [[_COMMUNITY_Community 699|Community 699]]
- [[_COMMUNITY_Community 700|Community 700]]
- [[_COMMUNITY_Community 701|Community 701]]
- [[_COMMUNITY_Community 702|Community 702]]
- [[_COMMUNITY_Community 703|Community 703]]
- [[_COMMUNITY_Community 704|Community 704]]
- [[_COMMUNITY_Community 705|Community 705]]
- [[_COMMUNITY_Community 706|Community 706]]
- [[_COMMUNITY_Community 707|Community 707]]
- [[_COMMUNITY_Community 708|Community 708]]
- [[_COMMUNITY_Community 709|Community 709]]
- [[_COMMUNITY_Community 710|Community 710]]
- [[_COMMUNITY_Community 711|Community 711]]
- [[_COMMUNITY_Community 712|Community 712]]
- [[_COMMUNITY_Community 713|Community 713]]
- [[_COMMUNITY_Community 714|Community 714]]
- [[_COMMUNITY_Community 715|Community 715]]
- [[_COMMUNITY_Community 716|Community 716]]
- [[_COMMUNITY_Community 717|Community 717]]
- [[_COMMUNITY_Community 718|Community 718]]
- [[_COMMUNITY_Community 719|Community 719]]
- [[_COMMUNITY_Community 720|Community 720]]
- [[_COMMUNITY_Community 721|Community 721]]
- [[_COMMUNITY_Community 722|Community 722]]
- [[_COMMUNITY_Community 723|Community 723]]
- [[_COMMUNITY_Community 724|Community 724]]
- [[_COMMUNITY_Community 725|Community 725]]
- [[_COMMUNITY_Community 726|Community 726]]
- [[_COMMUNITY_Community 727|Community 727]]
@@ -732,10 +721,6 @@
- [[_COMMUNITY_Community 729|Community 729]]
- [[_COMMUNITY_Community 730|Community 730]]
- [[_COMMUNITY_Community 731|Community 731]]
- [[_COMMUNITY_Community 732|Community 732]]
- [[_COMMUNITY_Community 733|Community 733]]
- [[_COMMUNITY_Community 734|Community 734]]
- [[_COMMUNITY_Community 735|Community 735]]
- [[_COMMUNITY_Community 738|Community 738]]
## God Nodes (most connected - your core abstractions)
@@ -747,29 +732,29 @@
6. `Doctor` - 48 edges
7. `useAuthStore` - 43 edges
8. `ApiResponse` - 41 edges
9. `AdminApiController` - 40 edges
9. `AdminApiController` - 41 edges
10. `formatDate()` - 39 edges
## Surprising Connections (you probably didn't know these)
- `ServiceTariffModal()` --calls--> `formatNumber()` [EXTRACTED]
assets/admin/components/ServiceTariffModal.tsx → assets/admin/lib/utils.ts
- `Pagination()` --calls--> `formatNumber()` [EXTRACTED]
assets/admin/components/ui/Pagination.tsx → assets/admin/lib/utils.ts
- `RepresentationSettlementPage()` --calls--> `formatRial()` [EXTRACTED]
assets/admin/pages/RepresentationSettlementPage.tsx → assets/admin/lib/utils.ts
- `SettlementsPage()` --calls--> `formatRial()` [EXTRACTED]
assets/admin/pages/SettlementsPage.tsx → assets/admin/lib/utils.ts
- `SmsPage()` --calls--> `formatDateTime()` [EXTRACTED]
assets/admin/pages/SmsPage.tsx → assets/admin/lib/utils.ts
- `NewAppointmentModal()` --calls--> `useAuthStore` [EXTRACTED]
assets/admin/pages/AppointmentsPage.tsx → assets/admin/stores/authStore.ts
- `LogoUploadField()` --calls--> `useAuthStore` [EXTRACTED]
assets/admin/pages/CategoriesPage.tsx → assets/admin/stores/authStore.ts
- `TabActions()` --calls--> `useAuthStore` [EXTRACTED]
assets/admin/pages/CategoriesPage.tsx → assets/admin/stores/authStore.ts
## Import Cycles
- None detected.
## Communities (737 total, 151 thin omitted)
## Communities (722 total, 145 thin omitted)
### Community 0 - "Community 0"
Cohesion: 0.05
Nodes (38): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, DEGREE_OPTIONS, DoctorFormPage() (+30 more)
Nodes (48): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, get, BeforeInstallPromptEvent (+40 more)
### Community 1 - "Community 1"
Cohesion: 0.03
@@ -800,8 +785,8 @@ Cohesion: 0.07
Nodes (5): Clinic, Collection, Doctor, self, User
### Community 8 - "Community 8"
Cohesion: 0.08
Nodes (27): useSubscription(), AdminLayout(), avatarBg(), buildSections(), HUES, Props, ROLE_LABELS, Section (+19 more)
Cohesion: 0.07
Nodes (27): Contract, InsuranceOption, KIND_LABEL, AdminLayout(), Topbar(), DEGREE_OPTIONS, DoctorFormPage(), FormValues (+19 more)
### Community 9 - "Community 9"
Cohesion: 0.04
@@ -820,8 +805,8 @@ Cohesion: 0.05
Nodes (44): Clinic Doctor Invitation API, DELETE `/api/v1/admin/clinic/invitation/{invUuid}`, Errors, Errors, Errors, Errors, Errors, Errors (+36 more)
### Community 13 - "Community 13"
Cohesion: 0.07
Nodes (25): get, api, ApiError, getToken(), refreshOnce(), request(), { refreshMock, logoutMock }, replaceMock (+17 more)
Cohesion: 0.08
Nodes (21): api, ApiError, downloadFile(), getToken(), refreshOnce(), request(), { refreshMock, logoutMock }, replaceMock (+13 more)
### Community 14 - "Community 14"
Cohesion: 0.10
@@ -832,8 +817,8 @@ Cohesion: 0.25
Nodes (7): PaymentController, Appointment, JsonResponse, Payment, Request, Response, User
### Community 16 - "Community 16"
Cohesion: 0.06
Nodes (8): PatientSession, SmsWallet, LogPruneService, Appointment, Collection, PatientRecord, self, SessionService
Cohesion: 0.09
Nodes (6): PatientSession, Appointment, Collection, PatientRecord, self, SessionService
### Community 17 - "Community 17"
Cohesion: 0.05
@@ -845,19 +830,19 @@ Nodes (38): API, API, API, API, API, Route, Route, Route (+30 more)
### Community 19 - "Community 19"
Cohesion: 0.03
Nodes (81): PaginatedResponse, CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema, LogoUploadField(), ProvinceForm (+73 more)
Nodes (59): CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema, LogoUploadField(), ProvinceForm, provinceSchema (+51 more)
### Community 20 - "Community 20"
Cohesion: 0.13
Nodes (3): AdminApiController, JsonResponse, Request
Nodes (4): AdminApiController, JsonResponse, Request, StreamedResponse
### Community 21 - "Community 21"
Cohesion: 0.04
Nodes (59): PaymentConfig, PaymentGatewayInfo, usePaymentConfig(), ApiResponse, formatNumber(), formatRial(), ClinicDetailPage(), AdminCharts (+51 more)
Cohesion: 0.05
Nodes (34): formatNumber(), ClinicDetailPage(), AdminCharts, AdminDashboard(), AdminRecent, AdminStats, APPT_CLS, APPT_COLOR (+26 more)
### Community 22 - "Community 22"
Cohesion: 0.15
Nodes (9): RatingController, Like, LikeRepository, JsonResponse, Request, User, Comment, ManagerRegistry (+1 more)
Cohesion: 0.09
Nodes (15): RatingController, Like, Rate, CommentListNPlusOneTest, LikeRepository, RateRepository, JsonResponse, Request (+7 more)
### Community 23 - "Community 23"
Cohesion: 0.05
@@ -896,8 +881,8 @@ Cohesion: 0.06
Nodes (32): 10. Modal / Dialog, 11. Toast Notifications, 12. Empty States & Loading, 13. Page Header (هر صفحه), 14. تکنولوژی Stack, 15. Responsive Breakpoints, 16. Dark Mode (اختیاری — فاز دوم), 17. نمونه رنگ‌بندی صفحه داشبورد (+24 more)
### Community 33 - "Community 33"
Cohesion: 0.07
Nodes (25): CoverageRow, Draft, KIND, TenantInsurance, ServiceTariffModal(), TariffResponse, TariffRow, EMPTY_ITEMS (+17 more)
Cohesion: 0.08
Nodes (21): CoverageRow, Draft, KIND, TenantInsurance, ServiceTariffModal(), TariffResponse, TariffRow, EMPTY_ITEMS (+13 more)
### Community 34 - "Community 34"
Cohesion: 0.06
@@ -927,6 +912,10 @@ Nodes (5): DoctorAddress, City, Doctor, Province, self
Cohesion: 0.09
Nodes (4): User, PasswordAuthenticatedUserInterface, self, UserInterface
### Community 41 - "Community 41"
Cohesion: 0.07
Nodes (29): ApiResponse, PaginatedResponse, STATUS_FILTERS, FILTERS, Breakdown, SOURCE_LABEL, Summary, LEVEL_FILTER_OPTIONS (+21 more)
### Community 42 - "Community 42"
Cohesion: 0.07
Nodes (29): API calls (با `useMutation`):, API موجود:, Frontend موجود:, `PATCH /api/v1/clinic/{clinicUuid}/doctor/{doctorUuid}/deactivate`, `PATCH /api/v1/clinic/{clinicUuid}/doctor/{doctorUuid}/reactivate`, UX نکات:, آپدیت `GET /api/v1/clinic/doctor-list/{clinicUuid}` (فیلدهای جدید), آپدیت interface: (+21 more)
@@ -956,8 +945,8 @@ Cohesion: 0.11
Nodes (4): Payment, Appointment, self, User
### Community 49 - "Community 49"
Cohesion: 0.09
Nodes (18): AppointmentsPage(), BookingSlot, CancelledBadge(), DateNavigator(), EMPTY_ARR, getPersianWeekDay(), navBtnSx, NewAppointmentModal() (+10 more)
Cohesion: 0.07
Nodes (22): AppointmentsPage(), BookingSlot, CancelledBadge(), DateNavigator(), EMPTY_ARR, getPersianWeekDay(), navBtnSx, NewAppointmentModal() (+14 more)
### Community 50 - "Community 50"
Cohesion: 0.07
@@ -972,8 +961,8 @@ Cohesion: 0.07
Nodes (26): الزامات UI, باگ‌فیکس صفحه نوبت‌ها, باگ ۱ — کرش تقویم, باگ ۲ — روز هفته در DateNavigator, باگ ۳ — پیام «slot نیست», باگ ۴ — نوبت جدید: نام اجباری + find-or-create patient, باگ ۵ — patient_mobile نشان می‌دهد موبایل پزشک, باگ ۶ — نوبت‌های رزرو شده در نمایش زمانبندی (+18 more)
### Community 53 - "Community 53"
Cohesion: 0.10
Nodes (13): AppLogRepository, ClaimItemRepository, DoctorInsuranceRepository, InvoiceRepository, PreRegistrationRepository, ServiceEntityRepository, ManagerRegistry, ManagerRegistry (+5 more)
Cohesion: 0.08
Nodes (15): AppLogRepository, ClaimItemRepository, InvoiceItemRepository, PreRegistrationRepository, SessionServiceRepository, SiteConfigRepository, ServiceEntityRepository, ManagerRegistry (+7 more)
### Community 54 - "Community 54"
Cohesion: 0.10
@@ -992,8 +981,8 @@ Cohesion: 0.08
Nodes (24): Blog API, DELETE `/api/v1/blog/{uuid}`, Errors, Errors, Errors, Errors, Errors, GET `/api/v1/blog/{slug}` (+16 more)
### Community 58 - "Community 58"
Cohesion: 0.28
Nodes (4): Blog, BlogRepository, ManagerRegistry, QueryBuilder
Cohesion: 0.15
Nodes (8): Blog, BlogController, BlogRepository, JsonResponse, Request, User, ManagerRegistry, QueryBuilder
### Community 59 - "Community 59"
Cohesion: 0.22
@@ -1012,12 +1001,12 @@ Cohesion: 0.08
Nodes (25): Bulk import / export, DELETE `/api/v1/admin/specialty/{id}`, Errors, Errors, Errors, Errors, GET `/api/v1/admin/specialties`, GET `/api/v1/specialties` (+17 more)
### Community 63 - "Community 63"
Cohesion: 0.09
Nodes (20): FreeVisitPrice(), Pricing, rialToToman(), tomanToRial(), IbanItem, RepMe, RepresentationSettlementPage(), RepSummary (+12 more)
Cohesion: 0.05
Nodes (45): FreeVisitPrice(), Pricing, cn(), formatDateTime(), formatRial(), iranMobileOptionalSchema, iranMobileSchema, isValidIranMobile() (+37 more)
### Community 64 - "Community 64"
Cohesion: 0.29
Nodes (4): SmsWalletController, JsonResponse, Request, User
Cohesion: 0.19
Nodes (7): SmsWalletController, SmsSettingsRepository, SmsSettings, JsonResponse, Request, User, ManagerRegistry
### Community 65 - "Community 65"
Cohesion: 0.08
@@ -1041,7 +1030,7 @@ Nodes (12): رفع بهم‌ریختگی کامل پنل ادمین روی iPhon
### Community 71 - "Community 71"
Cohesion: 0.09
Nodes (21): AddForm, addSchema, ClinicsPage(), HUES_LIST, EMPTY, PreRegistration, STATUS_META, STATUS_TABS (+13 more)
Nodes (19): AddForm, addSchema, ClinicsPage(), HUES_LIST, EMPTY, PreRegistration, STATUS_META, STATUS_TABS (+11 more)
### Community 72 - "Community 72"
Cohesion: 0.09
@@ -1075,6 +1064,10 @@ Nodes (3): SubscriptionPlan, Collection, self
Cohesion: 0.09
Nodes (23): dependencies, @ckeditor/ckeditor5-build-classic, @ckeditor/ckeditor5-react, @fontsource/vazirmatn, @heroicons/react, @hookform/resolvers, jalaali-js, leaflet (+15 more)
### Community 82 - "Community 82"
Cohesion: 0.07
Nodes (8): CategoryImportTest, Connection, RepositoryClassMappingTest, KernelTestCase, DbLogger, CategoryImporter, DbLoggerTest, Stringable
### Community 83 - "Community 83"
Cohesion: 0.09
Nodes (21): Backend, CSS / UI, Frontend, روند اجرای هر قابلیت, قبل از شروع — تحلیل پرامپت و ساخت Todo, قوانین اجرا (اجباری — هیچ استثنایی ندارد), قوانین خاص این پروژه, مثال اجرا (+13 more)
@@ -1089,7 +1082,7 @@ Nodes (30): devDependencies, @babel/core, @babel/preset-env, @babel/preset-react
### Community 86 - "Community 86"
Cohesion: 0.06
Nodes (14): AppointmentExpiryServiceTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, ServiceItemStaffOwnershipTest, EntityManagerInterface, KernelBrowser, CommentPaginationTest (+6 more)
Nodes (15): AppointmentExpiryServiceTest, DateOverrideOwnershipTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, ServiceItemStaffOwnershipTest, EntityManagerInterface, KernelBrowser (+7 more)
### Community 87 - "Community 87"
Cohesion: 0.10
@@ -1160,8 +1153,8 @@ Cohesion: 0.11
Nodes (18): `AdminApiController::paymentDetail` — الان فقط GET, `MellatGateway.php` — الگوی موجود REST/SOAP (پس از کار sandbox), `PaymentGatewayInterface.php`, `PaymentManager.php` — الگوی log و transaction, برگشت/استرداد وجه ملت از پنل ادمین (bpReversalRequest / bpRefundRequest), زمینه, فایل‌های مرتبط, نکات مهم (+10 more)
### Community 104 - "Community 104"
Cohesion: 0.18
Nodes (6): TagController, TagRepository, JsonResponse, Request, ManagerRegistry, Tag
Cohesion: 0.35
Nodes (3): TagController, JsonResponse, Request
### Community 105 - "Community 105"
Cohesion: 0.11
@@ -1276,8 +1269,8 @@ Cohesion: 0.12
Nodes (16): Endpoint ها, GET /api/v1/representation/filter/{id}, GET /api/v1/representation/filter/{representationId}, GET /api/v1/representation/my-appointments/{id}, GET /api/v1/representation/{uuid}, GET /api/v1/representation/yearly-income/{id}, GET /api/v1/representation/yearly-income/{representationId}, POST /api/v1/representations/{id}/bank-accounts (+8 more)
### Community 135 - "Community 135"
Cohesion: 0.09
Nodes (22): Appointment Settings API, Available Locations, Day Index Convention, DELETE `/api/v1/booking-setting/{uuid}`, Errors, Errors, Errors, Errors (+14 more)
Cohesion: 0.12
Nodes (16): Day Index Convention, DELETE `/api/v1/booking-setting/{uuid}`, Errors, Errors, Errors, Errors, GET `/api/v1/appointment-settings/weekly-schedule/{uuid}`, PATCH `/api/v1/appointment-settings/weekly-schedule/{uuid}` (+8 more)
### Community 136 - "Community 136"
Cohesion: 0.12
@@ -1384,8 +1377,8 @@ Cohesion: 0.13
Nodes (13): Architecture, Auth, Backend (PHP/Symfony), Backend — `src/`, Category / Bundle system, Commands, Database, First-time setup (+5 more)
### Community 163 - "Community 163"
Cohesion: 0.11
Nodes (18): autoload, autoload-dev, psr-4, psr-4, conflict, symfony/symfony, description, extra (+10 more)
Cohesion: 0.13
Nodes (14): autoload, autoload-dev, psr-4, psr-4, conflict, symfony/symfony, description, license (+6 more)
### Community 164 - "Community 164"
Cohesion: 0.29
@@ -1408,8 +1401,8 @@ Cohesion: 0.10
Nodes (20): api.ir (استعلام هویت — Shahkar / IbanMatch), اتصال به دیتابیس‌های مستقل (الزامی), اسرار (الزامی — قبل از اولین دیپلوی), امنیت و منابع, بررسی سلامت, دامنه‌ها و CORS, دیپلوی‌های بعدی, راهنمای دیپلوی ClinicPro (Coolify + Docker Compose) (+12 more)
### Community 169 - "Community 169"
Cohesion: 0.15
Nodes (5): EntityInsurancePricing, TenantInsuranceCleanupTest, EntityInsurancePricingRepository, TenantInsuranceCleanupService, ManagerRegistry
Cohesion: 0.22
Nodes (4): EntityInsurancePricing, TenantInsuranceCleanupTest, EntityInsurancePricingRepository, ManagerRegistry
### Community 170 - "Community 170"
Cohesion: 0.13
@@ -1459,6 +1452,10 @@ Nodes (3): PatientRecord, Collection, User
Cohesion: 0.23
Nodes (3): WeeklySchedule, Doctor, self
### Community 182 - "Community 182"
Cohesion: 0.07
Nodes (5): SmsSettings, SmsWallet, LogPruneService, AppointmentExpiryService, self
### Community 183 - "Community 183"
Cohesion: 0.14
Nodes (13): `UserDetailPage.tsx` — فقط user query, زمینه, فایل‌های مرتبط, قرارداد پروفایل (`UserProfile.toArray`), مشکل / هدف, نمایش پروفایل کاربر در صفحه‌ی جزئیات کاربرِ پنل ادمین, نکات مهم, وضعیت فعلی (کد واقعی) (+5 more)
@@ -1528,8 +1525,8 @@ Cohesion: 0.14
Nodes (13): Endpoint ها, PATCH /api/v1/secretary/{uuid}, POST /api/v1/secretary, تسک ۱۴: ماژول منشی, توضیح, زمان تخمینی, ساختار JSON, سیستم مجوزها — Resource-Based Permissions (مقیاس‌پذیر) (+5 more)
### Community 201 - "Community 201"
Cohesion: 0.15
Nodes (13): Admin API, Clinic Invitation Management, GET `/api/v1/admin/pre-registrations`, GET `/api/v1/admin/secretaries`, GET /api/v1/admin/settings, PATCH /api/v1/admin/settings, POST `/api/v1/admin/pre-registrations/{uuid}/approve`, POST `/api/v1/admin/pre-registrations/{uuid}/reject` (+5 more)
Cohesion: 0.12
Nodes (16): Admin API, Clinic Invitation Management, Dashboard, GET `/api/v1/admin/dashboard/charts`, GET `/api/v1/admin/dashboard/recent`, GET `/api/v1/admin/dashboard/stats`, GET `/api/v1/admin/pre-registrations`, GET /api/v1/admin/settings (+8 more)
### Community 202 - "Community 202"
Cohesion: 0.15
@@ -1608,8 +1605,8 @@ Cohesion: 0.23
Nodes (5): PaymentRepository, Appointment, ManagerRegistry, Payment, User
### Community 225 - "Community 225"
Cohesion: 0.05
Nodes (37): formatDate(), formatDateTime(), ALL_STATUSES, AppointmentDetailPage(), timeOf(), Claim, ClaimItem, DebtRow (+29 more)
Cohesion: 0.09
Nodes (18): formatDate(), toDate(), ALL_STATUSES, AppointmentDetailPage(), timeOf(), Claim, ClaimItem, DebtRow (+10 more)
### Community 226 - "Community 226"
Cohesion: 0.15
@@ -1620,8 +1617,8 @@ Cohesion: 0.17
Nodes (11): تشخیص عمیق down شدن سرور بعد از ~۱۰ سیکل + وریفای و تکمیل فیکس‌های پایداری, زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی, وظایف, ۱. وریفای فیکس‌های repo (idempotent) (+3 more)
### Community 228 - "Community 228"
Cohesion: 0.20
Nodes (10): Bulk import / export, DELETE `/api/v1/admin/insurance/{id}`, DELETE `/api/v1/insurance/{id}`, EntityInsurancePricing — قیمت‌گذاری ویزیت بر اساس بیمه, GET `/api/v1/insurance/{id}`, Insurance API, Response `200`, Response `200` (+2 more)
Cohesion: 0.04
Nodes (47): Bulk import / export, DELETE `/api/v1/admin/insurance/{id}`, DELETE `/api/v1/billing/tenant-insurances/{uuid}`, DELETE `/api/v1/insurance/{id}`, EntityInsurancePricing — قیمت‌گذاری ویزیت بر اساس بیمه, Errors, Errors, Errors (+39 more)
### Community 229 - "Community 229"
Cohesion: 0.14
@@ -1760,8 +1757,8 @@ Cohesion: 0.30
Nodes (4): RepresentationRepository, ManagerRegistry, Representation, User
### Community 265 - "Community 265"
Cohesion: 0.06
Nodes (33): Contract, InsuranceOption, KIND_LABEL, calcFinalPrice(), EMPTY_RECORDS, EMPTY_SESSIONS, fileNumber(), getPatientName() (+25 more)
Cohesion: 0.08
Nodes (27): calcFinalPrice(), EMPTY_RECORDS, EMPTY_SESSIONS, fileNumber(), getPatientName(), getPatientPhone(), InsurancePricing, MyPatientsPageInner() (+19 more)
### Community 266 - "Community 266"
Cohesion: 0.33
@@ -1796,7 +1793,7 @@ Cohesion: 0.18
Nodes (10): Endpoint های موجود که تغییر می‌کنند, GET /api/v1/admin/dashboard/charts?from=UNIX&to=UNIX, GET /api/v1/dashboard/clinic, GET /api/v1/dashboard/doctor, تسک ۱۶: داشبورد هوشمند — چارت + فیلتر زمانی, توضیح, زمان تخمینی, فیلتر بازه زمانی (+2 more)
### Community 274 - "Community 274"
Cohesion: 0.21
Cohesion: 0.20
Nodes (5): Authentication, ClinicPro — API Documentation Index, Error Code Reference, Modules, Standard Response Envelope
### Community 275 - "Community 275"
@@ -1900,8 +1897,8 @@ Cohesion: 0.42
Nodes (3): PreRegistrationController, JsonResponse, Request
### Community 301 - "Community 301"
Cohesion: 0.06
Nodes (31): cn(), iranMobileOptionalSchema, iranMobileSchema, isValidIranMobile(), maskMobile(), sanitizeMobileInput(), toDate(), toEnglishDigits() (+23 more)
Cohesion: 0.07
Nodes (18): ClinicAddress, ClinicDoctorItem, ClinicInvitation, EditForm, editSchema, HUES_LIST, INV_STATUS_MAP, IRAN_CENTER (+10 more)
### Community 302 - "Community 302"
Cohesion: 0.12
@@ -1912,8 +1909,8 @@ Cohesion: 0.12
Nodes (16): آماده‌سازی پروژه ClinicPro برای دیپلوی روی Coolify با Docker Compose, زمینه, فایل‌های مرتبط, نکات مهم (محدودیت‌ها و edge caseها), هدف, وظایف, ۱. ساخت `Dockerfile` چندمرحله‌ای, ۱۰. ساخت راهنمای `docs/deploy/coolify.md` (+8 more)
### Community 304 - "Community 304"
Cohesion: 0.22
Nodes (9): 29. 🟢 `GET` clinic list 🆕, 30. 🟢 `GET` get 🆕, 33. 🔵 `POST` image_clinic, 6. کلینیک (Clinic), هدرهای اضافی, پارامترهای Query, پاسخ‌ها, پاسخ‌ها (+1 more)
Cohesion: 0.04
Nodes (47): 29. 🟢 `GET` clinic list 🆕, 30. 🟢 `GET` get 🆕, 33. 🔵 `POST` image_clinic, 34. 🔵 `POST` image logo, 36. 🟢 `GET` get my rate, 37. 🔵 `POST` post, 38. 🟢 `GET` Unapproved comments, 39. 🟡 `PATCH` Comment confirmation (+39 more)
### Community 306 - "Community 306"
Cohesion: 0.07
@@ -2012,8 +2009,8 @@ Cohesion: 0.22
Nodes (8): Query های جدید, بیماران منحصربه‌فرد در بازه, درآمد بر اساس روز (از patient_sessions), فروش اشتراک بر اساس پنل (admin), نوبت‌ها بر اساس روز (admin chart), نکات مهم, هیچ migration لازم نیست, پایگاه داده — تسک ۱۶: داشبورد هوشمند
### Community 333 - "Community 333"
Cohesion: 0.05
Nodes (40): DELETE `/api/v1/clinic-pro/doctor-address/{id}`, Doctor API, Errors, Errors, Errors, Errors, Errors, Errors (+32 more)
Cohesion: 0.25
Nodes (7): DELETE `/api/v1/clinic-pro/doctor-address/{id}`, Doctor API, Errors, GET `/api/v1/doctors`, Query Parameters, Response `200`, Response `200`
### Community 334 - "Community 334"
Cohesion: 0.25
@@ -2140,8 +2137,8 @@ Cohesion: 0.25
Nodes (7): ادمین, دکتر نمونه کامل — تبریز, دکتران bulk (۱۵۰۰ دکتر در ۱۵ شهر), ساخت مجدد, منشی دکتر نمونه, کاربران تستی, کلینیک نمونه — تبریز
### Community 367 - "Community 367"
Cohesion: 0.29
Nodes (7): Dashboard, GET `/api/v1/admin/dashboard/charts`, GET `/api/v1/admin/dashboard/recent`, GET `/api/v1/admin/dashboard/stats`, Response `200`, Response `200`, Response `200`
Cohesion: 0.13
Nodes (12): AdminUserDetail, AVATAR_COLORS, EditForm, editSchema, GENDER_LABELS, getPrimaryRole(), MARITAL_LABELS, MEDICAL_SECTIONS (+4 more)
### Community 368 - "Community 368"
Cohesion: 0.36
@@ -2261,7 +2258,7 @@ Nodes (7): initiate(), refund(), reverse(), verify(), PaymentInitResult, Payment
### Community 399 - "Community 399"
Cohesion: 0.23
Nodes (5): AbstractMigration, Schema, Version20260609130407, Schema, Version20260628165710
Nodes (5): AbstractMigration, Schema, Version20260609130407, Schema, Version20260611075829
### Community 401 - "Community 401"
Cohesion: 0.12
@@ -2272,7 +2269,7 @@ Cohesion: 0.11
Nodes (17): بازطراحی معماری پرداخت — سرویس‌محور، امن، توسعه‌پذیر (Backend), تست دستی (ddev، در حالت `payment_test_mode=1`), خروجی نهایی (طبق spec — در گزارش اجرا ارائه شود), زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی (+9 more)
### Community 407 - "Community 407"
Cohesion: 0.16
Cohesion: 0.15
Nodes (11): MessageBusInterface, MockObject, SmsService, SmsServiceLookupOnlyTest, SmsLogRepository, SmsMessageTemplateRepository, SmsService, SmsTextResolver (+3 more)
### Community 418 - "Community 418"
@@ -2296,12 +2293,12 @@ Cohesion: 0.35
Nodes (5): PatientController, JsonResponse, PatientSession, Request, User
### Community 435 - "Community 435"
Cohesion: 0.33
Nodes (4): BlogController, JsonResponse, Request, User
Cohesion: 0.43
Nodes (3): InvoiceRepository, Invoice, ManagerRegistry
### Community 439 - "Community 439"
Cohesion: 0.43
Nodes (3): InvoiceItemRepository, InvoiceItem, ManagerRegistry
Cohesion: 0.39
Nodes (3): TagRepository, ManagerRegistry, Tag
### Community 440 - "Community 440"
Cohesion: 0.11
@@ -2407,6 +2404,14 @@ Nodes (3): TaxRateHistoryRepository, ManagerRegistry, TaxRateHistory
Cohesion: 0.47
Nodes (3): CommissionService, Payment, Representation
### Community 483 - "Community 483"
Cohesion: 0.29
Nodes (6): Appointment Settings API, Available Locations, Errors, `GET /api/v1/appointment-settings/available-locations/{doctorUuid}`, Response `200`, Slot Calculation Logic (Reference)
### Community 485 - "Community 485"
Cohesion: 0.43
Nodes (3): SmsMessageController, JsonResponse, Request
### Community 486 - "Community 486"
Cohesion: 0.40
Nodes (5): ۲.۸ تنظیمات نوبت (Appointment Settings), ۲.۸.۱ برنامه هفتگی (Weekly Schedule), ۲.۸.۲ تعطیلات (Holidays), ۲.۸.۳ لغو تعطیل (Date Override), ۲.۸.۴ الگوریتم محاسبه اسلات‌های خالی
@@ -2420,8 +2425,8 @@ Cohesion: 0.40
Nodes (5): Admin Endpoints, GET /api/v1/admin/sms/settings/review, GET /api/v1/admin/sms/wallet-report, POST /api/v1/admin/sms/settings/{id}/approve, POST /api/v1/admin/sms/settings/{id}/reject
### Community 490 - "Community 490"
Cohesion: 0.15
Nodes (11): emptyFeatures(), FEATURE_KEYS, FEATURE_LABELS, PeriodForm, periodSchema, PLAN_DISPLAY, PlanForm, planSchema (+3 more)
Cohesion: 0.06
Nodes (29): PaymentConfig, PaymentGatewayInfo, usePaymentConfig(), emptyFeatures(), FEATURE_KEYS, FEATURE_LABELS, PeriodForm, periodSchema (+21 more)
### Community 491 - "Community 491"
Cohesion: 0.12
@@ -2592,8 +2597,8 @@ Cohesion: 0.22
Nodes (3): AppException, SlotTakenException, RuntimeException
### Community 542 - "Community 542"
Cohesion: 0.50
Nodes (4): 38. 🟢 `GET` Unapproved comments, هدرهای اضافی, پارامترهای Query, پاسخ‌ها
Cohesion: 0.48
Nodes (3): DoctorInsuranceRepository, DoctorInsurance, ManagerRegistry
### Community 543 - "Community 543"
Cohesion: 0.30
@@ -2660,8 +2665,8 @@ Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/admin/sms/template/{uuid}/reject`, Request Body, Response `200`
### Community 559 - "Community 559"
Cohesion: 0.16
Nodes (7): SmsMessageController, SmsMessageTemplateRepository, SmsTextResolver, SmsMessageTemplate, JsonResponse, Request, ManagerRegistry
Cohesion: 0.25
Nodes (4): SmsMessageTemplateRepository, SmsTextResolver, SmsMessageTemplate, ManagerRegistry
### Community 560 - "Community 560"
Cohesion: 0.50
@@ -2747,10 +2752,6 @@ Nodes (3): Entity: Payment, ساختار فایل‌ها, معماری — تس
Cohesion: 0.40
Nodes (5): Errors, GET `/api/v1/clinic/my-doctor/{doctorUuid}`, Path Parameters, Response `200`, Schedule Fields Notes
### Community 596 - "Community 596"
Cohesion: 0.38
Nodes (3): RepositoryClassMappingTest, KernelTestCase, DbLoggerTest
### Community 597 - "Community 597"
Cohesion: 0.29
Nodes (7): Configuration, Errors, GET `/api/v1/admin/sms/templates`, GET `/api/v1/sms/template/{uuid}`, Response `200`, Response `200`, SMS API
@@ -2775,10 +2776,6 @@ Nodes (3): ماژول‌های شناسایی‌شده در PRD, موارد پو
Cohesion: 0.67
Nodes (3): نقاط ضعف, نقاط قوت, ۶. تحلیل API Design
### Community 606 - "Community 606"
Cohesion: 0.15
Nodes (3): LoggerInterface, RanginehProvider, ApiIrService
### Community 607 - "Community 607"
Cohesion: 0.34
Nodes (5): RepresentationController, JsonResponse, Representation, Request, User
@@ -2788,8 +2785,8 @@ Cohesion: 0.67
Nodes (3): بک‌اند, فرانت‌اند, وضعیت فعلی کد (مهم — قبل از تغییر بخوان)
### Community 618 - "Community 618"
Cohesion: 0.16
Nodes (5): ServiceItemDeleteCleanupTest, ServiceCoverageNPlusOneTest, TenantServiceCoverageRepository, ManagerRegistry, TenantServiceCoverage
Cohesion: 0.12
Nodes (6): ServiceItemDeleteCleanupTest, ServiceCoverageNPlusOneTest, TenantServiceCoverageRepository, TenantInsuranceCleanupService, ManagerRegistry, TenantServiceCoverage
### Community 631 - "Community 631"
Cohesion: 0.50
@@ -2799,10 +2796,6 @@ Nodes (4): GET `/api/v1/admin/representations`, Query Parameters, Representation
Cohesion: 0.50
Nodes (4): DELETE `/api/v1/doctor/{uuid}`, Errors, Path Parameters, Response `200`
### Community 633 - "Community 633"
Cohesion: 0.48
Nodes (3): SmsSettingsRepository, SmsSettings, ManagerRegistry
### Community 634 - "Community 634"
Cohesion: 0.47
Nodes (3): ImageCropModalProps, createImage(), getCroppedImage()
@@ -2812,8 +2805,8 @@ Cohesion: 0.12
Nodes (16): Runbook — تشخیص «ری‌استارت» سرور: recycle عادی یا خرابی واقعی؟, اقدامات تکمیلی روی سرور (خارج از repo), تأیید روی سرور — اسکریپت آماده, جدول تفسیر خروجی اسکریپت, خلاصه یک‌خطی, علامت مشکل, چرا این اتفاق می‌افتاد (و فیکس اعمال‌شده), چک‌لیست رفع (+8 more)
### Community 638 - "Community 638"
Cohesion: 0.53
Nodes (3): SessionServiceRepository, ManagerRegistry, SessionService
Cohesion: 0.40
Nodes (5): Errors, PATCH `/api/v1/doctor/{uuid}`, Path Parameters, Request Body (`application/json`), Response `200`
### Community 640 - "Community 640"
Cohesion: 0.40
@@ -2872,12 +2865,12 @@ Cohesion: 0.43
Nodes (3): SmsLogRepository, SmsLog, ManagerRegistry
### Community 662 - "Community 662"
Cohesion: 0.29
Nodes (7): Application Logs, DELETE `/api/v1/admin/logs`, GET `/api/v1/admin/logs`, Log Retention, Query Parameters, Response `200`, Response `200`
Cohesion: 0.20
Nodes (10): Application Logs, DELETE `/api/v1/admin/logs`, GET `/api/v1/admin/logs`, GET `/api/v1/admin/logs/export`, Log Retention, Query Parameters, Query Parameters, Response `200` (+2 more)
### Community 667 - "Community 667"
Cohesion: 0.40
Nodes (5): DELETE `/api/v1/billing/tenant-insurances/{uuid}`, GET `/api/v1/billing/tenant-insurances`, PATCH `/api/v1/billing/tenant-insurances/{uuid}`, POST `/api/v1/billing/tenant-insurances`, TenantInsurance — قراردادهای بیمه‌ی tenant (فاز ۱ سیستم صورتحساب)
Nodes (5): Errors, PATCH `/api/v1/clinic-pro/doctor-address/{id}`, Path Parameters, Request Body, Response `200`
### Community 672 - "Community 672"
Cohesion: 0.17
@@ -2888,20 +2881,20 @@ Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/user/register`, Request Body, Response `201`
### Community 674 - "Community 674"
Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/admin/insurances`, Query Parameters, Response `200`
Cohesion: 0.40
Nodes (3): Props, StatTone, TONE
### Community 675 - "Community 675"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/admin/insurance`, Request Body (`application/json`), Response `201`
Nodes (4): GET `/api/v1/admin/secretaries`, Query Parameters, Response `200`, Secretary Management
### Community 676 - "Community 676"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/insurance/`, Request Body (`application/json`), Response `201`
Nodes (4): Errors, POST `/api/v1/doctor`, Request Body (`application/json`), Response `201`
### Community 677 - "Community 677"
Cohesion: 0.43
Nodes (5): BeforeInstallPromptEvent, usePwaInstall(), PwaInstallBanner(), detectIOS(), PwaLoginCard()
Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/doctor/{uuid}`, Path Parameters, Response `200`
### Community 678 - "Community 678"
Cohesion: 0.50
@@ -2913,7 +2906,7 @@ Nodes (4): Errors, POST `/api/v1/auth/switch-context`, Request Body, Response `2
### Community 684 - "Community 684"
Cohesion: 0.50
Nodes (4): Errors, PATCH `/api/v1/insurance/{id}`, Request Body, Response `200`
Nodes (4): Errors, POST `/file/upload/clinic_pro/doctor/field_image`, Request, Response `200`
### Community 686 - "Community 686"
Cohesion: 0.40
@@ -2925,23 +2918,19 @@ Nodes (4): Errors, PATCH `/api/v1/admin/insurance/{id}`, Path Parameters, Respon
### Community 689 - "Community 689"
Cohesion: 0.50
Nodes (4): PUT `/api/v1/insurance-pricing`, Request Body, Response `200`, خطاها
Nodes (4): Errors, POST `/api/v1/clinic-pro/doctor-address`, Request Body, Response `201`
### Community 690 - "Community 690"
Cohesion: 0.67
Nodes (3): GET `/api/v1/billing/tenant-insurances/{uuid}/service-coverage`, PUT `/api/v1/billing/tenant-insurances/{uuid}/service-coverage`, TenantServiceCoverage — پوشش خدمت تحت یک قرارداد بیمه (فاز ۲)
Cohesion: 0.50
Nodes (4): Errors, Path Parameters, POST `/api/v1/clinic-pro/doctor-address/from-clinic/{clinicUuid}`, Response `201`
### Community 692 - "Community 692"
Cohesion: 0.67
Nodes (3): GET `/api/v1/insurance-pricing`, Response `200`, خطاها
Cohesion: 0.50
Nodes (4): extra, symfony, allow-contrib, require
### Community 693 - "Community 693"
Cohesion: 0.67
Nodes (3): GET `/api/v1/insurances`, Query Parameters, Response `200`
### Community 694 - "Community 694"
Cohesion: 0.67
Nodes (3): POST `/api/v1/admin/insurance/{id}/upload-logo`, Request, Response `200`
Nodes (3): GET `/api/v1/clinic-pro/doctor-addresses/{doctorId}`, Path Parameters, Response `200`
### Community 695 - "Community 695"
Cohesion: 0.67
@@ -2963,26 +2952,14 @@ Nodes (11): رفع خطای `Class "SoapClient" not found` در پرداخت م
Cohesion: 0.40
Nodes (5): 32. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 705 - "Community 705"
Cohesion: 0.40
Nodes (5): 37. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 706 - "Community 706"
Cohesion: 0.53
Nodes (3): PaymentLog, PaymentLogRepository, ManagerRegistry
### Community 707 - "Community 707"
Cohesion: 0.38
Nodes (5): Rate, RateRepository, Doctor, ManagerRegistry, User
### Community 708 - "Community 708"
Cohesion: 0.33
Nodes (4): PatientService, Appointment, PatientRecord, PatientSession
### Community 710 - "Community 710"
Cohesion: 0.50
Nodes (4): 39. 🟡 `PATCH` Comment confirmation, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 712 - "Community 712"
Cohesion: 0.50
Nodes (4): 44. 🟢 `GET` list comment, هدرهای اضافی, پارامترهای Query, پاسخ‌ها
@@ -2995,22 +2972,10 @@ Nodes (5): 31. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای
Cohesion: 0.40
Nodes (5): 35. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 716 - "Community 716"
Cohesion: 0.40
Nodes (5): 41. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 720 - "Community 720"
Cohesion: 0.33
Nodes (3): Closure, CorsRegexEnvProcessor, EnvVarProcessorInterface
### Community 723 - "Community 723"
Cohesion: 0.50
Nodes (4): 40. 🔵 `POST` post, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 724 - "Community 724"
Cohesion: 0.50
Nodes (4): 45. 🔵 `POST` post, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 725 - "Community 725"
Cohesion: 0.43
Nodes (3): InvoiceService, Invoice, PatientSession
@@ -3031,44 +2996,28 @@ Nodes (3): Errors, GET `/api/v1/notification-mobile/{target}`, Response `200`
Cohesion: 0.67
Nodes (3): GET `/api/v1/representation/{uuid}/dashboard/yearly`, Query Parameters, Response `200`
### Community 732 - "Community 732"
Cohesion: 0.67
Nodes (3): 36. 🟢 `GET` get my rate, هدرهای اضافی, پاسخ‌ها
### Community 733 - "Community 733"
Cohesion: 0.67
Nodes (3): 34. 🔵 `POST` image logo, هدرهای اضافی, پاسخ‌ها
### Community 734 - "Community 734"
Cohesion: 0.67
Nodes (3): 42. 🔴 `DELETE` delete, هدرهای اضافی, پاسخ‌ها
### Community 735 - "Community 735"
Cohesion: 0.67
Nodes (3): 43. 🟢 `GET` get, هدرهای اضافی, پاسخ‌ها
### Community 738 - "Community 738"
Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/representation/{uuid}`, Path Parameters, Response `200`
## Knowledge Gaps
- **4007 isolated node(s):** `ALLOWED_ROLES`, `Pricing`, `ImageCropModalProps`, `TenantInsurance`, `CoverageRow` (+4002 more)
- **4009 isolated node(s):** `ALLOWED_ROLES`, `Pricing`, `ImageCropModalProps`, `TenantInsurance`, `CoverageRow` (+4004 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **151 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **145 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `BaseController` connect `Community 108` to `Community 6`, `Community 138`, `Community 139`, `Community 14`, `Community 654`, `Community 655`, `Community 15`, `Community 20`, `Community 22`, `Community 26`, `Community 164`, `Community 295`, `Community 424`, `Community 300`, `Community 559`, `Community 433`, `Community 435`, `Community 308`, `Community 59`, `Community 318`, `Community 64`, `Community 75`, `Community 77`, `Community 607`, `Community 480`, `Community 230`, `Community 104`, `Community 107`, `Community 109`, `Community 245`, `Community 380`, `Community 121`, `Community 122`, `Community 252`?**
_High betweenness centrality (0.035) - this node is a cross-community bridge._
- **Why does `ApiTestCase` connect `Community 86` to `Community 397`, `Community 534`, `Community 535`, `Community 541`, `Community 41`, `Community 169`, `Community 562`, `Community 565`, `Community 573`, `Community 574`, `Community 575`, `Community 717`, `Community 718`, `Community 594`, `Community 82`, `Community 609`, `Community 484`, `Community 618`, `Community 497`, `Community 371`?**
_High betweenness centrality (0.022) - this node is a cross-community bridge._
- **Why does `BaseController` connect `Community 108` to `Community 6`, `Community 138`, `Community 139`, `Community 14`, `Community 654`, `Community 655`, `Community 15`, `Community 20`, `Community 22`, `Community 26`, `Community 164`, `Community 295`, `Community 424`, `Community 300`, `Community 433`, `Community 308`, `Community 58`, `Community 59`, `Community 318`, `Community 64`, `Community 75`, `Community 77`, `Community 607`, `Community 480`, `Community 485`, `Community 230`, `Community 104`, `Community 107`, `Community 109`, `Community 245`, `Community 380`, `Community 121`, `Community 122`, `Community 252`?**
_High betweenness centrality (0.026) - this node is a cross-community bridge._
- **Why does `Version20260705070546` connect `Community 646` to `Community 399`?**
_High betweenness centrality (0.019) - this node is a cross-community bridge._
- **Why does `ApiTestCase` connect `Community 86` to `Community 397`, `Community 22`, `Community 535`, `Community 534`, `Community 541`, `Community 169`, `Community 562`, `Community 565`, `Community 573`, `Community 574`, `Community 575`, `Community 594`, `Community 82`, `Community 609`, `Community 484`, `Community 618`, `Community 497`, `Community 371`, `Community 633`?**
_High betweenness centrality (0.018) - this node is a cross-community bridge._
- **What connects `ALLOWED_ROLES`, `Pricing`, `ImageCropModalProps` to the rest of the system?**
_4007 weakly-connected nodes found - possible documentation gaps or missing edges._
_4009 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `Community 0` be split into smaller, more focused modules?**
_Cohesion score 0.05200501253132832 - nodes in this community are weakly interconnected._
_Cohesion score 0.05004389815627744 - nodes in this community are weakly interconnected._
- **Should `Community 1` be split into smaller, more focused modules?**
_Cohesion score 0.028985507246376812 - nodes in this community are weakly interconnected._
- **Should `Community 2` be split into smaller, more focused modules?**
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 one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+805 -578
View File
File diff suppressed because it is too large Load Diff
+12 -12
View File
@@ -155,8 +155,8 @@
"semantic_hash": ""
},
"assets/admin/lib/api.ts": {
"mtime": 1782396341.3121104,
"ast_hash": "0c8c5044646343d9901c96c7ae4175b5",
"mtime": 1783663912.9593666,
"ast_hash": "e9eb6990a4e8b4467907f5df6fa87ef9",
"semantic_hash": ""
},
"assets/admin/lib/utils.ts": {
@@ -810,8 +810,8 @@
"semantic_hash": ""
},
"src/Admin/Controller/AdminApiController.php": {
"mtime": 1783569345.7785833,
"ast_hash": "76990cb279d535ab2d869f87752a185a",
"mtime": 1783663902.0176175,
"ast_hash": "1be6bc6af210c01303d49cf031d05593",
"semantic_hash": ""
},
"src/Admin/Controller/AdminController.php": {
@@ -2340,8 +2340,8 @@
"semantic_hash": ""
},
"docs/api/admin.md": {
"mtime": 1783569345.7769597,
"ast_hash": "c0e70f627d969f3449dbe58fe653a9bf",
"mtime": 1783663961.4046154,
"ast_hash": "0ecb4de166b81cb69125d9c6b59f8d16",
"semantic_hash": ""
},
"docs/api/appointment-settings.md": {
@@ -3245,8 +3245,8 @@
"semantic_hash": ""
},
"docker-compose.yml": {
"mtime": 1783520508.741232,
"ast_hash": "75c5d64fa9241dd92c5a0b9999f8241f",
"mtime": 1783608242.4596496,
"ast_hash": "466eb229daac6f54667dd7ecb20efadf",
"semantic_hash": ""
},
"docs/DEPLOY.md": {
@@ -3375,8 +3375,8 @@
"semantic_hash": ""
},
"assets/admin/pages/LogsPage.tsx": {
"mtime": 1782929861.6704445,
"ast_hash": "2e9aed8e9f683011985c6c932644892a",
"mtime": 1783663932.1559613,
"ast_hash": "c2b170578a588a65b894a7c5e2da2de5",
"semantic_hash": ""
},
"migrations/Version20260629161536.php": {
@@ -3400,8 +3400,8 @@
"semantic_hash": ""
},
"tests/Admin/AdminLogsTest.php": {
"mtime": 1782750195.979033,
"ast_hash": "6622637d75fe6e5fc81b9c9236f03191",
"mtime": 1783664104.075507,
"ast_hash": "738f8fd28b22ea6d6a9ed31d91c27b6b",
"semantic_hash": ""
},
"tests/Shared/DbLoggerTest.php": {
@@ -26,6 +26,7 @@ use Doctrine\ORM\EntityManagerInterface;
use OpenApi\Attributes as OA;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -2098,6 +2099,72 @@ class AdminApiController extends BaseController
], $rows), (int) $total, $page, $limit);
}
#[OA\Get(
path: '/api/v1/admin/logs/export',
summary: 'Export all persisted application logs as CSV (respects filters, no pagination)',
security: [['bearerAuth' => []]],
parameters: [
new OA\Parameter(name: 'level', in: 'query', required: false, description: 'PSR level filter (warning/error/critical/...)', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'search', in: 'query', required: false, description: 'substring match on message', schema: new OA\Schema(type: 'string')),
new OA\Parameter(name: 'from', in: 'query', required: false, description: 'unix timestamp lower bound', schema: new OA\Schema(type: 'integer')),
new OA\Parameter(name: 'to', in: 'query', required: false, description: 'unix timestamp upper bound', schema: new OA\Schema(type: 'integer')),
],
responses: [new OA\Response(response: 200, description: 'CSV file (text/csv) of all matching logs')]
)]
#[Route('/api/v1/admin/logs/export', methods: ['GET'])]
public function exportLogs(Request $request): StreamedResponse
{
$level = trim((string) $request->query->get('level', ''));
$search = trim((string) $request->query->get('search', ''));
$from = trim((string) $request->query->get('from', ''));
$to = trim((string) $request->query->get('to', ''));
$qb = $this->em->createQueryBuilder()
->select('l.id, l.level, l.message, l.context, l.channel, l.path, l.createdAt')
->from(AppLog::class, 'l');
if ($level !== '') {
$qb->andWhere('l.level = :level')->setParameter('level', $level);
}
if ($search !== '') {
$qb->andWhere('l.message LIKE :s')->setParameter('s', '%' . $search . '%');
}
if ($from !== '') {
$qb->andWhere('l.createdAt >= :from')->setParameter('from', (int) $from);
}
if ($to !== '') {
$qb->andWhere('l.createdAt <= :to')->setParameter('to', (int) $to);
}
$qb->orderBy('l.id', 'DESC');
$response = new StreamedResponse(function () use ($qb) {
$out = fopen('php://output', 'w');
// UTF-8 BOM so Excel renders Persian correctly
fwrite($out, "\xEF\xBB\xBF");
fputcsv($out, ['id', 'level', 'message', 'context', 'channel', 'path', 'created_at']);
foreach ($qb->getQuery()->toIterable([], \Doctrine\ORM\Query::HYDRATE_ARRAY) as $l) {
fputcsv($out, [
(int) $l['id'],
$l['level'],
$l['message'],
$l['context'],
$l['channel'],
$l['path'],
date('Y-m-d H:i:s', (int) $l['createdAt']),
]);
}
fclose($out);
});
$filename = 'logs-' . date('Ymd-His') . '.csv';
$response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
$response->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"');
return $response;
}
#[Route('/api/v1/admin/logs', methods: ['DELETE'])]
public function clearLogs(): JsonResponse
{
+35
View File
@@ -45,4 +45,39 @@ class AdminLogsTest extends ApiTestCase
$this->em->getConnection()->executeStatement('DELETE FROM app_log WHERE message LIKE ?', [$marker . '%']);
}
public function testExportNonAdminForbidden(): void
{
$user = $this->createUser(['ROLE_USER']);
$this->authJson('GET', '/api/v1/admin/logs/export', $user);
self::assertSame(403, $this->responseCode());
}
public function testAdminExportsCsvFilteredByLevel(): void
{
$marker = 'ADMINLOGEXPORT_' . bin2hex(random_bytes(5));
$this->seedLog('error', $marker . '_err');
$this->seedLog('warning', $marker . '_warn');
$admin = $this->createUser(['ROLE_ADMIN']);
$this->client->request(
'GET',
'/api/v1/admin/logs/export?level=error&search=' . $marker,
server: ['HTTP_AUTHORIZATION' => 'Bearer ' . $this->jwtFor($admin)],
);
$response = $this->client->getResponse();
self::assertSame(200, $response->getStatusCode());
self::assertStringContainsString('text/csv', (string) $response->headers->get('Content-Type'));
self::assertStringContainsString('attachment', (string) $response->headers->get('Content-Disposition'));
// StreamedResponse body is captured by BrowserKit into the internal response.
$csv = $this->client->getInternalResponse()->getContent();
self::assertStringContainsString('id,level,message', $csv);
self::assertStringContainsString($marker . '_err', $csv);
self::assertStringNotContainsString($marker . '_warn', $csv);
$this->em->getConnection()->executeStatement('DELETE FROM app_log WHERE message LIKE ?', [$marker . '%']);
}
}