Add AST cache files for AltchaService, API documentation, and AltchaService tests

- Created JSON representation of AltchaService class and its methods, including imports and relationships.
- Added documentation for the Captcha API, detailing endpoints and responses.
- Introduced test cases for AltchaService, covering various functionalities and edge cases.
This commit is contained in:
hamed
2026-07-10 11:42:23 +03:30
parent c3c520801d
commit ec184dfcc8
17 changed files with 1069 additions and 1039 deletions
+26 -10
View File
@@ -23,6 +23,7 @@ interface TaxHistoryRow {
const schema = z.object({
site_name: z.string().min(1, 'نام سایت الزامی است'),
support_phone: z.string(),
altcha_enabled: z.string(),
max_cancel_hours_before: z.string(),
appointment_reminder_hours: z.string(),
// financial engine
@@ -55,6 +56,7 @@ interface Settings extends FormValues {
const toForm = (s: Partial<Settings>): FormValues => ({
site_name: s.site_name ?? 'ClinicPro',
support_phone: s.support_phone ?? '',
altcha_enabled: s.altcha_enabled ?? '0',
max_cancel_hours_before: s.max_cancel_hours_before ?? '24',
appointment_reminder_hours: s.appointment_reminder_hours ?? '2',
appointment_commission_enabled: s.appointment_commission_enabled ?? '0',
@@ -91,7 +93,7 @@ interface SectionDef {
}
const SECTIONS: SectionDef[] = [
{ id: 'general', label: 'عمومی', desc: 'اطلاعات پایه پلتفرم', Icon: Cog6ToothIcon, bg: 'var(--primary-soft)', fg: 'var(--primary)', keywords: 'نام سایت پشتیبانی شماره تلفن brand' },
{ id: 'general', label: 'عمومی', desc: 'اطلاعات پایه پلتفرم', Icon: Cog6ToothIcon, bg: 'var(--primary-soft)', fg: 'var(--primary)', keywords: 'نام سایت پشتیبانی شماره تلفن brand کپچا امنیت altcha captcha بات' },
{ id: 'appointments', label: 'نوبت‌دهی', desc: 'قوانین لغو و یادآوری', Icon: ClockIcon, bg: 'var(--warning-bg)', fg: 'var(--warning)', keywords: 'نوبت لغو یادآور reminder cancel ساعت' },
{ id: 'financial', label: 'مالی', desc: 'پورسانت، مالیات و کارمزدها', Icon: CalculatorIcon, bg: 'var(--info-bg)', fg: 'var(--info)', keywords: 'پورسانت مالیات کارمزد پیامک نوبت مبلغ ریال tax commission' },
{ id: 'payment', label: 'درگاه پرداخت', desc: 'ملت، سپ و حالت تست', Icon: CreditCardIcon, bg: 'var(--success-bg)', fg: 'var(--success)', keywords: 'درگاه پرداخت ملت سپ mellat sep terminal تست gateway' },
@@ -218,6 +220,7 @@ export default function SettingsPage() {
const apptCommissionEnabled = watch('appointment_commission_enabled') === '1';
const upgradeCommissionEnabled = watch('upgrade_commission_enabled') === '1';
const taxEnabled = watch('tax_enabled') === '1';
const altchaEnabled = watch('altcha_enabled') === '1';
const toggle = (name: keyof FormValues, current: boolean) =>
setValue(name, current ? '0' : '1', { shouldDirty: true });
@@ -284,15 +287,28 @@ export default function SettingsPage() {
{/* عمومی */}
{current.id === 'general' && (
<div className="settings-grid">
<Field label="نام سایت" required error={errors.site_name?.message}
hint="عنوانی که در سربرگ سایت و پیامک‌ها استفاده می‌شود.">
<input {...register('site_name')} className={`input${errors.site_name ? ' err' : ''}`} placeholder="نام سایت" />
</Field>
<Field label="شماره پشتیبانی" optional hint="برای نمایش به کاربران در بخش تماس.">
<input {...register('support_phone')} className="input" dir="ltr" placeholder="021-12345678" />
</Field>
</div>
<>
<div className="settings-grid">
<Field label="نام سایت" required error={errors.site_name?.message}
hint="عنوانی که در سربرگ سایت و پیامک‌ها استفاده می‌شود.">
<input {...register('site_name')} className={`input${errors.site_name ? ' err' : ''}`} placeholder="نام سایت" />
</Field>
<Field label="شماره پشتیبانی" optional hint="برای نمایش به کاربران در بخش تماس.">
<input {...register('support_phone')} className="input" dir="ltr" placeholder="021-12345678" />
</Field>
</div>
{/* کپچا (ALTCHA) */}
<div className={`toggle-row${altchaEnabled ? ' on' : ''}`} style={{ marginTop: 18 }}>
<div>
<div className="tr-title">کپچای امنیتی (ALTCHA)</div>
<div className="tr-desc">
محافظت فرمهای ورود/ثبتنام در برابر بات. پیشفرض از متغیر محیطی سرور خوانده میشود؛ این کلید آن را override میکند.
</div>
</div>
<Toggle checked={altchaEnabled} onChange={() => toggle('altcha_enabled', altchaEnabled)} label="کپچای امنیتی ALTCHA" />
</div>
</>
)}
{/* نوبت‌دهی */}
+1 -1
View File
@@ -52,7 +52,7 @@ services:
App\Shared\Captcha\AltchaService:
arguments:
$hmacKey: '%env(ALTCHA_HMAC_KEY)%'
$enabled: '%env(bool:ALTCHA_ENABLED)%'
$envEnabled: '%env(bool:ALTCHA_ENABLED)%'
$maxNumber: '%env(int:ALTCHA_MAX_NUMBER)%'
$expireSeconds: '%env(int:ALTCHA_EXPIRE_SECONDS)%'
$altchaPool: '@altcha.pool'
+1
View File
@@ -1071,6 +1071,7 @@ Reject a pending request. **Permission:** `ROLE_ADMIN`
| `sms_price_rials` | `500` | هزینه هر پیامک ارسالی به ریال؛ مبنای محاسبهٔ تعداد پیامک از موجودی کیف‌پول (`GET /api/v1/sms/wallet/balance`). قابل ویرایش در `/admin/settings` → بخش پیامک |
| `appointment_fee_rials` | `150000` | مبلغ هر نوبت به ریال؛ مبلغی که بیمار هنگام رزرو آنلاین پرداخت می‌کند. backend از همین کلید می‌خواند و در `GET /api/v1/payment/config` expose می‌شود |
| `log_retention_days` | `90` | مدت نگهداری لاگ‌ها (روز)؛ کاماند روزانه `app:prune-logs` لاگ‌های قدیمی‌تر را حذف می‌کند. `0` = نگهداری نامحدود |
| `altcha_enabled` | _(از env)_ | فعال/غیرفعال کپچای ALTCHA (`1`/`0`). اگر ست شود بر `ALTCHA_ENABLED` env مقدم است؛ اگر ست نشده باشد `GET` مقدار مؤثرِ env را برمی‌گرداند. رجوع به [captcha.md](captcha.md) |
**ترتیب محاسبه** (در `CommissionService`): ۱) کسر `sms_panel_fee_rials` ۲) مالیاتِ استخراجی `afterSms × tax/(100+tax)` ۳) پورسانت = `netAfterTax × percent/100`. سهم نماینده به کیف‌پولش (`WalletTransaction` credit) واریز و یک ردیف `FinancialBreakdown` ثبت می‌شود (idempotent بر اساس `payment_id`).
+5 -2
View File
@@ -2,8 +2,11 @@
کپچای خودمیزبان مبتنی بر ALTCHA (Proof-of-Work، بدون تصویر، بدون سرویس خارجی). برای محافظت از endpointهای عمومی و بدون احراز هویت در برابر اسپم/بات.
- فعال/غیرفعال با `ALTCHA_ENABLED` (پیش‌فرض `false` در dev/test، در prod باید `true` شود).
- وقتی غیرفعال است، همه‌ی endpointها بدون فیلد `altcha` کار می‌کنند.
- فعال/غیرفعال از دو جا کنترل می‌شود:
1. **پنل ادمین** (`/admin/settings` → عمومی → کپچای امنیتی) — کلید `altcha_enabled` در `site_config`.
2. **متغیر محیطی** `ALTCHA_ENABLED` (پیش‌فرض/fallback).
- **اولویت:** اگر کلید پنل ست شده باشد مقدم است؛ در غیر این صورت به `ALTCHA_ENABLED` برمی‌گردد.
- وقتی غیرفعال است، همه‌ی endpointها بدون فیلد `altcha` کار می‌کنند و کلاینت‌ها (از `/altcha/config`) widget را نشان نمی‌دهند.
---
+12 -20
View File
@@ -560,6 +560,7 @@
"558": "Community 558",
"559": "Community 559",
"560": "Community 560",
"561": "Community 561",
"562": "Community 562",
"563": "Community 563",
"564": "Community 564",
@@ -624,16 +625,19 @@
"623": "Community 623",
"624": "Community 624",
"625": "Community 625",
"626": "Community 626",
"627": "Community 627",
"628": "Community 628",
"629": "Community 629",
"630": "Community 630",
"631": "Community 631",
"632": "Community 632",
"633": "Community 633",
"634": "Community 634",
"635": "Community 635",
"636": "Community 636",
"637": "Community 637",
"638": "Community 638",
"639": "Community 639",
"640": "Community 640",
"641": "Community 641",
@@ -653,6 +657,7 @@
"655": "Community 655",
"656": "Community 656",
"657": "Community 657",
"658": "Community 658",
"659": "Community 659",
"660": "Community 660",
"661": "Community 661",
@@ -661,13 +666,16 @@
"664": "Community 664",
"665": "Community 665",
"666": "Community 666",
"667": "Community 667",
"668": "Community 668",
"669": "Community 669",
"670": "Community 670",
"671": "Community 671",
"672": "Community 672",
"673": "Community 673",
"674": "Community 674",
"675": "Community 675",
"676": "Community 676",
"677": "Community 677",
"678": "Community 678",
"679": "Community 679",
@@ -681,6 +689,7 @@
"687": "Community 687",
"688": "Community 688",
"689": "Community 689",
"690": "Community 690",
"691": "Community 691",
"692": "Community 692",
"693": "Community 693",
@@ -690,11 +699,13 @@
"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",
@@ -705,25 +716,6 @@
"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",
"728": "Community 728",
"729": "Community 729",
"730": "Community 730",
"731": "Community 731",
"733": "Community 733",
"734": "Community 734",
"735": "Community 735",
"736": "Community 736",
"737": "Community 737",
"738": "Community 738",
"739": "Community 739"
"738": "Community 738"
}
+183 -239
View File
@@ -1,16 +1,16 @@
# Graph Report - clinicpro (2026-07-10)
## Corpus Check
- 736 files · ~541,658 words
- 736 files · ~541,964 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 9273 nodes · 12830 edges · 727 communities (581 shown, 146 thin omitted)
- 9274 nodes · 12833 edges · 719 communities (569 shown, 150 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: `6f2e0ec2`
- Built from commit: `c3c52080`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@@ -576,6 +576,7 @@
- [[_COMMUNITY_Community 558|Community 558]]
- [[_COMMUNITY_Community 559|Community 559]]
- [[_COMMUNITY_Community 560|Community 560]]
- [[_COMMUNITY_Community 561|Community 561]]
- [[_COMMUNITY_Community 562|Community 562]]
- [[_COMMUNITY_Community 563|Community 563]]
- [[_COMMUNITY_Community 565|Community 565]]
@@ -633,12 +634,15 @@
- [[_COMMUNITY_Community 620|Community 620]]
- [[_COMMUNITY_Community 621|Community 621]]
- [[_COMMUNITY_Community 625|Community 625]]
- [[_COMMUNITY_Community 626|Community 626]]
- [[_COMMUNITY_Community 631|Community 631]]
- [[_COMMUNITY_Community 632|Community 632]]
- [[_COMMUNITY_Community 633|Community 633]]
- [[_COMMUNITY_Community 634|Community 634]]
- [[_COMMUNITY_Community 635|Community 635]]
- [[_COMMUNITY_Community 636|Community 636]]
- [[_COMMUNITY_Community 637|Community 637]]
- [[_COMMUNITY_Community 638|Community 638]]
- [[_COMMUNITY_Community 639|Community 639]]
- [[_COMMUNITY_Community 640|Community 640]]
- [[_COMMUNITY_Community 641|Community 641]]
@@ -656,6 +660,7 @@
- [[_COMMUNITY_Community 655|Community 655]]
- [[_COMMUNITY_Community 656|Community 656]]
- [[_COMMUNITY_Community 657|Community 657]]
- [[_COMMUNITY_Community 658|Community 658]]
- [[_COMMUNITY_Community 659|Community 659]]
- [[_COMMUNITY_Community 660|Community 660]]
- [[_COMMUNITY_Community 661|Community 661]]
@@ -664,12 +669,15 @@
- [[_COMMUNITY_Community 664|Community 664]]
- [[_COMMUNITY_Community 665|Community 665]]
- [[_COMMUNITY_Community 666|Community 666]]
- [[_COMMUNITY_Community 667|Community 667]]
- [[_COMMUNITY_Community 668|Community 668]]
- [[_COMMUNITY_Community 669|Community 669]]
- [[_COMMUNITY_Community 671|Community 671]]
- [[_COMMUNITY_Community 672|Community 672]]
- [[_COMMUNITY_Community 673|Community 673]]
- [[_COMMUNITY_Community 674|Community 674]]
- [[_COMMUNITY_Community 675|Community 675]]
- [[_COMMUNITY_Community 676|Community 676]]
- [[_COMMUNITY_Community 677|Community 677]]
- [[_COMMUNITY_Community 678|Community 678]]
- [[_COMMUNITY_Community 679|Community 679]]
@@ -683,6 +691,7 @@
- [[_COMMUNITY_Community 687|Community 687]]
- [[_COMMUNITY_Community 688|Community 688]]
- [[_COMMUNITY_Community 689|Community 689]]
- [[_COMMUNITY_Community 690|Community 690]]
- [[_COMMUNITY_Community 691|Community 691]]
- [[_COMMUNITY_Community 692|Community 692]]
- [[_COMMUNITY_Community 693|Community 693]]
@@ -692,11 +701,13 @@
- [[_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]]
@@ -707,27 +718,8 @@
- [[_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 728|Community 728]]
- [[_COMMUNITY_Community 729|Community 729]]
- [[_COMMUNITY_Community 730|Community 730]]
- [[_COMMUNITY_Community 731|Community 731]]
- [[_COMMUNITY_Community 733|Community 733]]
- [[_COMMUNITY_Community 734|Community 734]]
- [[_COMMUNITY_Community 735|Community 735]]
- [[_COMMUNITY_Community 736|Community 736]]
- [[_COMMUNITY_Community 737|Community 737]]
- [[_COMMUNITY_Community 738|Community 738]]
- [[_COMMUNITY_Community 739|Community 739]]
## God Nodes (most connected - your core abstractions)
1. `BaseController` - 80 edges
@@ -744,27 +736,27 @@
## Surprising Connections (you probably didn't know these)
- `ServiceTariffModal()` --calls--> `formatNumber()` [EXTRACTED]
assets/admin/components/ServiceTariffModal.tsx → assets/admin/lib/utils.ts
- `LogsPage()` --calls--> `formatDateTime()` [EXTRACTED]
assets/admin/pages/LogsPage.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 (727 total, 146 thin omitted)
## Communities (719 total, 150 thin omitted)
### Community 0 - "Community 0"
Cohesion: 0.06
Nodes (35): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, DEGREE_OPTIONS, DoctorFormPage() (+27 more)
Cohesion: 0.05
Nodes (48): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, get, BeforeInstallPromptEvent (+40 more)
### Community 1 - "Community 1"
Cohesion: 0.03
Nodes (52): addMinutes(), AddressData, AddrForm, addrSchema, AVATAR_COLORS, BookingMeta, calcSlotCount(), CityOpt (+44 more)
Nodes (41): AddressData, AddrForm, addrSchema, AVATAR_COLORS, BookingMeta, CityOpt, DateOverrideData, DEFAULT_BOOKING_META (+33 more)
### Community 2 - "Community 2"
Cohesion: 0.10
@@ -775,24 +767,24 @@ Cohesion: 0.10
Nodes (20): `RepresentationActionController` — welcome به‌صورت inline (بدون تمپلت), `SmsMessageTemplate::DEFAULTS` (فاقد نام تمپلت و نگاشت token), `SmsService::sendNow` — انتخاب بین lookup و متن‌آزاد, الگوی فعلی همه‌ی call-siteها (به‌جز OTP) — متن‌آزاد، بدون `templateCode`, تبدیل همه‌ی پیامک‌های سیستمی به VerifyLookup کاوه‌نگار (تمپلت نام‌دار), تنها جای درست (OTP) — که باید الگوی بقیه شود, زمینه, فایل‌های مرتبط (+12 more)
### Community 4 - "Community 4"
Cohesion: 0.05
Nodes (11): DoctorServiceController, DoctorService, Doctor, DoctorServiceRepository, Collection, self, User, WeeklySchedule (+3 more)
Cohesion: 0.08
Nodes (5): Doctor, Collection, self, User, WeeklySchedule
### Community 5 - "Community 5"
Cohesion: 0.07
Nodes (3): UserProfile, self, User
### Community 6 - "Community 6"
Cohesion: 0.09
Nodes (15): SettlementController, SettlementRepository, WalletTransactionRepository, CommissionService, Settlement, JsonResponse, Request, User (+7 more)
Cohesion: 0.12
Nodes (12): SettlementController, SettlementRepository, WalletTransactionRepository, Settlement, JsonResponse, Request, User, ManagerRegistry (+4 more)
### Community 7 - "Community 7"
Cohesion: 0.07
Nodes (5): Clinic, Collection, Doctor, self, User
Cohesion: 0.05
Nodes (11): DoctorServiceController, DoctorService, Clinic, DoctorServiceRepository, Collection, Doctor, self, User (+3 more)
### Community 8 - "Community 8"
Cohesion: 0.16
Nodes (15): AdminLayout(), avatarBg(), buildSections(), HUES, Props, ROLE_LABELS, Section, SectionItem (+7 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
@@ -811,8 +803,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.04
Nodes (46): get, PaymentConfig, PaymentGatewayInfo, usePaymentConfig(), useSubscription(), api, ApiError, downloadFile() (+38 more)
Cohesion: 0.08
Nodes (21): api, ApiError, downloadFile(), getToken(), refreshOnce(), request(), { refreshMock, logoutMock }, replaceMock (+13 more)
### Community 14 - "Community 14"
Cohesion: 0.10
@@ -824,7 +816,7 @@ Nodes (7): PaymentController, Appointment, JsonResponse, Payment, Request, Respo
### Community 16 - "Community 16"
Cohesion: 0.06
Nodes (8): PatientSession, SmsWallet, AppointmentExpiryService, Appointment, Collection, PatientRecord, self, SessionService
Nodes (8): PatientSession, SmsWallet, AppLog, Appointment, Collection, PatientRecord, self, SessionService
### Community 17 - "Community 17"
Cohesion: 0.05
@@ -836,19 +828,19 @@ Nodes (38): API, API, API, API, API, Route, Route, Route (+30 more)
### Community 19 - "Community 19"
Cohesion: 0.03
Nodes (61): ALL_STATUSES, CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema, LogoUploadField(), ProvinceForm (+53 more)
Nodes (59): CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema, LogoUploadField(), ProvinceForm, provinceSchema (+51 more)
### Community 20 - "Community 20"
Cohesion: 0.13
Nodes (4): AdminApiController, JsonResponse, Request, StreamedResponse
### Community 21 - "Community 21"
Cohesion: 0.04
Nodes (43): formatNumber(), ClinicAddress, ClinicDetailPage(), ClinicDoctorItem, ClinicInvitation, EditForm, editSchema, HUES_LIST (+35 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.16
Nodes (9): RatingController, Rate, RateRepository, JsonResponse, Request, User, Doctor, ManagerRegistry (+1 more)
### Community 23 - "Community 23"
Cohesion: 0.05
@@ -878,10 +870,6 @@ Nodes (4): Appointment, Doctor, self, User
Cohesion: 0.06
Nodes (35): Bulk import / export, DELETE `/api/v1/admin/city/{id}`, DELETE `/api/v1/admin/province/{id}`, Errors, Errors, Errors, Errors, GET `/api/v1/admin/cities` (+27 more)
### Community 30 - "Community 30"
Cohesion: 0.09
Nodes (13): BillingCalculatorTest, BillingCalculator, Money, BillingCalculator, InvoiceService, PatientService, CoverageRule, ShareBreakdown (+5 more)
### Community 31 - "Community 31"
Cohesion: 0.06
Nodes (33): `AppointmentStatusDropdown.tsx`, Doctor Tabs در داشبورد کلینیک, Pagination, `PersianCalendar.tsx`, Stats Bar, Status Badge (inline قابل کلیک), Status Dropdown (کلیک روی badge), Toolbar (+25 more)
@@ -891,8 +879,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.06
Nodes (27): CoverageRow, Draft, KIND, TenantInsurance, ServiceTariffModal(), TariffResponse, TariffRow, EMPTY_ITEMS (+19 more)
Cohesion: 0.08
Nodes (21): CoverageRow, Draft, KIND, TenantInsurance, ServiceTariffModal(), TariffResponse, TariffRow, EMPTY_ITEMS (+13 more)
### Community 34 - "Community 34"
Cohesion: 0.06
@@ -911,8 +899,8 @@ Cohesion: 0.06
Nodes (31): API endpoint موجود برای آدرس دکتر:, `DELETE /api/v1/clinic/{clinicUuid}/address/{addressUuid}` — حذف, `docs/api/appointment-settings.md`:, `docs/api/clinic.md`:, Endpoint موجود (workaround که حذف می‌شود):, Entity `DoctorAddress`:, Frontend موجود (`DoctorDetailPage.tsx`):, `GET /api/v1/clinic/{clinicUuid}/addresses` — لیست آدرس‌ها (+23 more)
### Community 38 - "Community 38"
Cohesion: 0.25
Nodes (8): Authentication API, DELETE `/api/v1/notification-mobile/{target}`, Errors, Notification Mobile (OTP), POST `/oauth/logout`, Request Body, Response `200`, Response `200`
Cohesion: 0.05
Nodes (44): Authentication API, DELETE `/api/v1/notification-mobile/{target}`, Error Codes, Error Codes, Errors, Errors, Errors, Errors (+36 more)
### Community 39 - "Community 39"
Cohesion: 0.12
@@ -956,7 +944,7 @@ Nodes (4): Payment, Appointment, self, User
### Community 49 - "Community 49"
Cohesion: 0.07
Nodes (21): AppointmentsPage(), BookingSlot, CancelledBadge(), DateNavigator(), EMPTY_ARR, getPersianWeekDay(), navBtnSx, NewAppointmentModal() (+13 more)
Nodes (22): AppointmentsPage(), BookingSlot, CancelledBadge(), DateNavigator(), EMPTY_ARR, getPersianWeekDay(), navBtnSx, NewAppointmentModal() (+14 more)
### Community 50 - "Community 50"
Cohesion: 0.07
@@ -971,8 +959,8 @@ Cohesion: 0.07
Nodes (26): الزامات UI, باگ‌فیکس صفحه نوبت‌ها, باگ ۱ — کرش تقویم, باگ ۲ — روز هفته در DateNavigator, باگ ۳ — پیام «slot نیست», باگ ۴ — نوبت جدید: نام اجباری + find-or-create patient, باگ ۵ — patient_mobile نشان می‌دهد موبایل پزشک, باگ ۶ — نوبت‌های رزرو شده در نمایش زمانبندی (+18 more)
### Community 53 - "Community 53"
Cohesion: 0.07
Nodes (18): AppLogRepository, PaymentLog, ClaimItemRepository, PaymentLogRepository, PreRegistrationRepository, SessionServiceRepository, SiteConfigRepository, SmsSettingsRepository (+10 more)
Cohesion: 0.08
Nodes (16): AppLogRepository, PaymentLog, ClaimItemRepository, InvoiceItemRepository, InvoiceRepository, PaymentLogRepository, PreRegistrationRepository, ServiceEntityRepository (+8 more)
### Community 54 - "Community 54"
Cohesion: 0.10
@@ -991,8 +979,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,11 +1000,11 @@ Nodes (25): Bulk import / export, DELETE `/api/v1/admin/specialty/{id}`, Errors,
### Community 63 - "Community 63"
Cohesion: 0.05
Nodes (51): FreeVisitPrice(), Pricing, cn(), formatDate(), formatDateTime(), formatRial(), iranMobileOptionalSchema, isValidIranMobile() (+43 more)
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
@@ -1074,10 +1062,6 @@ 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.06
Nodes (11): CategoryImportTest, Connection, CategoryImportController, RepositoryClassMappingTest, KernelTestCase, DbLogger, CategoryImporter, DbLoggerTest (+3 more)
### Community 83 - "Community 83"
Cohesion: 0.09
Nodes (21): Backend, CSS / UI, Frontend, روند اجرای هر قابلیت, قبل از شروع — تحلیل پرامپت و ساخت Todo, قوانین اجرا (اجباری — هیچ استثنایی ندارد), قوانین خاص این پروژه, مثال اجرا (+13 more)
@@ -1091,8 +1075,8 @@ Cohesion: 0.07
Nodes (30): devDependencies, @babel/core, @babel/preset-env, @babel/preset-react, @babel/preset-typescript, core-js, @csstools/postcss-oklab-function, @hotwired/stimulus (+22 more)
### Community 86 - "Community 86"
Cohesion: 0.05
Nodes (16): AppointmentExpiryServiceTest, DateOverrideOwnershipTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, CaptchaFlowTest, ServiceItemDeleteCleanupTest, ServiceItemStaffOwnershipTest (+8 more)
Cohesion: 0.06
Nodes (15): AppointmentExpiryServiceTest, DateOverrideOwnershipTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, CaptchaFlowTest, ServiceItemStaffOwnershipTest, KernelBrowser (+7 more)
### Community 87 - "Community 87"
Cohesion: 0.10
@@ -1179,8 +1163,8 @@ Cohesion: 0.33
Nodes (6): AppointmentController, Appointment, Doctor, JsonResponse, Request, User
### Community 108 - "Community 108"
Cohesion: 0.14
Nodes (9): CaptchaController, BaseController, CategoryController, SiteContextController, JsonResponse, JsonResponse, Request, JsonResponse (+1 more)
Cohesion: 0.11
Nodes (12): CaptchaController, BaseController, CategoryController, CategoryImportController, SiteContextController, JsonResponse, JsonResponse, Request (+4 more)
### Community 109 - "Community 109"
Cohesion: 0.29
@@ -1380,7 +1364,7 @@ Nodes (15): Date Overrides, DELETE `/api/v1/appointment-settings/date-override/{
### Community 161 - "Community 161"
Cohesion: 0.24
Nodes (7): ClaimSubmitterInterface, ClaimService, ManualClaimSubmitter, Claim, Invoice, Claim, ClaimSubmissionResult
Nodes (5): ClaimsListNPlusOneTest, ClaimItem, ClaimService, Claim, Invoice
### Community 162 - "Community 162"
Cohesion: 0.13
@@ -1411,8 +1395,8 @@ Cohesion: 0.10
Nodes (20): api.ir (استعلام هویت — Shahkar / IbanMatch), اتصال به دیتابیس‌های مستقل (الزامی), اسرار (الزامی — قبل از اولین دیپلوی), امنیت و منابع, بررسی سلامت, دامنه‌ها و CORS, دیپلوی‌های بعدی, راهنمای دیپلوی ClinicPro (Coolify + Docker Compose) (+12 more)
### Community 169 - "Community 169"
Cohesion: 0.13
Nodes (7): EntityInsurancePricing, EntityInsurancePricingRepository, TenantServiceCoverageRepository, TenantInsuranceCleanupService, ManagerRegistry, ManagerRegistry, TenantServiceCoverage
Cohesion: 0.15
Nodes (5): EntityInsurancePricing, TenantInsuranceCleanupTest, EntityInsurancePricingRepository, TenantInsuranceCleanupService, ManagerRegistry
### Community 170 - "Community 170"
Cohesion: 0.13
@@ -1543,16 +1527,16 @@ Cohesion: 0.15
Nodes (12): Clinic Services API, DELETE /api/v1/service-item/{uuid}, DELETE /api/v1/service-section/{uuid}, GET /api/v1/service-items/{sectionUuid}, GET /api/v1/service-items/{uuid}/tariffs, GET /api/v1/service-sections, PATCH /api/v1/service-item/{uuid}, PATCH /api/v1/service-section/{uuid} (+4 more)
### Community 204 - "Community 204"
Cohesion: 0.21
Nodes (6): AuthenticationException, ExceptionSubscriber, SecurityHeadersSubscriber, EventSubscriberInterface, ExceptionEvent, ResponseEvent
Cohesion: 0.23
Nodes (5): ExceptionSubscriber, SecurityHeadersSubscriber, EventSubscriberInterface, ExceptionEvent, ResponseEvent
### Community 205 - "Community 205"
Cohesion: 0.07
Nodes (20): Command, CancelExpiredAppointmentsCommand, CreateAdminCommand, PruneLogsCommand, SeedCategoriesCommand, SeedDemoDataCommand, SeedSmsMessageTemplatesCommand, InputInterface (+12 more)
### Community 206 - "Community 206"
Cohesion: 0.06
Nodes (17): GatewayFactory, MellatGateway, MockGateway, SepGateway, MellatGateway, SepGateway, SoapClient, PaymentGatewayInterface (+9 more)
Cohesion: 0.21
Nodes (5): MellatGateway, SoapClient, PaymentInitResult, PaymentRefundResult, PaymentVerifyResult
### Community 207 - "Community 207"
Cohesion: 0.15
@@ -1611,8 +1595,8 @@ Cohesion: 0.23
Nodes (5): PaymentRepository, Appointment, ManagerRegistry, Payment, User
### Community 225 - "Community 225"
Cohesion: 0.07
Nodes (19): Contract, InsuranceOption, KIND_LABEL, FormData, schema, Claim, ClaimItem, DebtRow (+11 more)
Cohesion: 0.09
Nodes (18): formatDate(), toDate(), ALL_STATUSES, AppointmentDetailPage(), timeOf(), Claim, ClaimItem, DebtRow (+10 more)
### Community 226 - "Community 226"
Cohesion: 0.15
@@ -1623,8 +1607,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 (51): 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 (+43 more)
### Community 229 - "Community 229"
Cohesion: 0.14
@@ -1687,8 +1671,8 @@ Cohesion: 0.28
Nodes (4): SubscriptionService, ClinicSubscription, Payment, SubscriptionPlan
### Community 245 - "Community 245"
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 246 - "Community 246"
Cohesion: 0.17
@@ -1799,12 +1783,12 @@ 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.15
Cohesion: 0.16
Nodes (5): Authentication, ClinicPro — API Documentation Index, Error Code Reference, Modules, Standard Response Envelope
### Community 275 - "Community 275"
Cohesion: 0.15
Nodes (6): MellatGatewayTest, CorsRegexEnvProcessorTest, ErrorCodesTest, KavehNegarProviderTest, TestCase, KavehNegarProvider
Cohesion: 0.19
Nodes (5): MellatGatewayTest, ErrorCodesTest, KavehNegarProviderTest, TestCase, KavehNegarProvider
### Community 276 - "Community 276"
Cohesion: 0.20
@@ -1875,12 +1859,12 @@ Cohesion: 0.20
Nodes (9): AdminApiController — dashboardCharts با بازه زمانی, DashboardController — اضافه کردن from/to, date range selector component:, تغییر Backend, تغییر Frontend — DashboardPage.tsx, فایل‌هایی که تغییر می‌کنند, معماری — تسک ۱۶: داشبورد هوشمند, نصب dependency: (+1 more)
### Community 294 - "Community 294"
Cohesion: 0.30
Nodes (6): AbstractAuthenticator, Passport, PasswordAuthenticator, Request, Response, TokenInterface
Cohesion: 0.25
Nodes (8): AbstractAuthenticator, AuthenticationException, Passport, RateLimiterFactory, PasswordAuthenticator, Request, Response, TokenInterface
### Community 295 - "Community 295"
Cohesion: 0.29
Nodes (5): AbstractController, AdminController, HomeController, Response, Response
Cohesion: 0.20
Nodes (8): AbstractController, AdminController, HomeController, SeoController, Response, Response, Request, Response
### Community 296 - "Community 296"
Cohesion: 0.22
@@ -1899,12 +1883,12 @@ Cohesion: 0.22
Nodes (9): require-dev, phpstan/phpstan, phpstan/phpstan-doctrine, phpstan/phpstan-symfony, phpunit/phpunit, symfony/browser-kit, symfony/css-selector, symfony/debug-bundle (+1 more)
### Community 300 - "Community 300"
Cohesion: 0.42
Nodes (3): PreRegistrationController, JsonResponse, Request
Cohesion: 0.19
Nodes (6): HealthController, PreRegistrationController, EntityManagerInterface, JsonResponse, Request, JsonResponse
### Community 301 - "Community 301"
Cohesion: 0.05
Nodes (48): ApiResponse, PaginatedResponse, iranMobileSchema, STATUS_FILTERS, AddForm, addSchema, HUES_LIST, FILTERS (+40 more)
Cohesion: 0.07
Nodes (29): ApiResponse, PaginatedResponse, STATUS_FILTERS, FILTERS, Breakdown, SOURCE_LABEL, Summary, LEVEL_FILTER_OPTIONS (+21 more)
### Community 302 - "Community 302"
Cohesion: 0.12
@@ -1915,8 +1899,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 🆕, 36. 🟢 `GET` get my rate, 6. کلینیک (Clinic), هدرهای اضافی, پارامترهای Query, پاسخ‌ها, پاسخ‌ها (+1 more)
Cohesion: 0.04
Nodes (47): 29. 🟢 `GET` clinic list 🆕, 30. 🟢 `GET` get 🆕, 32. 🔵 `POST` post, 33. 🔵 `POST` image_clinic, 34. 🔵 `POST` image logo, 35. 🟡 `PATCH` patch, 36. 🟢 `GET` get my rate, 38. 🟢 `GET` Unapproved comments (+39 more)
### Community 306 - "Community 306"
Cohesion: 0.07
@@ -1927,8 +1911,8 @@ Cohesion: 0.28
Nodes (3): UserActiveContext, self, User
### Community 308 - "Community 308"
Cohesion: 0.17
Nodes (7): HealthController, SiteConfigController, EntityManagerInterface, JsonResponse, Request, User, JsonResponse
Cohesion: 0.36
Nodes (4): SiteConfigController, JsonResponse, Request, User
### Community 309 - "Community 309"
Cohesion: 0.22
@@ -1963,8 +1947,8 @@ Cohesion: 0.31
Nodes (3): SubscriptionPlanRepository, ManagerRegistry, SubscriptionPlan
### Community 318 - "Community 318"
Cohesion: 0.22
Nodes (5): AuthController, RateLimiterFactory, JsonResponse, Request, User
Cohesion: 0.21
Nodes (5): ErrorCodes, AuthController, JsonResponse, Request, User
### Community 319 - "Community 319"
Cohesion: 0.39
@@ -2015,8 +1999,8 @@ Cohesion: 0.22
Nodes (8): Query های جدید, بیماران منحصربه‌فرد در بازه, درآمد بر اساس روز (از patient_sessions), فروش اشتراک بر اساس پنل (admin), نوبت‌ها بر اساس روز (admin chart), نکات مهم, هیچ migration لازم نیست, پایگاه داده — تسک ۱۶: داشبورد هوشمند
### Community 333 - "Community 333"
Cohesion: 0.05
Nodes (39): DELETE `/api/v1/clinic-pro/doctor-address/{id}`, DELETE `/api/v1/doctor/{uuid}`, Doctor API, Errors, Errors, Errors, Errors, Errors (+31 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
@@ -2143,8 +2127,8 @@ Cohesion: 0.25
Nodes (7): ادمین, دکتر نمونه کامل — تبریز, دکتران bulk (۱۵۰۰ دکتر در ۱۵ شهر), ساخت مجدد, منشی دکتر نمونه, کاربران تستی, کلینیک نمونه — تبریز
### Community 367 - "Community 367"
Cohesion: 0.15
Nodes (7): Altcha, AltchaService, altcha, Altcha(), AltchaProps, FA_STRINGS, IntrinsicElements
Cohesion: 0.24
Nodes (3): Altcha, AltchaService, altcha
### Community 368 - "Community 368"
Cohesion: 0.36
@@ -2191,8 +2175,8 @@ Cohesion: 0.29
Nodes (7): بک‌اند — endpoint جدید: `GET /api/v1/my/appointments` `[IS_AUTHENTICATED_FULLY]`, فرانت‌اند — `AppointmentsPage.tsx`, مرحله ۸ — نوبت‌های فیلترشده (بک‌اند + فرانت‌اند) — API جدید, نمای جدولی (`TableView`):, نمای زمانبندی (`TimelineView`):, هدر صفحه (مشترک هر دو نما):, وضعیت‌های نوبت (باید در entity و frontend هر دو باشند):
### Community 380 - "Community 380"
Cohesion: 0.31
Nodes (6): ErrorCodes, ClinicServiceController, JsonResponse, Request, ServiceSection, User
Cohesion: 0.36
Nodes (5): ClinicServiceController, JsonResponse, Request, ServiceSection, User
### Community 381 - "Community 381"
Cohesion: 0.13
@@ -2255,8 +2239,8 @@ Cohesion: 0.33
Nodes (6): Refactoring Plan, فاز ۰ — مستندسازی (۳ تا ۵ روز، قبل از هر کدنویسی), فاز ۱ — زیرساخت پایه (task-01), فاز ۲ — پیاده‌سازی ماژول‌ها (به ترتیب dependency), فاز ۳ — بهینه‌سازی (بعد از پیاده‌سازی), فاز ۴ — آماده‌سازی تولید
### Community 397 - "Community 397"
Cohesion: 0.21
Nodes (6): ClaimAmountBoundsTest, ClaimsListNPlusOneTest, ClaimItem, Claim, Doctor, User
Cohesion: 0.36
Nodes (4): ClaimAmountBoundsTest, Claim, Doctor, User
### Community 398 - "Community 398"
Cohesion: 0.22
@@ -2264,7 +2248,7 @@ Nodes (7): initiate(), refund(), reverse(), verify(), PaymentInitResult, Payment
### Community 399 - "Community 399"
Cohesion: 0.23
Nodes (5): AbstractMigration, Schema, Version20260609130407, Schema, Version20260629161536
Nodes (5): AbstractMigration, Schema, Version20260609130407, Schema, Version20260628165710
### Community 401 - "Community 401"
Cohesion: 0.12
@@ -2275,8 +2259,12 @@ Cohesion: 0.11
Nodes (17): بازطراحی معماری پرداخت — سرویس‌محور، امن، توسعه‌پذیر (Backend), تست دستی (ddev، در حالت `payment_test_mode=1`), خروجی نهایی (طبق spec — در گزارش اجرا ارائه شود), زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی (+9 more)
### Community 407 - "Community 407"
Cohesion: 0.16
Nodes (9): MessageBusInterface, MockObject, SmsTextResolver, SmsServiceLookupOnlyTest, SmsLogRepository, SmsMessageTemplateRepository, SmsService, SmsTextResolver (+1 more)
Cohesion: 0.27
Nodes (8): MessageBusInterface, MockObject, SmsServiceLookupOnlyTest, SmsLogRepository, SmsMessageTemplateRepository, SmsService, SmsTextResolver, KavehNegarProvider
### Community 414 - "Community 414"
Cohesion: 0.07
Nodes (18): ClinicAddress, ClinicDoctorItem, ClinicInvitation, EditForm, editSchema, HUES_LIST, INV_STATUS_MAP, IRAN_CENTER (+10 more)
### Community 418 - "Community 418"
Cohesion: 0.17
@@ -2299,20 +2287,16 @@ Cohesion: 0.35
Nodes (5): PatientController, JsonResponse, PatientSession, Request, User
### Community 435 - "Community 435"
Cohesion: 0.43
Nodes (3): InvoiceRepository, Invoice, ManagerRegistry
### Community 439 - "Community 439"
Cohesion: 0.33
Nodes (4): BlogController, JsonResponse, Request, User
Cohesion: 0.21
Nodes (4): SepGateway, PaymentInitResult, PaymentRefundResult, PaymentVerifyResult
### Community 440 - "Community 440"
Cohesion: 0.11
Nodes (18): [F10] راهنمای کهنه در `CLAUDE.md`: endpoint `categorys/{bundle}` منتقل شده, [F11] داشبورد دکتر `GET /api/v1/dashboard/doctor` همیشه 500 (فیلد ناموجود در DQL) — ✅ رفع شد, [F1] phpstan: مقایسهٔ همیشه‌درست در محاسبهٔ estimated SMS — ✅ رفع شد, [F2] تست‌های PHPUnit به API خارجی Kavenegar درخواست واقعی می‌زنند, [F3] دیتابیس تست seed نشده — فقط کاربر ادمین وجود دارد, [F4] اسکریپت seeder `create_test_users.php` وجود ندارد, [F5] ادمین با JWT معتبر به `/api/doc` (Swagger UI) دسترسی ندارد (401), [F6] ناسازگاری کدهای خطا بین دامنه‌ها (+10 more)
### Community 451 - "Community 451"
Cohesion: 0.20
Nodes (8): AdminUser, ChangeRoleModal(), getPrimaryRole(), HUES_LIST, ROLE_META, ROLE_TABS, RoleBadge(), UserStats
Cohesion: 0.09
Nodes (19): AddForm, addSchema, ClinicsPage(), HUES_LIST, EMPTY, PreRegistration, STATUS_META, STATUS_TABS (+11 more)
### Community 452 - "Community 452"
Cohesion: 0.33
@@ -2415,8 +2399,8 @@ 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 483 - "Community 483"
Cohesion: 0.57
Nodes (3): SeoController, Request, Response
Cohesion: 0.18
Nodes (5): MockGateway, PaymentGatewayInterface, PaymentInitResult, PaymentRefundResult, PaymentVerifyResult
### Community 486 - "Community 486"
Cohesion: 0.40
@@ -2438,10 +2422,6 @@ Nodes (15): `Modal.tsx` (بدون Portal), `PersianCalendar.tsx` (buttonها ب
Cohesion: 0.20
Nodes (9): Backend Audit Backlog — ClinicPro, ☐ CRITICAL, ✅ DONE (committed on backend-audit), ☐ EPICS (design debt — cross-repo, defer; do NOT quick-fix), ☐ HIGH, ☐ LOW, ☐ MEDIUM, Progress (this audit session) (+1 more)
### Community 494 - "Community 494"
Cohesion: 0.50
Nodes (4): Error Codes, POST `/api/v1/user/reset-password`, Request Body, Response `200`
### Community 495 - "Community 495"
Cohesion: 0.12
Nodes (15): CORS — `config/packages/nelmio_cors.yaml`, MellatGateway — تشخیص فعال‌بودن, payment/config — `PaymentController::config()` (خط ۵۴۶), resolveGateway + callback (کد واقعی), رفع باگ‌های پروداکشن: CORS + payment/config 500 + درگاه‌های فعال و callback ملت, زمینه, فایل‌های مرتبط, فرانت — `SubscriptionPage.tsx` (+7 more)
@@ -2538,6 +2518,10 @@ Nodes (4): مجوزها در سیستم, مجوزهای منشی, نقش کار
Cohesion: 0.40
Nodes (4): ساختار فایل‌ها, معماری — تسک ۱۶: ماژول داشبورد دکتر, نمودار جریان, کوئری درآمد سالانه (بر اساس ماه‌های شمسی)
### Community 522 - "Community 522"
Cohesion: 0.33
Nodes (5): Like, LikeRepository, Comment, ManagerRegistry, User
### Community 523 - "Community 523"
Cohesion: 0.15
Nodes (12): افزودن اسم سایت شهر به پیامک کد تأیید (OTP) — به‌صورت اختیاری, زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی, وظایف, پروژه (+4 more)
@@ -2556,7 +2540,7 @@ Nodes (4): GET /api/v1/appointment-settings/slots — دریافت اسلات‌
### Community 527 - "Community 527"
Cohesion: 0.13
Nodes (5): LoggerInterface, RanginehProvider, SmsService, SendSmsMessage, SmsProviderInterface
Nodes (5): RepositoryClassMappingTest, KernelTestCase, LoggerInterface, RanginehProvider, DbLoggerTest
### Community 528 - "Community 528"
Cohesion: 0.50
@@ -2567,16 +2551,16 @@ Cohesion: 0.50
Nodes (4): Errors, POST `/oauth/token/refresh`, Request Body, Response `200`
### Community 530 - "Community 530"
Cohesion: 0.40
Nodes (5): Errors, Notes, POST `/api/v1/notification-mobile/request-otp`, Request Body, Response `200`
Cohesion: 0.33
Nodes (3): GatewayFactory, MellatGateway, SepGateway
### Community 531 - "Community 531"
Cohesion: 0.50
Nodes (4): ۲.۱۳ نظرات، لایک و امتیازدهی, ۲.۱۳.۱ نظر (Comment), ۲.۱۳.۲ لایک (Like), ۲.۱۳.۳ امتیاز (Rate)
### Community 532 - "Community 532"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/notification-mobile/verify`, Request Body, Response `200`
Cohesion: 0.33
Nodes (4): PatientService, Appointment, PatientRecord, PatientSession
### Community 533 - "Community 533"
Cohesion: 0.19
@@ -2603,8 +2587,8 @@ Cohesion: 0.48
Nodes (3): DoctorInsuranceRepository, DoctorInsurance, ManagerRegistry
### Community 543 - "Community 543"
Cohesion: 0.40
Nodes (5): 32. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
Cohesion: 0.47
Nodes (3): CommissionService, Payment, Representation
### Community 544 - "Community 544"
Cohesion: 0.15
@@ -2639,8 +2623,8 @@ Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/representation/appointments`, Query Parameters, Response `200`
### Community 552 - "Community 552"
Cohesion: 0.67
Nodes (3): 33. 🔵 `POST` image_clinic, هدرهای اضافی, پاسخ‌ها
Cohesion: 0.32
Nodes (3): SmsService, SendSmsMessage, SmsProviderInterface
### Community 553 - "Community 553"
Cohesion: 0.50
@@ -2667,8 +2651,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.22
Nodes (6): SmsMessageController, SmsMessageTemplateRepository, SmsMessageTemplate, JsonResponse, Request, ManagerRegistry
Cohesion: 0.25
Nodes (4): SmsMessageTemplateRepository, SmsTextResolver, SmsMessageTemplate, ManagerRegistry
### Community 560 - "Community 560"
Cohesion: 0.50
@@ -2707,8 +2691,8 @@ Cohesion: 0.12
Nodes (15): دیپلوی ClinicPro (Symfony) روی لیارا با Docker, زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی (کد واقعی), وظایف, پروژه (+7 more)
### Community 577 - "Community 577"
Cohesion: 0.38
Nodes (5): Rate, RateRepository, Doctor, ManagerRegistry, User
Cohesion: 0.43
Nodes (3): SmsMessageController, JsonResponse, Request
### Community 581 - "Community 581"
Cohesion: 0.50
@@ -2747,16 +2731,12 @@ Cohesion: 0.50
Nodes (3): Entity: Payment, ساختار فایل‌ها, معماری — تسک ۱۵: ماژول پرداخت
### Community 595 - "Community 595"
Cohesion: 0.53
Cohesion: 0.43
Nodes (3): SmsLogRepository, SmsLog, ManagerRegistry
### Community 596 - "Community 596"
Cohesion: 0.40
Nodes (5): 35. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 597 - "Community 597"
Cohesion: 0.20
Nodes (10): Configuration, Errors, GET `/api/v1/admin/sms/templates`, GET `/api/v1/sms/template/{uuid}`, POST `/api/v1/admin/sms/template/{uuid}/approve`, Request Body (`application/json`), Response `200`, Response `200` (+2 more)
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
### Community 599 - "Community 599"
Cohesion: 0.67
@@ -2782,10 +2762,22 @@ Nodes (5): RepresentationController, JsonResponse, Representation, Request, User
Cohesion: 0.67
Nodes (3): بک‌اند, فرانت‌اند, وضعیت فعلی کد (مهم — قبل از تغییر بخوان)
### Community 618 - "Community 618"
Cohesion: 0.16
Nodes (5): ServiceItemDeleteCleanupTest, ServiceCoverageNPlusOneTest, TenantServiceCoverageRepository, ManagerRegistry, TenantServiceCoverage
### Community 625 - "Community 625"
Cohesion: 0.40
Nodes (5): 31. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 626 - "Community 626"
Cohesion: 0.43
Nodes (3): InvoiceService, Invoice, PatientSession
### Community 631 - "Community 631"
Cohesion: 0.53
Nodes (4): ClaimSubmitterInterface, ManualClaimSubmitter, Claim, ClaimSubmissionResult
### Community 633 - "Community 633"
Cohesion: 0.40
Nodes (5): Errors, GET `/api/v1/clinic/my-doctor/{doctorUuid}`, Path Parameters, Response `200`, Schedule Fields Notes
@@ -2799,8 +2791,8 @@ Cohesion: 0.12
Nodes (16): Runbook — تشخیص «ری‌استارت» سرور: recycle عادی یا خرابی واقعی؟, اقدامات تکمیلی روی سرور (خارج از repo), تأیید روی سرور — اسکریپت آماده, جدول تفسیر خروجی اسکریپت, خلاصه یک‌خطی, علامت مشکل, چرا این اتفاق می‌افتاد (و فیکس اعمال‌شده), چک‌لیست رفع (+8 more)
### Community 640 - "Community 640"
Cohesion: 0.43
Nodes (3): InvoiceItemRepository, InvoiceItem, ManagerRegistry
Cohesion: 0.53
Nodes (4): Money, BillingCalculator, CoverageRule, ShareBreakdown
### Community 641 - "Community 641"
Cohesion: 0.39
@@ -2842,18 +2834,26 @@ Nodes (8): Captcha API (ALTCHA), GET `/api/v1/altcha/challenge`, GET `/api/v1/al
Cohesion: 0.20
Nodes (10): Errors (payment refund/reverse/detail), GET `/api/v1/admin/payments`, GET `/api/v1/admin/payments/{uuid}`, Payment Management, POST `/api/v1/admin/payments/{uuid}/refund`, POST `/api/v1/admin/payments/{uuid}/reverse`, Query Parameters, Query Parameters (تکمیل) (+2 more)
### Community 658 - "Community 658"
Cohesion: 0.47
Nodes (6): formatPersianDate(), gToJ(), jFirstDayOfWeek(), PersianDateInput(), todayGregorian(), toPersianNums()
### Community 659 - "Community 659"
Cohesion: 0.31
Nodes (4): ClinicInvitationService, Clinic, ClinicDoctorInvitation, User
### Community 661 - "Community 661"
Cohesion: 0.43
Nodes (5): BeforeInstallPromptEvent, usePwaInstall(), PwaInstallBanner(), detectIOS(), PwaLoginCard()
Cohesion: 0.53
Nodes (3): SessionServiceRepository, ManagerRegistry, SessionService
### Community 662 - "Community 662"
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 671 - "Community 671"
Cohesion: 0.40
Nodes (5): Errors, PATCH `/api/v1/doctor/{uuid}`, Path Parameters, Request Body (`application/json`), Response `200`
### Community 672 - "Community 672"
Cohesion: 0.17
Nodes (11): تشخیص «ری‌استارت» سرور روی Coolify + رفع نویز لاگ + بررسی خطای ACME, زمینه, فایل‌های مرتبط, نکات مهم, وضعیت فعلی, وظایف, پروژه, ۱. کاهش نویز لاگ workerها (بدون تغییر رفتار) (+3 more)
@@ -2862,6 +2862,10 @@ Nodes (11): تشخیص «ری‌استارت» سرور روی Coolify + رفع
Cohesion: 0.50
Nodes (4): GET `/api/v1/admin/secretaries`, Query Parameters, Response `200`, Secretary Management
### Community 676 - "Community 676"
Cohesion: 0.40
Nodes (5): addMinutes(), calcSlotCount(), hasOverlap(), parseMinutes(), SessionEditor()
### Community 677 - "Community 677"
Cohesion: 0.40
Nodes (5): 37. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
@@ -2875,8 +2879,8 @@ Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/auth/switch-context`, Request Body, Response `200`
### Community 684 - "Community 684"
Cohesion: 0.50
Nodes (4): Error Codes, POST `/api/v1/user/otp-login`, Request Body, Response `200`
Cohesion: 0.40
Nodes (4): Altcha(), AltchaProps, FA_STRINGS, IntrinsicElements
### Community 686 - "Community 686"
Cohesion: 0.40
@@ -2884,19 +2888,23 @@ Nodes (5): GET `/api/v1/admin/comments`, GET `/api/v1/admin/rates`, Query Parame
### Community 687 - "Community 687"
Cohesion: 0.50
Nodes (4): Errors, PATCH `/api/v1/admin/insurance/{id}`, Path Parameters, Response `200`
Nodes (4): DELETE `/api/v1/doctor/{uuid}`, Errors, Path Parameters, Response `200`
### Community 689 - "Community 689"
Cohesion: 0.40
Nodes (5): 41. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 690 - "Community 690"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/doctor`, Request Body (`application/json`), Response `201`
### Community 692 - "Community 692"
Cohesion: 0.50
Nodes (4): GET `/api/v1/admin/representations`, Query Parameters, Representation Management, Response `200`
### Community 693 - "Community 693"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/user/send-code`, Request Body, Response `200`
Nodes (4): Errors, GET `/api/v1/doctor/{uuid}`, Path Parameters, Response `200`
### Community 694 - "Community 694"
Cohesion: 0.50
@@ -2914,29 +2922,33 @@ Nodes (3): Errors, POST `/api/v1/sms/send` — ⛔ غیرفعال (Deprecated),
Cohesion: 0.17
Nodes (11): رفع خطاهای ارسال پیامک کاوه‌نگار در سرور prod (431 + Idle timeout), زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی, وظایف, پروژه (+3 more)
### Community 700 - "Community 700"
Cohesion: 0.50
Nodes (4): Errors, POST `/file/upload/clinic_pro/doctor/field_image`, Request, Response `200`
### Community 701 - "Community 701"
Cohesion: 0.17
Nodes (11): رفع خطای `Class "SoapClient" not found` در پرداخت ملت (سرور prod), زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی, وظایف, پروژه (+3 more)
### Community 705 - "Community 705"
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 (فاز ۱ سیستم صورتحساب)
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/clinic-pro/doctor-address`, Request Body, Response `201`
### Community 706 - "Community 706"
Cohesion: 0.50
Nodes (4): Errors, Path Parameters, POST `/api/v1/clinic-pro/doctor-address/from-clinic/{clinicUuid}`, Response `201`
### Community 707 - "Community 707"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/user/register`, Request Body, Response `201`
### Community 708 - "Community 708"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/user/login`, Request Body, Response `200`
### Community 710 - "Community 710"
Cohesion: 0.67
Nodes (3): GET `/api/v1/representation/{uuid}/dashboard/yearly`, Query Parameters, Response `200`
### Community 712 - "Community 712"
Cohesion: 0.50
Nodes (4): Errors, POST `/oauth/token`, Request Body, Response `200`
Cohesion: 0.67
Nodes (3): GET `/api/v1/clinic-pro/doctor-addresses/{doctorId}`, Path Parameters, Response `200`
### Community 713 - "Community 713"
Cohesion: 0.50
@@ -2946,105 +2958,37 @@ Nodes (4): 39. 🟡 `PATCH` Comment confirmation, مثال Request, هدرهای
Cohesion: 0.50
Nodes (4): 45. 🔵 `POST` post, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 715 - "Community 715"
Cohesion: 0.67
Nodes (3): POST `/api/v1/admin/sms/template/{uuid}/approve`, Request Body (`application/json`), Response `200`
### Community 716 - "Community 716"
Cohesion: 0.50
Nodes (4): Errors, GET `/oauth/userinfo`, Headers, Response `200`
### Community 717 - "Community 717"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/user/verify-code`, Request Body, Response `200`
### Community 718 - "Community 718"
Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/admin/insurances`, Query Parameters, Response `200`
### Community 719 - "Community 719"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/admin/insurance`, Request Body (`application/json`), Response `201`
### Community 720 - "Community 720"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/insurance/`, Request Body (`application/json`), Response `201`
### Community 721 - "Community 721"
Cohesion: 0.50
Nodes (4): Errors, PATCH `/api/v1/insurance/{id}`, Request Body, Response `200`
### Community 723 - "Community 723"
Cohesion: 0.50
Nodes (4): PUT `/api/v1/insurance-pricing`, Request Body, Response `200`, خطاها
### Community 724 - "Community 724"
Cohesion: 0.50
Nodes (4): 38. 🟢 `GET` Unapproved comments, هدرهای اضافی, پارامترهای Query, پاسخ‌ها
### Community 725 - "Community 725"
Cohesion: 0.50
Nodes (4): 40. 🔵 `POST` post, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 726 - "Community 726"
Cohesion: 0.50
Nodes (4): 44. 🟢 `GET` list comment, هدرهای اضافی, پارامترهای Query, پاسخ‌ها
### Community 728 - "Community 728"
Cohesion: 0.50
Nodes (4): 46. 🟡 `PATCH` patch, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 730 - "Community 730"
Cohesion: 0.67
Nodes (3): Errors, GET `/api/v1/notification-mobile/{target}`, Response `200`
### Community 731 - "Community 731"
Cohesion: 0.67
Nodes (3): 34. 🔵 `POST` image logo, هدرهای اضافی, پاسخ‌ها
### Community 733 - "Community 733"
Cohesion: 0.67
Nodes (3): 42. 🔴 `DELETE` delete, هدرهای اضافی, پاسخ‌ها
### Community 734 - "Community 734"
Cohesion: 0.67
Nodes (3): GET `/api/v1/billing/tenant-insurances/{uuid}/service-coverage`, PUT `/api/v1/billing/tenant-insurances/{uuid}/service-coverage`, TenantServiceCoverage — پوشش خدمت تحت یک قرارداد بیمه (فاز ۲)
### Community 735 - "Community 735"
Cohesion: 0.67
Nodes (3): GET `/api/v1/insurance-pricing`, Response `200`, خطاها
### Community 736 - "Community 736"
Cohesion: 0.67
Nodes (3): GET `/api/v1/insurances`, Query Parameters, Response `200`
### Community 737 - "Community 737"
Cohesion: 0.67
Nodes (3): POST `/api/v1/admin/insurance/{id}/upload-logo`, Request, Response `200`
### Community 738 - "Community 738"
Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/representation/{uuid}`, Path Parameters, Response `200`
### Community 739 - "Community 739"
Cohesion: 0.67
Nodes (3): 43. 🟢 `GET` get, هدرهای اضافی, پاسخ‌ها
## Knowledge Gaps
- **4032 isolated node(s):** `ALLOWED_ROLES`, `Pricing`, `ImageCropModalProps`, `TenantInsurance`, `CoverageRow` (+4027 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **146 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **150 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 `Altcha` connect `Community 367` to `Community 485`?**
- **Why does `Altcha` connect `Community 367` to `Community 684`, `Community 485`?**
_High betweenness centrality (0.068) - this node is a cross-community bridge._
- **Why does `BaseController` connect `Community 108` to `Community 4`, `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 308`, `Community 439`, `Community 59`, `Community 318`, `Community 64`, `Community 75`, `Community 77`, `Community 82`, `Community 607`, `Community 480`, `Community 230`, `Community 104`, `Community 107`, `Community 109`, `Community 380`, `Community 121`, `Community 122`, `Community 252`?**
_High betweenness centrality (0.043) - this node is a cross-community bridge._
- **Why does `Version20260705070546` connect `Community 646` to `Community 399`?**
_High betweenness centrality (0.023) - this node is a cross-community bridge._
- **Why does `BaseController` connect `Community 108` to `Community 6`, `Community 7`, `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 577`, `Community 75`, `Community 77`, `Community 607`, `Community 480`, `Community 230`, `Community 104`, `Community 107`, `Community 109`, `Community 380`, `Community 121`, `Community 122`, `Community 252`?**
_High betweenness centrality (0.042) - this node is a cross-community bridge._
- **Why does `MellatGateway` connect `Community 206` to `Community 16`, `Community 483`, `Community 20`, `Community 527`?**
_High betweenness centrality (0.024) - this node is a cross-community bridge._
- **What connects `ALLOWED_ROLES`, `Pricing`, `ImageCropModalProps` to the rest of the system?**
_4032 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `Community 0` be split into smaller, more focused modules?**
_Cohesion score 0.05725490196078432 - 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.028481012658227847 - nodes in this community are weakly interconnected._
_Cohesion score 0.028985507246376812 - nodes in this community are weakly interconnected._
- **Should `Community 2` be split into smaller, more focused modules?**
_Cohesion score 0.09523809523809523 - nodes in this community are weakly interconnected._
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
@@ -0,0 +1 @@
{"nodes": [{"id": "users_hamed_pj_my_pj_clinic_pro_clinicpro_docs_api_captcha_md", "label": "captcha.md", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L1"}, {"id": "api_captcha_captcha_api_altcha", "label": "Captcha API (ALTCHA)", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L1"}, {"id": "api_captcha_get_api_v1_altcha_challenge", "label": "GET `/api/v1/altcha/challenge`", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L13"}, {"id": "api_captcha_response_200", "label": "Response `200`", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L17"}, {"id": "api_captcha_get_api_v1_altcha_config", "label": "GET `/api/v1/altcha/config`", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L34"}, {"id": "api_captcha_response_200_38", "label": "Response `200`", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L38"}, {"id": "api_captcha_\u0627\u0639\u0645\u0627\u0644_\u06a9\u067e\u0686\u0627_\u0631\u0648\u06cc_endpoint\u0647\u0627\u06cc_\u0645\u062d\u0627\u0641\u0638\u062a_\u0634\u062f\u0647", "label": "\u0627\u0639\u0645\u0627\u0644 \u06a9\u067e\u0686\u0627 \u0631\u0648\u06cc endpoint\u0647\u0627\u06cc \u0645\u062d\u0627\u0641\u0638\u062a\u200c\u0634\u062f\u0647", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L45"}, {"id": "api_captcha_\u062e\u0637\u0627\u06cc_\u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc_\u06a9\u067e\u0686\u0627_422", "label": "\u062e\u0637\u0627\u06cc \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc \u06a9\u067e\u0686\u0627 `422`", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L68"}, {"id": "api_captcha_\u0627\u0645\u0646\u06cc\u062a", "label": "\u0627\u0645\u0646\u06cc\u062a", "file_type": "document", "source_file": "docs/api/captcha.md", "source_location": "L81"}], "edges": [{"source": "users_hamed_pj_my_pj_clinic_pro_clinicpro_docs_api_captcha_md", "target": "api_captcha_captcha_api_altcha", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L1", "weight": 1.0}, {"source": "api_captcha_captcha_api_altcha", "target": "api_captcha_get_api_v1_altcha_challenge", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L13", "weight": 1.0}, {"source": "api_captcha_get_api_v1_altcha_challenge", "target": "api_captcha_response_200", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L17", "weight": 1.0}, {"source": "api_captcha_captcha_api_altcha", "target": "api_captcha_get_api_v1_altcha_config", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L34", "weight": 1.0}, {"source": "api_captcha_get_api_v1_altcha_config", "target": "api_captcha_response_200_38", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L38", "weight": 1.0}, {"source": "api_captcha_captcha_api_altcha", "target": "api_captcha_\u0627\u0639\u0645\u0627\u0644_\u06a9\u067e\u0686\u0627_\u0631\u0648\u06cc_endpoint\u0647\u0627\u06cc_\u0645\u062d\u0627\u0641\u0638\u062a_\u0634\u062f\u0647", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L45", "weight": 1.0}, {"source": "api_captcha_\u0627\u0639\u0645\u0627\u0644_\u06a9\u067e\u0686\u0627_\u0631\u0648\u06cc_endpoint\u0647\u0627\u06cc_\u0645\u062d\u0627\u0641\u0638\u062a_\u0634\u062f\u0647", "target": "api_captcha_\u062e\u0637\u0627\u06cc_\u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc_\u06a9\u067e\u0686\u0627_422", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L68", "weight": 1.0}, {"source": "api_captcha_captcha_api_altcha", "target": "api_captcha_\u0627\u0645\u0646\u06cc\u062a", "relation": "contains", "confidence": "EXTRACTED", "source_file": "docs/api/captcha.md", "source_location": "L81", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0}
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
+787 -746
View File
File diff suppressed because it is too large Load Diff
+16 -16
View File
@@ -345,8 +345,8 @@
"semantic_hash": ""
},
"assets/admin/pages/SettingsPage.tsx": {
"mtime": 1783060574.3517244,
"ast_hash": "342ffb05150e7e73101ab5c0b4581113",
"mtime": 1783670960.5889294,
"ast_hash": "d41b1ec43ab746564041dce8523f9693",
"semantic_hash": ""
},
"assets/admin/pages/SettlementDetailPage.tsx": {
@@ -1150,8 +1150,8 @@
"semantic_hash": ""
},
"src/Config/Controller/SiteConfigController.php": {
"mtime": 1783010796.4351387,
"ast_hash": "e4424874defd966d41c4445dbd629806",
"mtime": 1783670899.2864327,
"ast_hash": "5bdc87f76d539d1e91c1d67b1d17346b",
"semantic_hash": ""
},
"src/Config/Entity/SiteConfig.php": {
@@ -2300,8 +2300,8 @@
"semantic_hash": ""
},
"config/services.yaml": {
"mtime": 1783666096.987689,
"ast_hash": "92837e221e0914e026f4f79e8e8ee0b6",
"mtime": 1783670869.0603309,
"ast_hash": "4446e5510d383465e1d3b4bbaaf5eb8c",
"semantic_hash": ""
},
"docs/Architecture_Audit.md": {
@@ -2340,8 +2340,8 @@
"semantic_hash": ""
},
"docs/api/admin.md": {
"mtime": 1783663961.4046154,
"ast_hash": "0ecb4de166b81cb69125d9c6b59f8d16",
"mtime": 1783671102.5622253,
"ast_hash": "878c59042b8a5873afa8346b07830a35",
"semantic_hash": ""
},
"docs/api/appointment-settings.md": {
@@ -3245,8 +3245,8 @@
"semantic_hash": ""
},
"docker-compose.yml": {
"mtime": 1783669013.1104357,
"ast_hash": "d2b26d468f967197b376295721bcb435",
"mtime": 1783669690.2173707,
"ast_hash": "8ecc13cd82c69bd23b797d1d7bffaded",
"semantic_hash": ""
},
"docs/DEPLOY.md": {
@@ -3810,8 +3810,8 @@
"semantic_hash": ""
},
"src/Shared/Captcha/AltchaService.php": {
"mtime": 1783666097.1130326,
"ast_hash": "432b4dd0304710632ba86b243e530a5b",
"mtime": 1783670847.5803795,
"ast_hash": "452ec5eece56475fc08269b033cd2c5d",
"semantic_hash": ""
},
"src/Shared/Captcha/CaptchaController.php": {
@@ -3825,8 +3825,8 @@
"semantic_hash": ""
},
"tests/Shared/Captcha/AltchaServiceTest.php": {
"mtime": 1783666097.1154962,
"ast_hash": "f6a6ca5f5ccaa6fb6cbf811f1e91dc0b",
"mtime": 1783670997.8952963,
"ast_hash": "a8ca01d08b01445fce7923510253dfe1",
"semantic_hash": ""
},
"tests/Shared/Captcha/CaptchaFlowTest.php": {
@@ -3840,8 +3840,8 @@
"semantic_hash": ""
},
"docs/api/captcha.md": {
"mtime": 1783669288.2668343,
"ast_hash": "56e9b036792f8b79aafd0f60dbd546e9",
"mtime": 1783671083.4752364,
"ast_hash": "92b8fc394a330b77058d252b26eb85e5",
"semantic_hash": ""
}
}
@@ -30,6 +30,8 @@ class SiteConfigController extends BaseController
'max_cancel_hours_before',
'appointment_reminder_hours',
'log_retention_days',
// captcha
'altcha_enabled',
// payment gateways
'payment_test_mode',
'payment_allowed_frontend_hosts',
@@ -47,6 +49,7 @@ class SiteConfigController extends BaseController
private readonly SiteConfigRepository $configRepo,
private readonly \App\Config\Repository\TaxRateHistoryRepository $taxHistoryRepo,
private readonly EntityManagerInterface $em,
private readonly \App\Shared\Captcha\AltchaService $altcha,
) {}
#[Route('/api/v1/admin/settings', methods: ['GET'])]
@@ -55,6 +58,8 @@ class SiteConfigController extends BaseController
$config = $this->configRepo->getAll();
// کلید API پیامک فقط از env؛ فقط وضعیت تنظیم‌بودن برگردانده می‌شود نه مقدار.
$config['sms_api_key_configured'] = ($_ENV['KAVENEGAR_API_KEY'] ?? '') !== '';
// مقدار مؤثر کپچا (override پنل اگر ست شده، وگرنه env) تا toggle درست نمایش دهد.
$config['altcha_enabled'] = $this->altcha->enabled() ? '1' : '0';
return $this->success($config);
}
+12 -2
View File
@@ -4,6 +4,7 @@ namespace App\Shared\Captcha;
use AltchaOrg\Altcha\V1\Altcha;
use AltchaOrg\Altcha\V1\ChallengeOptions;
use App\Config\Repository\SiteConfigRepository;
use Psr\Cache\CacheItemPoolInterface;
/**
@@ -20,17 +21,26 @@ class AltchaService
public function __construct(
private readonly string $hmacKey,
private readonly bool $enabled,
private readonly bool $envEnabled,
private readonly int $maxNumber,
private readonly int $expireSeconds,
private readonly CacheItemPoolInterface $altchaPool,
private readonly SiteConfigRepository $configRepo,
) {
$this->altcha = new Altcha($this->hmacKey);
}
/**
* فعال بودن کپچا: override پنل ادمین (site_config) مقدم است؛ اگر ست نشده باشد،
* به مقدار env (`ALTCHA_ENABLED`) برمی‌گردد. پس هم از env هم از پنل قابل کنترل است.
*/
public function enabled(): bool
{
return $this->enabled;
$override = $this->configRepo->get('altcha_enabled');
if ($override !== null && $override !== '') {
return $override === '1' || strtolower($override) === 'true';
}
return $this->envEnabled;
}
/**
+15 -2
View File
@@ -4,6 +4,7 @@ namespace App\Tests\Shared\Captcha;
use AltchaOrg\Altcha\V1\Altcha;
use AltchaOrg\Altcha\V1\Hasher\Algorithm;
use App\Config\Repository\SiteConfigRepository;
use App\Shared\Captcha\AltchaService;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -15,9 +16,11 @@ class AltchaServiceTest extends TestCase
{
private const KEY = 'test-hmac-key-please-change';
private function service(bool $enabled = true, int $maxNumber = 2000, int $expire = 300): AltchaService
private function service(bool $enabled = true, int $maxNumber = 2000, int $expire = 300, ?string $override = null): AltchaService
{
return new AltchaService(self::KEY, $enabled, $maxNumber, $expire, new ArrayAdapter());
$configRepo = $this->createStub(SiteConfigRepository::class);
$configRepo->method('get')->willReturn($override); // null → fall back to env flag
return new AltchaService(self::KEY, $enabled, $maxNumber, $expire, new ArrayAdapter(), $configRepo);
}
/**
@@ -90,4 +93,14 @@ class AltchaServiceTest extends TestCase
self::assertTrue($this->service(true)->enabled());
self::assertFalse($this->service(false)->enabled());
}
public function testAdminOverrideBeatsEnv(): void
{
// env off ولی override پنل روشن → روشن
self::assertTrue($this->service(false, override: '1')->enabled());
// env on ولی override پنل خاموش → خاموش
self::assertFalse($this->service(true, override: '0')->enabled());
// override خالی/null → به env برمی‌گردد
self::assertTrue($this->service(true, override: null)->enabled());
}
}