Add AST JSON representation for SiteConfigController.php with nodes and edges

This commit is contained in:
hamed
2026-07-02 10:16:40 +03:30
parent 70d280070b
commit 949fddc57a
16 changed files with 707 additions and 650 deletions
+38 -8
View File
@@ -32,9 +32,11 @@ const schema = z.object({
appointment_fee_rials: z.string(), appointment_fee_rials: z.string(),
// payment gateways // payment gateways
payment_test_mode: z.string(), payment_test_mode: z.string(),
mellat_enabled: z.string(),
mellat_terminal_id: z.string(), mellat_terminal_id: z.string(),
mellat_username: z.string(), mellat_username: z.string(),
mellat_password: z.string(), mellat_password: z.string(),
sep_enabled: z.string(),
sep_terminal_id: z.string(), sep_terminal_id: z.string(),
}); });
@@ -53,9 +55,11 @@ interface Settings {
sms_panel_fee_rials: string; sms_panel_fee_rials: string;
appointment_fee_rials: string; appointment_fee_rials: string;
payment_test_mode: string; payment_test_mode: string;
mellat_enabled: string;
mellat_terminal_id: string; mellat_terminal_id: string;
mellat_username: string; mellat_username: string;
mellat_password: string; mellat_password: string;
sep_enabled: string;
sep_terminal_id: string; sep_terminal_id: string;
sms_api_key_configured: boolean; sms_api_key_configured: boolean;
} }
@@ -107,9 +111,11 @@ export default function SettingsPage() {
sms_panel_fee_rials: settings.sms_panel_fee_rials ?? '1500000', sms_panel_fee_rials: settings.sms_panel_fee_rials ?? '1500000',
appointment_fee_rials: settings.appointment_fee_rials ?? '150000', appointment_fee_rials: settings.appointment_fee_rials ?? '150000',
payment_test_mode: settings.payment_test_mode ?? '0', payment_test_mode: settings.payment_test_mode ?? '0',
mellat_enabled: settings.mellat_enabled ?? '1',
mellat_terminal_id: settings.mellat_terminal_id ?? '', mellat_terminal_id: settings.mellat_terminal_id ?? '',
mellat_username: settings.mellat_username ?? '', mellat_username: settings.mellat_username ?? '',
mellat_password: settings.mellat_password ?? '', mellat_password: settings.mellat_password ?? '',
sep_enabled: settings.sep_enabled ?? '1',
sep_terminal_id: settings.sep_terminal_id ?? '', sep_terminal_id: settings.sep_terminal_id ?? '',
}); });
} }
@@ -125,6 +131,8 @@ export default function SettingsPage() {
}); });
const paymentTestMode = watch('payment_test_mode') === '1'; const paymentTestMode = watch('payment_test_mode') === '1';
const mellatEnabled = watch('mellat_enabled') === '1';
const sepEnabled = watch('sep_enabled') === '1';
const apptCommissionEnabled = watch('appointment_commission_enabled') === '1'; const apptCommissionEnabled = watch('appointment_commission_enabled') === '1';
const upgradeCommissionEnabled = watch('upgrade_commission_enabled') === '1'; const upgradeCommissionEnabled = watch('upgrade_commission_enabled') === '1';
const taxEnabled = watch('tax_enabled') === '1'; const taxEnabled = watch('tax_enabled') === '1';
@@ -407,10 +415,20 @@ export default function SettingsPage() {
</div> </div>
{/* Mellat */} {/* Mellat */}
<div style={{ marginBottom: '1.25rem' }}> <div style={{ marginBottom: '1.25rem', opacity: mellatEnabled ? 1 : 0.55 }}>
<div style={{ fontSize: 13.5, fontWeight: 600, marginBottom: '0.75rem', display: 'flex', alignItems: 'center', gap: 6 }}> <div style={{ marginBottom: '0.75rem', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 }}>
<span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--violet)', display: 'inline-block' }} /> <div style={{ fontSize: 13.5, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6 }}>
درگاه ملت (Mellat) <span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--violet)', display: 'inline-block' }} />
درگاه ملت (Mellat)
</div>
<input type="hidden" {...register('mellat_enabled')} />
<label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer' }}
onClick={() => setValue('mellat_enabled', mellatEnabled ? '0' : '1', { shouldDirty: true })}>
<span style={{ fontSize: 12.5, fontWeight: 500, color: mellatEnabled ? 'var(--success)' : 'var(--muted)' }}>{mellatEnabled ? 'فعال' : 'غیرفعال'}</span>
<div style={{ width: 44, height: 24, borderRadius: 12, background: mellatEnabled ? 'var(--success)' : 'var(--border)', transition: 'background .2s', position: 'relative' }}>
<div style={{ position: 'absolute', top: 2, width: 20, height: 20, borderRadius: '50%', background: 'var(--surface)', transition: 'right .2s', right: mellatEnabled ? 2 : 22, boxShadow: '0 1px 3px rgba(0,0,0,.2)' }} />
</div>
</label>
</div> </div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '0.75rem' }}> <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '0.75rem' }}>
<div> <div>
@@ -441,10 +459,20 @@ export default function SettingsPage() {
</div> </div>
{/* SEP */} {/* SEP */}
<div> <div style={{ opacity: sepEnabled ? 1 : 0.55 }}>
<div style={{ fontSize: 13.5, fontWeight: 600, marginBottom: '0.75rem', display: 'flex', alignItems: 'center', gap: 6 }}> <div style={{ marginBottom: '0.75rem', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 6 }}>
<span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--success)', display: 'inline-block' }} /> <div style={{ fontSize: 13.5, fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6 }}>
درگاه سپ (SEP) <span style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--success)', display: 'inline-block' }} />
درگاه سپ (SEP)
</div>
<input type="hidden" {...register('sep_enabled')} />
<label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer' }}
onClick={() => setValue('sep_enabled', sepEnabled ? '0' : '1', { shouldDirty: true })}>
<span style={{ fontSize: 12.5, fontWeight: 500, color: sepEnabled ? 'var(--success)' : 'var(--muted)' }}>{sepEnabled ? 'فعال' : 'غیرفعال'}</span>
<div style={{ width: 44, height: 24, borderRadius: 12, background: sepEnabled ? 'var(--success)' : 'var(--border)', transition: 'background .2s', position: 'relative' }}>
<div style={{ position: 'absolute', top: 2, width: 20, height: 20, borderRadius: '50%', background: 'var(--surface)', transition: 'right .2s', right: sepEnabled ? 2 : 22, boxShadow: '0 1px 3px rgba(0,0,0,.2)' }} />
</div>
</label>
</div> </div>
<div style={{ maxWidth: 240 }}> <div style={{ maxWidth: 240 }}>
<label style={{ fontSize: 12.5, fontWeight: 500, display: 'block', marginBottom: 4 }}>شناسه پایانه</label> <label style={{ fontSize: 12.5, fontWeight: 500, display: 'block', marginBottom: 4 }}>شناسه پایانه</label>
@@ -495,9 +523,11 @@ export default function SettingsPage() {
sms_panel_fee_rials: settings.sms_panel_fee_rials, sms_panel_fee_rials: settings.sms_panel_fee_rials,
appointment_fee_rials: settings.appointment_fee_rials, appointment_fee_rials: settings.appointment_fee_rials,
payment_test_mode: settings.payment_test_mode, payment_test_mode: settings.payment_test_mode,
mellat_enabled: settings.mellat_enabled ?? '1',
mellat_terminal_id: settings.mellat_terminal_id, mellat_terminal_id: settings.mellat_terminal_id,
mellat_username: settings.mellat_username, mellat_username: settings.mellat_username,
mellat_password: settings.mellat_password, mellat_password: settings.mellat_password,
sep_enabled: settings.sep_enabled ?? '1',
sep_terminal_id: settings.sep_terminal_id, sep_terminal_id: settings.sep_terminal_id,
})} })}
disabled={!isDirty || mutation.isPending} disabled={!isDirty || mutation.isPending}
+1 -1
View File
@@ -675,7 +675,7 @@
"id": 600, "id": 600,
"uuid": "7bfbad3c-646b-11f1-84d7-f26ca1845824", "uuid": "7bfbad3c-646b-11f1-84d7-f26ca1845824",
"name": "نوبت 724", "name": "نوبت 724",
"site_name": "نوبت 724 نوبت", "site_name": "نوبت 724",
"status": 1, "status": 1,
"weight": 0, "weight": 0,
"province_id": null, "province_id": null,
+3
View File
@@ -847,9 +847,11 @@ Returns all site configuration values.
"appointment_reminder_hours": "2", "appointment_reminder_hours": "2",
"log_retention_days": "90", "log_retention_days": "90",
"payment_test_mode": "0", "payment_test_mode": "0",
"mellat_enabled": "1",
"mellat_terminal_id": "", "mellat_terminal_id": "",
"mellat_username": "", "mellat_username": "",
"mellat_password": "", "mellat_password": "",
"sep_enabled": "1",
"sep_terminal_id": "", "sep_terminal_id": "",
"sms_provider": "kavenegar", "sms_provider": "kavenegar",
"kavenegar_api_key": "", "kavenegar_api_key": "",
@@ -892,6 +894,7 @@ Update one or more settings. Unknown keys are silently ignored.
**Payment gateway rules:** **Payment gateway rules:**
- `payment_test_mode``"1"` = all payments use MockGateway (no real bank calls), `"0"` = real gateways - `payment_test_mode``"1"` = all payments use MockGateway (no real bank calls), `"0"` = real gateways
- `mellat_enabled` / `sep_enabled``"1"` = gateway selectable, `"0"` = gateway disabled (hidden from the payment selection list and rejected at `initiate`). Unset = enabled (default).
- `payment_allowed_frontend_hosts` — comma-separated hosts allowed as a payment `frontend_address` (origin site to return to). Falls back to the `ALLOWED_FRONTEND_HOSTS` env var when empty. Add a consumer site's host here to permit its payments. - `payment_allowed_frontend_hosts` — comma-separated hosts allowed as a payment `frontend_address` (origin site to return to). Falls back to the `ALLOWED_FRONTEND_HOSTS` env var when empty. Add a consumer site's host here to permit its payments.
- Gateway credentials (mellat/sep) read from DB first, fallback to env vars if DB value is empty - Gateway credentials (mellat/sep) read from DB first, fallback to env vars if DB value is empty
- MockGateway callback: same URL pattern + `&mock=1&ResCode=0&RefId=MOCK-{orderId}` (add `&cancel=1` to simulate a user cancellation → `canceled`) - MockGateway callback: same URL pattern + `&mock=1&ResCode=0&RefId=MOCK-{orderId}` (add `&cancel=1` to simulate a user cancellation → `canceled`)
+1 -1
View File
@@ -31,7 +31,7 @@
| `appointment_fee_rials` | integer | مبلغ هر نوبت به ریال (از تنظیمات سایت، کلید `appointment_fee_rials`). frontend برای نمایش «مبلغ قابل پرداخت» از این می‌خواند؛ مبلغِ واقعیِ تراکنش هم در backend از همین کلید خوانده می‌شود (نه از client) | | `appointment_fee_rials` | integer | مبلغ هر نوبت به ریال (از تنظیمات سایت، کلید `appointment_fee_rials`). frontend برای نمایش «مبلغ قابل پرداخت» از این می‌خواند؛ مبلغِ واقعیِ تراکنش هم در backend از همین کلید خوانده می‌شود (نه از client) |
| `gateways` | array | فقط درگاه‌های **فعال** (اعتبارنامه‌شان در تنظیمات سایت یا env ست شده). هر عضو: `{ name, label }`. frontend فقط همین‌ها را برای انتخاب نمایش می‌دهد. در `test_mode` تنها `[{ "name": "mellat", "label": "بانک ملت (آزمایشی)" }]` برمی‌گردد. اگر هیچ درگاهی فعال نباشد آرایه خالی است و frontend باید پرداخت را غیرفعال کند. | | `gateways` | array | فقط درگاه‌های **فعال** (اعتبارنامه‌شان در تنظیمات سایت یا env ست شده). هر عضو: `{ name, label }`. frontend فقط همین‌ها را برای انتخاب نمایش می‌دهد. در `test_mode` تنها `[{ "name": "mellat", "label": "بانک ملت (آزمایشی)" }]` برمی‌گردد. اگر هیچ درگاهی فعال نباشد آرایه خالی است و frontend باید پرداخت را غیرفعال کند. |
فعال‌بودن هر درگاه با `PaymentGatewayInterface::isConfigured()` تعیین می‌شود: `mellat` نیازمند `mellat_terminal_id` + `mellat_username` + `mellat_password`؛ `sep` نیازمند `sep_terminal_id`. فعال‌بودن هر درگاه با `PaymentGatewayInterface::isConfigured()` **و** کلید فعال‌سازی در تنظیمات سایت تعیین می‌شود: `mellat` نیازمند `mellat_terminal_id` + `mellat_username` + `mellat_password`؛ `sep` نیازمند `sep_terminal_id`. علاوه بر این، اگر ادمین درگاه را در تنظیمات غیرفعال کند (`mellat_enabled` / `sep_enabled` = `"0"`)، آن درگاه از این لیست حذف می‌شود و در `initiate` نیز رد می‌شود (خطای ۴۲۲: «درگاه پرداخت نامعتبر یا غیرفعال است»). کلید تنظیم‌نشده = فعال (پیش‌فرض).
**نکته:** این endpoint هیچ اطلاعات حساسی (terminal_id، password، ...) را expose نمی‌کند — فقط نام/برچسب درگاه‌های فعال. **نکته:** این endpoint هیچ اطلاعات حساسی (terminal_id، password، ...) را expose نمی‌کند — فقط نام/برچسب درگاه‌های فعال.
+3 -7
View File
@@ -637,6 +637,7 @@
"635": "Community 635", "635": "Community 635",
"636": "Community 636", "636": "Community 636",
"637": "Community 637", "637": "Community 637",
"638": "Community 638",
"639": "Community 639", "639": "Community 639",
"640": "Community 640", "640": "Community 640",
"641": "Community 641", "641": "Community 641",
@@ -650,18 +651,16 @@
"649": "Community 649", "649": "Community 649",
"650": "Community 650", "650": "Community 650",
"651": "Community 651", "651": "Community 651",
"652": "Community 652",
"653": "Community 653", "653": "Community 653",
"654": "Community 654", "654": "Community 654",
"655": "Community 655", "655": "Community 655",
"656": "Community 656", "656": "Community 656",
"657": "Community 657", "657": "Community 657",
"658": "Community 658",
"659": "Community 659", "659": "Community 659",
"660": "Community 660",
"661": "Community 661",
"662": "Community 662", "662": "Community 662",
"663": "Community 663", "663": "Community 663",
"664": "Community 664",
"665": "Community 665",
"666": "Community 666", "666": "Community 666",
"667": "Community 667", "667": "Community 667",
"668": "Community 668", "668": "Community 668",
@@ -669,8 +668,5 @@
"670": "Community 670", "670": "Community 670",
"671": "Community 671", "671": "Community 671",
"672": "Community 672", "672": "Community 672",
"675": "Community 675",
"677": "Community 677",
"678": "Community 678",
"679": "Community 679" "679": "Community 679"
} }
+105 -137
View File
@@ -1,16 +1,16 @@
# Graph Report - clinicpro (2026-07-02) # Graph Report - clinicpro (2026-07-02)
## Corpus Check ## Corpus Check
- 673 files · ~473,180 words - 673 files · ~473,575 words
- Verdict: corpus is large enough that graph structure adds value. - Verdict: corpus is large enough that graph structure adds value.
## Summary ## Summary
- 8465 nodes · 11664 edges · 674 communities (543 shown, 131 thin omitted) - 8466 nodes · 11667 edges · 670 communities (536 shown, 134 thin omitted)
- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 265 edges (avg confidence: 0.8) - Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 265 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output - Token cost: 0 input · 0 output
## Graph Freshness ## Graph Freshness
- Built from commit: `a7d5d17b` - Built from commit: `70d28007`
- Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost). - Run `graphify update .` after code changes (no API cost).
@@ -641,6 +641,7 @@
- [[_COMMUNITY_Community 635|Community 635]] - [[_COMMUNITY_Community 635|Community 635]]
- [[_COMMUNITY_Community 636|Community 636]] - [[_COMMUNITY_Community 636|Community 636]]
- [[_COMMUNITY_Community 637|Community 637]] - [[_COMMUNITY_Community 637|Community 637]]
- [[_COMMUNITY_Community 638|Community 638]]
- [[_COMMUNITY_Community 639|Community 639]] - [[_COMMUNITY_Community 639|Community 639]]
- [[_COMMUNITY_Community 640|Community 640]] - [[_COMMUNITY_Community 640|Community 640]]
- [[_COMMUNITY_Community 641|Community 641]] - [[_COMMUNITY_Community 641|Community 641]]
@@ -652,27 +653,22 @@
- [[_COMMUNITY_Community 649|Community 649]] - [[_COMMUNITY_Community 649|Community 649]]
- [[_COMMUNITY_Community 650|Community 650]] - [[_COMMUNITY_Community 650|Community 650]]
- [[_COMMUNITY_Community 651|Community 651]] - [[_COMMUNITY_Community 651|Community 651]]
- [[_COMMUNITY_Community 652|Community 652]]
- [[_COMMUNITY_Community 653|Community 653]] - [[_COMMUNITY_Community 653|Community 653]]
- [[_COMMUNITY_Community 654|Community 654]] - [[_COMMUNITY_Community 654|Community 654]]
- [[_COMMUNITY_Community 655|Community 655]] - [[_COMMUNITY_Community 655|Community 655]]
- [[_COMMUNITY_Community 656|Community 656]] - [[_COMMUNITY_Community 656|Community 656]]
- [[_COMMUNITY_Community 657|Community 657]] - [[_COMMUNITY_Community 657|Community 657]]
- [[_COMMUNITY_Community 658|Community 658]]
- [[_COMMUNITY_Community 659|Community 659]] - [[_COMMUNITY_Community 659|Community 659]]
- [[_COMMUNITY_Community 660|Community 660]]
- [[_COMMUNITY_Community 661|Community 661]]
- [[_COMMUNITY_Community 662|Community 662]] - [[_COMMUNITY_Community 662|Community 662]]
- [[_COMMUNITY_Community 663|Community 663]] - [[_COMMUNITY_Community 663|Community 663]]
- [[_COMMUNITY_Community 664|Community 664]]
- [[_COMMUNITY_Community 665|Community 665]]
- [[_COMMUNITY_Community 666|Community 666]] - [[_COMMUNITY_Community 666|Community 666]]
- [[_COMMUNITY_Community 667|Community 667]] - [[_COMMUNITY_Community 667|Community 667]]
- [[_COMMUNITY_Community 668|Community 668]] - [[_COMMUNITY_Community 668|Community 668]]
- [[_COMMUNITY_Community 669|Community 669]] - [[_COMMUNITY_Community 669|Community 669]]
- [[_COMMUNITY_Community 671|Community 671]] - [[_COMMUNITY_Community 671|Community 671]]
- [[_COMMUNITY_Community 672|Community 672]] - [[_COMMUNITY_Community 672|Community 672]]
- [[_COMMUNITY_Community 675|Community 675]]
- [[_COMMUNITY_Community 677|Community 677]]
- [[_COMMUNITY_Community 678|Community 678]]
- [[_COMMUNITY_Community 679|Community 679]] - [[_COMMUNITY_Community 679|Community 679]]
## God Nodes (most connected - your core abstractions) ## God Nodes (most connected - your core abstractions)
@@ -692,45 +688,45 @@
assets/admin/components/ServiceTariffModal.tsx → assets/admin/lib/utils.ts assets/admin/components/ServiceTariffModal.tsx → assets/admin/lib/utils.ts
- `PersianDatePicker()` --calls--> `formatDate()` [EXTRACTED] - `PersianDatePicker()` --calls--> `formatDate()` [EXTRACTED]
assets/admin/components/ui/PersianDatePicker.tsx → assets/admin/lib/utils.ts assets/admin/components/ui/PersianDatePicker.tsx → assets/admin/lib/utils.ts
- `LogsPage()` --calls--> `formatDateTime()` [EXTRACTED]
assets/admin/pages/LogsPage.tsx → assets/admin/lib/utils.ts
- `SmsPage()` --calls--> `formatDateTime()` [EXTRACTED] - `SmsPage()` --calls--> `formatDateTime()` [EXTRACTED]
assets/admin/pages/SmsPage.tsx → assets/admin/lib/utils.ts assets/admin/pages/SmsPage.tsx → assets/admin/lib/utils.ts
- `NewAppointmentModal()` --calls--> `useAuthStore` [EXTRACTED] - `NewAppointmentModal()` --calls--> `useAuthStore` [EXTRACTED]
assets/admin/pages/AppointmentsPage.tsx → assets/admin/stores/authStore.ts assets/admin/pages/AppointmentsPage.tsx → assets/admin/stores/authStore.ts
- `LogoUploadField()` --calls--> `useAuthStore` [EXTRACTED]
assets/admin/pages/CategoriesPage.tsx → assets/admin/stores/authStore.ts
## Import Cycles ## Import Cycles
- None detected. - None detected.
## Communities (674 total, 131 thin omitted) ## Communities (670 total, 134 thin omitted)
### Community 0 - "Community 0" ### Community 0 - "Community 0"
Cohesion: 0.05 Cohesion: 0.05
Nodes (40): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, AddForm, addSchema (+32 more) Nodes (37): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, AddForm, addSchema (+29 more)
### Community 1 - "Community 1" ### Community 1 - "Community 1"
Cohesion: 0.03 Cohesion: 0.03
Nodes (41): AddressData, AddrForm, addrSchema, AVATAR_COLORS, BookingMeta, CityOpt, DateOverrideData, DEFAULT_BOOKING_META (+33 more) Nodes (41): AddressData, AddrForm, addrSchema, AVATAR_COLORS, BookingMeta, CityOpt, DateOverrideData, DEFAULT_BOOKING_META (+33 more)
### Community 2 - "Community 2" ### Community 2 - "Community 2"
Cohesion: 0.08 Cohesion: 0.07
Nodes (23): get, PaymentConfig, PaymentGatewayInfo, api, ApiError, getToken(), refreshOnce(), request() (+15 more) Nodes (26): get, PaymentConfig, PaymentGatewayInfo, api, ApiError, getToken(), refreshOnce(), request() (+18 more)
### Community 3 - "Community 3" ### Community 3 - "Community 3"
Cohesion: 0.05 Cohesion: 0.03
Nodes (42): ApiResponse, PaginatedResponse, formatDate(), STATUS_FILTERS, FILTERS, Breakdown, SOURCE_LABEL, Summary (+34 more) Nodes (80): ApiResponse, PaginatedResponse, formatDate(), ALL_STATUSES, AppointmentDetailPage(), STATUS_FILTERS, FILTERS, Breakdown (+72 more)
### Community 4 - "Community 4" ### Community 4 - "Community 4"
Cohesion: 0.06 Cohesion: 0.05
Nodes (8): DoctorService, Doctor, DoctorServiceRepository, Collection, self, User, WeeklySchedule, ManagerRegistry Nodes (11): DoctorServiceController, DoctorService, Doctor, DoctorServiceRepository, Collection, self, User, WeeklySchedule (+3 more)
### Community 5 - "Community 5" ### Community 5 - "Community 5"
Cohesion: 0.07 Cohesion: 0.07
Nodes (3): UserProfile, self, User Nodes (3): UserProfile, self, User
### Community 6 - "Community 6" ### Community 6 - "Community 6"
Cohesion: 0.12 Cohesion: 0.09
Nodes (12): SettlementController, SettlementRepository, WalletTransactionRepository, Settlement, JsonResponse, Request, User, ManagerRegistry (+4 more) Nodes (15): SettlementController, SettlementRepository, WalletTransactionRepository, CommissionService, Settlement, JsonResponse, Request, User (+7 more)
### Community 7 - "Community 7" ### Community 7 - "Community 7"
Cohesion: 0.07 Cohesion: 0.07
@@ -749,16 +745,16 @@ Cohesion: 0.04
Nodes (46): Clinic Address Management, Clinic API, DELETE `/api/v1/admin/clinic/{clinicUuid}/doctor/{doctorUuid}`, `DELETE /api/v1/clinic/{clinicUuid}/address/{addressUuid}`, Errors, Errors, Errors, Errors (+38 more) Nodes (46): Clinic Address Management, Clinic API, DELETE `/api/v1/admin/clinic/{clinicUuid}/doctor/{doctorUuid}`, `DELETE /api/v1/clinic/{clinicUuid}/address/{addressUuid}`, Errors, Errors, Errors, Errors (+38 more)
### Community 11 - "Community 11" ### Community 11 - "Community 11"
Cohesion: 0.05 Cohesion: 0.50
Nodes (48): usePaymentConfig(), ALL_STATUSES, SmsPage(), STATUS_LOG_META, Tab, TAG_FILTER_OPTIONS, TAG_LABELS, TemplateFormData (+40 more) Nodes (4): UserActiveContextRepository, ManagerRegistry, User, UserActiveContext
### Community 12 - "Community 12" ### Community 12 - "Community 12"
Cohesion: 0.05 Cohesion: 0.05
Nodes (44): Clinic Doctor Invitation API, DELETE `/api/v1/admin/clinic/invitation/{invUuid}`, Errors, Errors, Errors, Errors, Errors, Errors (+36 more) 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" ### Community 13 - "Community 13"
Cohesion: 0.07 Cohesion: 0.06
Nodes (25): FreeVisitPrice(), Pricing, formatDateTime(), formatRial(), AppointmentDetailPage(), InsurancePricingPage(), FinancialSummary, MonthlyEntry (+17 more) Nodes (35): FreeVisitPrice(), Pricing, usePaymentConfig(), formatDateTime(), formatRial(), InsurancePricingPage(), LogsPage(), FinancialSummary (+27 more)
### Community 14 - "Community 14" ### Community 14 - "Community 14"
Cohesion: 0.15 Cohesion: 0.15
@@ -769,8 +765,8 @@ Cohesion: 0.09
Nodes (13): PaymentController, MockGateway, SepGateway, JsonResponse, Payment, PaymentGatewayInterface, Request, Response (+5 more) Nodes (13): PaymentController, MockGateway, SepGateway, JsonResponse, Payment, PaymentGatewayInterface, Request, Response (+5 more)
### Community 16 - "Community 16" ### Community 16 - "Community 16"
Cohesion: 0.09 Cohesion: 0.06
Nodes (6): PatientSession, Appointment, Collection, PatientRecord, self, SessionService Nodes (9): PatientSession, SmsWallet, LogPruneService, AppointmentExpiryService, Appointment, Collection, PatientRecord, self (+1 more)
### Community 17 - "Community 17" ### Community 17 - "Community 17"
Cohesion: 0.05 Cohesion: 0.05
@@ -790,7 +786,7 @@ Nodes (3): AdminApiController, JsonResponse, Request
### Community 21 - "Community 21" ### Community 21 - "Community 21"
Cohesion: 0.05 Cohesion: 0.05
Nodes (34): formatNumber(), ClinicDetailPage(), AdminCharts, AdminDashboard(), AdminRecent, AdminStats, APPT_CLS, APPT_COLOR (+26 more) Nodes (37): formatNumber(), ClinicDetailPage(), AdminCharts, AdminDashboard(), AdminRecent, AdminStats, APPT_CLS, APPT_COLOR (+29 more)
### Community 22 - "Community 22" ### Community 22 - "Community 22"
Cohesion: 0.29 Cohesion: 0.29
@@ -809,12 +805,12 @@ Cohesion: 0.05
Nodes (39): Appointment API, Error Responses, Errors, Errors, Errors, Errors, Errors, Errors (+31 more) Nodes (39): Appointment API, Error Responses, Errors, Errors, Errors, Errors, Errors, Errors (+31 more)
### Community 26 - "Community 26" ### Community 26 - "Community 26"
Cohesion: 0.15 Cohesion: 0.13
Nodes (7): InsuranceController, EntityInsurancePricing, EntityInsurancePricingRepository, JsonResponse, Request, User, ManagerRegistry Nodes (8): InsuranceController, EntityInsurancePricing, EntityInsurancePricingRepository, TenantInsuranceCleanupService, JsonResponse, Request, User, ManagerRegistry
### Community 27 - "Community 27" ### Community 27 - "Community 27"
Cohesion: 0.06 Cohesion: 0.05
Nodes (35): 55. 🟢 `GET` all tag, 56. 🟢 `GET` supplementary_insurance, 57. 🟢 `GET` categories list, 58. 🟢 `GET` all state, 59. 🟢 `GET` all city, 60. 🟢 `GET` all specially doctor, 61. 🔵 `POST` post, 63. 🔴 `DELETE` DELETE (+27 more) Nodes (40): 55. 🟢 `GET` all tag, 56. 🟢 `GET` supplementary_insurance, 57. 🟢 `GET` categories list, 58. 🟢 `GET` all state, 59. 🟢 `GET` all city, 60. 🟢 `GET` all specially doctor, 61. 🔵 `POST` post, 62. 🟡 `PATCH` patch (+32 more)
### Community 28 - "Community 28" ### Community 28 - "Community 28"
Cohesion: 0.09 Cohesion: 0.09
@@ -837,8 +833,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) 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" ### Community 33 - "Community 33"
Cohesion: 0.04 Cohesion: 0.08
Nodes (39): CoverageRow, Draft, KIND, TenantInsurance, ServiceTariffModal(), TariffResponse, TariffRow, Contract (+31 more) Nodes (20): CoverageRow, Draft, KIND, TenantInsurance, ServiceTariffModal(), TariffResponse, TariffRow, EMPTY_ITEMS (+12 more)
### Community 34 - "Community 34" ### Community 34 - "Community 34"
Cohesion: 0.06 Cohesion: 0.06
@@ -869,8 +865,8 @@ Cohesion: 0.09
Nodes (4): User, PasswordAuthenticatedUserInterface, self, UserInterface Nodes (4): User, PasswordAuthenticatedUserInterface, self, UserInterface
### Community 41 - "Community 41" ### Community 41 - "Community 41"
Cohesion: 0.06 Cohesion: 0.05
Nodes (23): CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema, LogoUploadField(), ProvinceForm, provinceSchema (+15 more) Nodes (29): Contract, InsuranceOption, KIND_LABEL, CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema (+21 more)
### Community 42 - "Community 42" ### Community 42 - "Community 42"
Cohesion: 0.07 Cohesion: 0.07
@@ -917,8 +913,8 @@ Cohesion: 0.07
Nodes (26): الزامات UI, باگ‌فیکس صفحه نوبت‌ها, باگ ۱ — کرش تقویم, باگ ۲ — روز هفته در DateNavigator, باگ ۳ — پیام «slot نیست», باگ ۴ — نوبت جدید: نام اجباری + find-or-create patient, باگ ۵ — patient_mobile نشان می‌دهد موبایل پزشک, باگ ۶ — نوبت‌های رزرو شده در نمایش زمانبندی (+18 more) Nodes (26): الزامات UI, باگ‌فیکس صفحه نوبت‌ها, باگ ۱ — کرش تقویم, باگ ۲ — روز هفته در DateNavigator, باگ ۳ — پیام «slot نیست», باگ ۴ — نوبت جدید: نام اجباری + find-or-create patient, باگ ۵ — patient_mobile نشان می‌دهد موبایل پزشک, باگ ۶ — نوبت‌های رزرو شده در نمایش زمانبندی (+18 more)
### Community 53 - "Community 53" ### Community 53 - "Community 53"
Cohesion: 0.08 Cohesion: 0.09
Nodes (17): AppLogRepository, ClaimItemRepository, InvoiceItemRepository, PreRegistrationRepository, SessionServiceRepository, UserActiveContextRepository, ServiceEntityRepository, ManagerRegistry (+9 more) Nodes (13): AppLogRepository, ClaimItemRepository, PreRegistrationRepository, SmsLogRepository, TariffRepository, ServiceEntityRepository, SmsLog, ManagerRegistry (+5 more)
### Community 54 - "Community 54" ### Community 54 - "Community 54"
Cohesion: 0.10 Cohesion: 0.10
@@ -961,8 +957,8 @@ Cohesion: 0.22
Nodes (5): AuthController, RateLimiterFactory, JsonResponse, Request, User Nodes (5): AuthController, RateLimiterFactory, JsonResponse, Request, User
### Community 64 - "Community 64" ### Community 64 - "Community 64"
Cohesion: 0.20 Cohesion: 0.32
Nodes (7): SmsWalletController, SmsSettingsRepository, SmsSettings, JsonResponse, Request, User, ManagerRegistry Nodes (4): SmsWalletController, JsonResponse, Request, User
### Community 65 - "Community 65" ### Community 65 - "Community 65"
Cohesion: 0.08 Cohesion: 0.08
@@ -1033,8 +1029,8 @@ Cohesion: 0.07
Nodes (29): devDependencies, @babel/core, @babel/preset-env, @babel/preset-react, @babel/preset-typescript, core-js, @hotwired/stimulus, jsdom (+21 more) Nodes (29): devDependencies, @babel/core, @babel/preset-env, @babel/preset-react, @babel/preset-typescript, core-js, @hotwired/stimulus, jsdom (+21 more)
### Community 86 - "Community 86" ### Community 86 - "Community 86"
Cohesion: 0.06 Cohesion: 0.07
Nodes (15): AppointmentExpiryServiceTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, ServiceItemStaffOwnershipTest, EntityManagerInterface, KernelBrowser, CommentPaginationTest (+7 more) Nodes (13): AppointmentExpiryServiceTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, ServiceItemDeleteCleanupTest, ServiceItemStaffOwnershipTest, KernelBrowser, CommentPaginationTest (+5 more)
### Community 87 - "Community 87" ### Community 87 - "Community 87"
Cohesion: 0.10 Cohesion: 0.10
@@ -1121,8 +1117,8 @@ Cohesion: 0.32
Nodes (6): AppointmentController, Appointment, Doctor, JsonResponse, Request, User Nodes (6): AppointmentController, Appointment, Doctor, JsonResponse, Request, User
### Community 108 - "Community 108" ### Community 108 - "Community 108"
Cohesion: 0.18 Cohesion: 0.13
Nodes (7): BaseController, CategoryController, CategoryImportController, JsonResponse, JsonResponse, Request, JsonResponse Nodes (10): BaseController, CategoryController, CategoryImportController, SmsMessageController, JsonResponse, JsonResponse, Request, JsonResponse (+2 more)
### Community 109 - "Community 109" ### Community 109 - "Community 109"
Cohesion: 0.29 Cohesion: 0.29
@@ -1322,7 +1318,7 @@ Nodes (15): Date Overrides, DELETE `/api/v1/appointment-settings/date-override/{
### Community 161 - "Community 161" ### Community 161 - "Community 161"
Cohesion: 0.24 Cohesion: 0.24
Nodes (7): ClaimSubmitterInterface, ClaimService, ManualClaimSubmitter, Claim, Invoice, Claim, ClaimSubmissionResult Nodes (5): ClaimsListNPlusOneTest, ClaimItem, ClaimService, Claim, Invoice
### Community 162 - "Community 162" ### Community 162 - "Community 162"
Cohesion: 0.13 Cohesion: 0.13
@@ -1400,10 +1396,6 @@ Nodes (3): PatientRecord, Collection, User
Cohesion: 0.23 Cohesion: 0.23
Nodes (3): WeeklySchedule, Doctor, self Nodes (3): WeeklySchedule, Doctor, self
### Community 182 - "Community 182"
Cohesion: 0.07
Nodes (5): SmsSettings, SmsWallet, LogPruneService, AppointmentExpiryService, self
### Community 183 - "Community 183" ### Community 183 - "Community 183"
Cohesion: 0.14 Cohesion: 0.14
Nodes (13): `UserDetailPage.tsx` — فقط user query, زمینه, فایل‌های مرتبط, قرارداد پروفایل (`UserProfile.toArray`), مشکل / هدف, نمایش پروفایل کاربر در صفحه‌ی جزئیات کاربرِ پنل ادمین, نکات مهم, وضعیت فعلی (کد واقعی) (+5 more) Nodes (13): `UserDetailPage.tsx` — فقط user query, زمینه, فایل‌های مرتبط, قرارداد پروفایل (`UserProfile.toArray`), مشکل / هدف, نمایش پروفایل کاربر در صفحه‌ی جزئیات کاربرِ پنل ادمین, نکات مهم, وضعیت فعلی (کد واقعی) (+5 more)
@@ -1473,12 +1465,12 @@ Cohesion: 0.14
Nodes (13): Endpoint ها, PATCH /api/v1/secretary/{uuid}, POST /api/v1/secretary, تسک ۱۴: ماژول منشی, توضیح, زمان تخمینی, ساختار JSON, سیستم مجوزها — Resource-Based Permissions (مقیاس‌پذیر) (+5 more) Nodes (13): Endpoint ها, PATCH /api/v1/secretary/{uuid}, POST /api/v1/secretary, تسک ۱۴: ماژول منشی, توضیح, زمان تخمینی, ساختار JSON, سیستم مجوزها — Resource-Based Permissions (مقیاس‌پذیر) (+5 more)
### Community 201 - "Community 201" ### Community 201 - "Community 201"
Cohesion: 0.15 Cohesion: 0.20
Nodes (13): Admin API, Clinic Invitation Management, GET `/api/v1/admin/pre-registrations`, GET `/api/v1/admin/representations`, 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) Nodes (10): Admin API, Clinic Invitation Management, GET `/api/v1/admin/comments`, GET `/api/v1/admin/rates`, GET /api/v1/admin/settings, PATCH /api/v1/admin/settings, Query Parameters, Query Parameters (+2 more)
### Community 202 - "Community 202" ### Community 202 - "Community 202"
Cohesion: 0.15 Cohesion: 0.10
Nodes (13): DELETE `/api/v1/appointment-settings/holidays/{uuid}`, Errors, GET `/api/v1/appointment-settings/holidays/list/{doctorUuid}`, GET `/api/v1/appointment-settings/holidays/{uuid}`, Holidays, PATCH `/api/v1/appointment-settings/holidays/{uuid}`, POST `/api/v1/appointment-settings/holidays`, Request Body (+5 more) Nodes (19): Appointment Settings API, Available Locations, DELETE `/api/v1/appointment-settings/holidays/{uuid}`, Errors, Errors, `GET /api/v1/appointment-settings/available-locations/{doctorUuid}`, GET `/api/v1/appointment-settings/holidays/list/{doctorUuid}`, GET `/api/v1/appointment-settings/holidays/{uuid}` (+11 more)
### Community 203 - "Community 203" ### Community 203 - "Community 203"
Cohesion: 0.15 Cohesion: 0.15
@@ -1565,8 +1557,8 @@ Cohesion: 0.30
Nodes (6): AbstractAuthenticator, Passport, PasswordAuthenticator, Request, Response, TokenInterface Nodes (6): AbstractAuthenticator, Passport, PasswordAuthenticator, Request, Response, TokenInterface
### Community 228 - "Community 228" ### Community 228 - "Community 228"
Cohesion: 0.05 Cohesion: 0.04
Nodes (43): 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 (+35 more) 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" ### Community 229 - "Community 229"
Cohesion: 0.15 Cohesion: 0.15
@@ -1652,10 +1644,6 @@ Nodes (11): Endpoint ها, تسک ۱۸: ماژول تسویه نماینده (Se
Cohesion: 0.18 Cohesion: 0.18
Nodes (11): Appointment Management, Error Responses, GET `/api/v1/admin/appointments`, GET `/api/v1/admin/appointments/today-stats`, POST `/api/v1/admin/appointment`, Query Parameters, Query Parameters, Request Body (+3 more) Nodes (11): Appointment Management, Error Responses, GET `/api/v1/admin/appointments`, GET `/api/v1/admin/appointments/today-stats`, POST `/api/v1/admin/appointment`, Query Parameters, Query Parameters, Request Body (+3 more)
### Community 251 - "Community 251"
Cohesion: 0.21
Nodes (4): SmsLogRepository, OtpService, SmsLog, ManagerRegistry
### Community 252 - "Community 252" ### Community 252 - "Community 252"
Cohesion: 0.45 Cohesion: 0.45
Nodes (4): NotificationMobileController, JsonResponse, Request, User Nodes (4): NotificationMobileController, JsonResponse, Request, User
@@ -1701,8 +1689,8 @@ Cohesion: 0.33
Nodes (4): RepresentationRepository, ManagerRegistry, Representation, User Nodes (4): RepresentationRepository, ManagerRegistry, Representation, User
### Community 265 - "Community 265" ### Community 265 - "Community 265"
Cohesion: 0.15 Cohesion: 0.08
Nodes (17): calcFinalPrice(), EMPTY_RECORDS, EMPTY_SESSIONS, fileNumber(), getPatientName(), getPatientPhone(), InsurancePricing, MyPatientsPageInner() (+9 more) Nodes (27): calcFinalPrice(), EMPTY_RECORDS, EMPTY_SESSIONS, fileNumber(), getPatientName(), getPatientPhone(), InsurancePricing, MyPatientsPageInner() (+19 more)
### Community 266 - "Community 266" ### Community 266 - "Community 266"
Cohesion: 0.33 Cohesion: 0.33
@@ -1837,8 +1825,8 @@ 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) 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" ### Community 300 - "Community 300"
Cohesion: 0.42 Cohesion: 0.19
Nodes (3): PreRegistrationController, JsonResponse, Request Nodes (6): HealthController, PreRegistrationController, EntityManagerInterface, JsonResponse, Request, JsonResponse
### Community 301 - "Community 301" ### Community 301 - "Community 301"
Cohesion: 0.36 Cohesion: 0.36
@@ -1853,8 +1841,8 @@ Cohesion: 0.12
Nodes (16): آماده‌سازی پروژه ClinicPro برای دیپلوی روی Coolify با Docker Compose, زمینه, فایل‌های مرتبط, نکات مهم (محدودیت‌ها و edge caseها), هدف, وظایف, ۱. ساخت `Dockerfile` چندمرحله‌ای, ۱۰. ساخت راهنمای `docs/deploy/coolify.md` (+8 more) Nodes (16): آماده‌سازی پروژه ClinicPro برای دیپلوی روی Coolify با Docker Compose, زمینه, فایل‌های مرتبط, نکات مهم (محدودیت‌ها و edge caseها), هدف, وظایف, ۱. ساخت `Dockerfile` چندمرحله‌ای, ۱۰. ساخت راهنمای `docs/deploy/coolify.md` (+8 more)
### Community 304 - "Community 304" ### Community 304 - "Community 304"
Cohesion: 0.22 Cohesion: 0.04
Nodes (9): 30. 🟢 `GET` get 🆕, 33. 🔵 `POST` image_clinic, 36. 🟢 `GET` get my rate, 6. کلینیک (Clinic), هدرهای اضافی, هدرهای اضافی, پاسخ‌ها, پاسخ‌ها (+1 more) Nodes (46): 29. 🟢 `GET` clinic list 🆕, 30. 🟢 `GET` get 🆕, 33. 🔵 `POST` image_clinic, 34. 🔵 `POST` image logo, 36. 🟢 `GET` get my rate, 37. 🔵 `POST` post, 39. 🟡 `PATCH` Comment confirmation, 40. 🔵 `POST` post (+38 more)
### Community 306 - "Community 306" ### Community 306 - "Community 306"
Cohesion: 0.07 Cohesion: 0.07
@@ -1901,8 +1889,8 @@ Cohesion: 0.36
Nodes (3): SubscriptionPlanRepository, ManagerRegistry, SubscriptionPlan Nodes (3): SubscriptionPlanRepository, ManagerRegistry, SubscriptionPlan
### Community 317 - "Community 317" ### Community 317 - "Community 317"
Cohesion: 0.36 Cohesion: 0.43
Nodes (3): TariffRepository, ManagerRegistry, Tariff Nodes (3): InvoiceItemRepository, InvoiceItem, ManagerRegistry
### Community 319 - "Community 319" ### Community 319 - "Community 319"
Cohesion: 0.39 Cohesion: 0.39
@@ -1953,8 +1941,8 @@ Cohesion: 0.22
Nodes (8): Query های جدید, بیماران منحصربه‌فرد در بازه, درآمد بر اساس روز (از patient_sessions), فروش اشتراک بر اساس پنل (admin), نوبت‌ها بر اساس روز (admin chart), نکات مهم, هیچ migration لازم نیست, پایگاه داده — تسک ۱۶: داشبورد هوشمند Nodes (8): Query های جدید, بیماران منحصربه‌فرد در بازه, درآمد بر اساس روز (از patient_sessions), فروش اشتراک بر اساس پنل (admin), نوبت‌ها بر اساس روز (admin chart), نکات مهم, هیچ migration لازم نیست, پایگاه داده — تسک ۱۶: داشبورد هوشمند
### Community 333 - "Community 333" ### Community 333 - "Community 333"
Cohesion: 0.05 Cohesion: 0.25
Nodes (39): DELETE `/api/v1/clinic-pro/doctor-address/{id}`, DELETE `/api/v1/doctor/{uuid}`, Doctor API, Errors, Errors, Errors, Errors, Errors (+31 more) 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" ### Community 334 - "Community 334"
Cohesion: 0.25 Cohesion: 0.25
@@ -2021,8 +2009,8 @@ Cohesion: 0.26
Nodes (3): MellatGateway, PaymentInitResult, PaymentVerifyResult Nodes (3): MellatGateway, PaymentInitResult, PaymentVerifyResult
### Community 352 - "Community 352" ### Community 352 - "Community 352"
Cohesion: 0.36 Cohesion: 0.48
Nodes (3): DoctorServiceController, JsonResponse, Request Nodes (3): SmsSettingsRepository, SmsSettings, ManagerRegistry
### Community 354 - "Community 354" ### Community 354 - "Community 354"
Cohesion: 0.36 Cohesion: 0.36
@@ -2185,20 +2173,20 @@ Cohesion: 0.33
Nodes (6): Refactoring Plan, فاز ۰ — مستندسازی (۳ تا ۵ روز، قبل از هر کدنویسی), فاز ۱ — زیرساخت پایه (task-01), فاز ۲ — پیاده‌سازی ماژول‌ها (به ترتیب dependency), فاز ۳ — بهینه‌سازی (بعد از پیاده‌سازی), فاز ۴ — آماده‌سازی تولید Nodes (6): Refactoring Plan, فاز ۰ — مستندسازی (۳ تا ۵ روز، قبل از هر کدنویسی), فاز ۱ — زیرساخت پایه (task-01), فاز ۲ — پیاده‌سازی ماژول‌ها (به ترتیب dependency), فاز ۳ — بهینه‌سازی (بعد از پیاده‌سازی), فاز ۴ — آماده‌سازی تولید
### Community 397 - "Community 397" ### Community 397 - "Community 397"
Cohesion: 0.21 Cohesion: 0.36
Nodes (6): ClaimAmountBoundsTest, ClaimsListNPlusOneTest, ClaimItem, Claim, Doctor, User Nodes (4): ClaimAmountBoundsTest, Claim, Doctor, User
### Community 398 - "Community 398" ### Community 398 - "Community 398"
Cohesion: 0.29 Cohesion: 0.29
Nodes (4): initiate(), verify(), PaymentInitResult, PaymentVerifyResult Nodes (4): initiate(), verify(), PaymentInitResult, PaymentVerifyResult
### Community 404 - "Community 404" ### Community 400 - "Community 400"
Cohesion: 0.23 Cohesion: 0.23
Nodes (5): AbstractMigration, Schema, Version20260609133334, Schema, Version20260619062912 Nodes (5): AbstractMigration, Schema, Version20260609131553, Schema, Version20260609134741
### Community 405 - "Community 405" ### Community 405 - "Community 405"
Cohesion: 0.47 Cohesion: 0.53
Nodes (3): CommissionService, Payment, Representation Nodes (4): ClaimSubmitterInterface, ManualClaimSubmitter, Claim, ClaimSubmissionResult
### Community 407 - "Community 407" ### Community 407 - "Community 407"
Cohesion: 0.36 Cohesion: 0.36
@@ -2217,8 +2205,8 @@ 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) 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 452 - "Community 452" ### Community 452 - "Community 452"
Cohesion: 0.06 Cohesion: 0.05
Nodes (31): cn(), iranMobileOptionalSchema, iranMobileSchema, isValidIranMobile(), maskMobile(), sanitizeMobileInput(), toDate(), toEnglishDigits() (+23 more) Nodes (34): cn(), iranMobileOptionalSchema, iranMobileSchema, isValidIranMobile(), maskMobile(), sanitizeMobileInput(), toDate(), toEnglishDigits() (+26 more)
### Community 456 - "Community 456" ### Community 456 - "Community 456"
Cohesion: 0.38 Cohesion: 0.38
@@ -2333,8 +2321,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 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 491 - "Community 491" ### Community 491 - "Community 491"
Cohesion: 0.43 Cohesion: 0.53
Nodes (3): SmsMessageController, JsonResponse, Request Nodes (3): SessionServiceRepository, ManagerRegistry, SessionService
### Community 493 - "Community 493" ### Community 493 - "Community 493"
Cohesion: 0.20 Cohesion: 0.20
@@ -2488,10 +2476,6 @@ Nodes (4): Errors, POST `/api/v1/user/verify-code`, Request Body, Response `200`
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/representation/{uuid}`, Path Parameters, Response `200` Nodes (4): Errors, GET `/api/v1/representation/{uuid}`, Path Parameters, Response `200`
### Community 536 - "Community 536"
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 539 - "Community 539" ### Community 539 - "Community 539"
Cohesion: 0.67 Cohesion: 0.67
Nodes (3): Errors, GET `/api/v1/notification-mobile/{target}`, Response `200` Nodes (3): Errors, GET `/api/v1/notification-mobile/{target}`, Response `200`
@@ -2650,15 +2634,15 @@ Nodes (5): Errors, GET `/api/v1/clinic/my-doctor/{doctorUuid}`, Path Parameters,
### Community 596 - "Community 596" ### Community 596 - "Community 596"
Cohesion: 0.40 Cohesion: 0.40
Nodes (5): GET `/api/v1/admin/comments`, GET `/api/v1/admin/rates`, Query Parameters, Query Parameters, Rating & Comment Management Nodes (5): Errors, PATCH `/api/v1/clinic-pro/doctor-address/{id}`, Path Parameters, Request Body, Response `200`
### Community 597 - "Community 597" ### Community 597 - "Community 597"
Cohesion: 0.20 Cohesion: 0.20
Nodes (10): Configuration, DELETE `/api/v1/sms/template/{uuid}`, Errors, Errors, GET `/api/v1/admin/sms/templates`, GET `/api/v1/sms/template/{uuid}`, Response `200`, Response `200` (+2 more) Nodes (10): Configuration, DELETE `/api/v1/sms/template/{uuid}`, Errors, Errors, GET `/api/v1/admin/sms/templates`, GET `/api/v1/sms/template/{uuid}`, Response `200`, Response `200` (+2 more)
### Community 598 - "Community 598" ### Community 598 - "Community 598"
Cohesion: 0.40 Cohesion: 0.50
Nodes (5): 62. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها Nodes (4): GET `/api/v1/admin/pre-registrations`, POST `/api/v1/admin/pre-registrations/{uuid}/approve`, POST `/api/v1/admin/pre-registrations/{uuid}/reject`, Pre-Registration Management
### Community 599 - "Community 599" ### Community 599 - "Community 599"
Cohesion: 0.67 Cohesion: 0.67
@@ -2697,20 +2681,20 @@ Cohesion: 0.67
Nodes (3): بک‌اند, فرانت‌اند, وضعیت فعلی کد (مهم — قبل از تغییر بخوان) Nodes (3): بک‌اند, فرانت‌اند, وضعیت فعلی کد (مهم — قبل از تغییر بخوان)
### Community 618 - "Community 618" ### Community 618 - "Community 618"
Cohesion: 0.10 Cohesion: 0.15
Nodes (7): ServiceItemDeleteCleanupTest, ServiceCoverageNPlusOneTest, TenantInsuranceCleanupTest, TenantServiceCoverageRepository, TenantInsuranceCleanupService, ManagerRegistry, TenantServiceCoverage Nodes (5): ServiceCoverageNPlusOneTest, TenantInsuranceCleanupTest, TenantServiceCoverageRepository, ManagerRegistry, TenantServiceCoverage
### Community 631 - "Community 631" ### Community 631 - "Community 631"
Cohesion: 0.40 Cohesion: 0.50
Nodes (3): Props, StatTone, TONE Nodes (4): GET `/api/v1/admin/representations`, Query Parameters, Representation Management, Response `200`
### Community 632 - "Community 632" ### Community 632 - "Community 632"
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/admin/insurances`, Query Parameters, Response `200` Nodes (4): DELETE `/api/v1/doctor/{uuid}`, Errors, Path Parameters, Response `200`
### Community 633 - "Community 633" ### Community 633 - "Community 633"
Cohesion: 0.50 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 634 - "Community 634" ### Community 634 - "Community 634"
Cohesion: 0.25 Cohesion: 0.25
@@ -2721,13 +2705,21 @@ Cohesion: 0.43
Nodes (5): BeforeInstallPromptEvent, usePwaInstall(), PwaInstallBanner(), detectIOS(), PwaLoginCard() Nodes (5): BeforeInstallPromptEvent, usePwaInstall(), PwaInstallBanner(), detectIOS(), PwaLoginCard()
### Community 636 - "Community 636" ### Community 636 - "Community 636"
Cohesion: 0.67 Cohesion: 0.50
Nodes (3): 29. 🟢 `GET` clinic list 🆕, پارامترهای Query, پاسخ‌ها Nodes (4): Errors, GET `/api/v1/doctor/{uuid}`, Path Parameters, Response `200`
### Community 638 - "Community 638"
Cohesion: 0.50
Nodes (4): Errors, POST `/file/upload/clinic_pro/doctor/field_image`, Request, Response `200`
### Community 639 - "Community 639" ### Community 639 - "Community 639"
Cohesion: 0.33 Cohesion: 0.33
Nodes (6): GET /api/v1/sms/balance — موجودی حساب پیامک, POST /api/v1/sms/queue — افزودن به صف, ۴. سیستم حساب و صف پیامک, ۴.۱ حساب پیامک (SMS Account), ۴.۲ صف پیامک (SMS Queue), ۴.۳ API پیامک Nodes (6): GET /api/v1/sms/balance — موجودی حساب پیامک, POST /api/v1/sms/queue — افزودن به صف, ۴. سیستم حساب و صف پیامک, ۴.۱ حساب پیامک (SMS Account), ۴.۲ صف پیامک (SMS Queue), ۴.۳ API پیامک
### Community 640 - "Community 640"
Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/clinic-pro/doctor-address`, Request Body, Response `201`
### Community 646 - "Community 646" ### Community 646 - "Community 646"
Cohesion: 0.40 Cohesion: 0.40
Nodes (5): 35. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها Nodes (5): 35. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
@@ -2744,17 +2736,17 @@ Nodes (5): 31. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای
Cohesion: 0.40 Cohesion: 0.40
Nodes (5): 32. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها Nodes (5): 32. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 652 - "Community 652"
Cohesion: 0.50
Nodes (4): Errors, Path Parameters, POST `/api/v1/clinic-pro/doctor-address/from-clinic/{clinicUuid}`, Response `201`
### Community 653 - "Community 653" ### Community 653 - "Community 653"
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): 38. 🟢 `GET` Unapproved comments, هدرهای اضافی, پارامترهای Query, پاسخ‌ها Nodes (4): 38. 🟢 `GET` Unapproved comments, هدرهای اضافی, پارامترهای Query, پاسخ‌ها
### Community 654 - "Community 654" ### Community 654 - "Community 654"
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): 44. 🟢 `GET` list comment, هدرهای اضافی, پارامترهای Query, پاسخ‌ها Nodes (4): Errors, PATCH `/api/v1/insurance/{id}`, Request Body, Response `200`
### Community 655 - "Community 655"
Cohesion: 0.40
Nodes (5): 37. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 656 - "Community 656" ### Community 656 - "Community 656"
Cohesion: 0.40 Cohesion: 0.40
@@ -2764,30 +2756,18 @@ Nodes (5): ۲.۸ تنظیمات نوبت (Appointment Settings), ۲.۸.۱ برن
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): GET `/api/v1/admin/payments`, Payment Management, Query Parameters, Response `200` Nodes (4): GET `/api/v1/admin/payments`, Payment Management, Query Parameters, Response `200`
### Community 658 - "Community 658"
Cohesion: 0.67
Nodes (3): GET `/api/v1/clinic-pro/doctor-addresses/{doctorId}`, Path Parameters, Response `200`
### Community 659 - "Community 659" ### Community 659 - "Community 659"
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): GET `/api/v1/admin/secretaries`, Query Parameters, Response `200`, Secretary Management Nodes (4): GET `/api/v1/admin/secretaries`, Query Parameters, Response `200`, Secretary Management
### Community 660 - "Community 660"
Cohesion: 0.50
Nodes (4): 39. 🟡 `PATCH` Comment confirmation, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 661 - "Community 661"
Cohesion: 0.50
Nodes (4): 40. 🔵 `POST` post, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 662 - "Community 662" ### Community 662 - "Community 662"
Cohesion: 0.29 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` Nodes (7): Application Logs, DELETE `/api/v1/admin/logs`, GET `/api/v1/admin/logs`, Log Retention, Query Parameters, Response `200`, Response `200`
### Community 664 - "Community 664"
Cohesion: 0.50
Nodes (4): 45. 🔵 `POST` post, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 665 - "Community 665"
Cohesion: 0.50
Nodes (4): 46. 🟡 `PATCH` patch, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 666 - "Community 666" ### Community 666 - "Community 666"
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): GET /api/v1/appointment-settings/slots — دریافت اسلات‌های خالی, POST /api/v1/appointment-settings/holidays — ثبت تعطیلی (فقط ادمین), POST /api/v1/appointment-settings/overrides — ثبت Override توسط دکتر, Task-09: API تنظیمات نوبت Nodes (4): GET /api/v1/appointment-settings/slots — دریافت اسلات‌های خالی, POST /api/v1/appointment-settings/holidays — ثبت تعطیلی (فقط ادمین), POST /api/v1/appointment-settings/overrides — ثبت Override توسط دکتر, Task-09: API تنظیمات نوبت
@@ -2804,37 +2784,25 @@ Nodes (4): ۲.۱۳ نظرات، لایک و امتیازدهی, ۲.۱۳.۱ نظ
Cohesion: 0.50 Cohesion: 0.50
Nodes (4): GET `/api/v1/admin/settlements`, Query Parameters, Response `200`, Settlement Management Nodes (4): GET `/api/v1/admin/settlements`, Query Parameters, Response `200`, Settlement Management
### Community 675 - "Community 675"
Cohesion: 0.67
Nodes (3): 34. 🔵 `POST` image logo, هدرهای اضافی, پاسخ‌ها
### Community 677 - "Community 677"
Cohesion: 0.67
Nodes (3): 42. 🔴 `DELETE` delete, هدرهای اضافی, پاسخ‌ها
### Community 678 - "Community 678"
Cohesion: 0.67
Nodes (3): 43. 🟢 `GET` get, هدرهای اضافی, پاسخ‌ها
## Knowledge Gaps ## Knowledge Gaps
- **3644 isolated node(s):** `ALLOWED_ROLES`, `Pricing`, `TenantInsurance`, `CoverageRow`, `Draft` (+3639 more) - **3644 isolated node(s):** `ALLOWED_ROLES`, `Pricing`, `TenantInsurance`, `CoverageRow`, `Draft` (+3639 more)
These have ≤1 connection - possible missing edges or undocumented components. These have ≤1 connection - possible missing edges or undocumented components.
- **131 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. - **134 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions ## Suggested Questions
_Questions this graph is uniquely positioned to answer:_ _Questions this graph is uniquely positioned to answer:_
- **Why does `BaseController` connect `Community 108` to `Community 6`, `Community 138`, `Community 139`, `Community 14`, `Community 15`, `Community 275`, `Community 20`, `Community 22`, `Community 26`, `Community 164`, `Community 295`, `Community 300`, `Community 301`, `Community 175`, `Community 176`, `Community 177`, `Community 58`, `Community 59`, `Community 63`, `Community 64`, `Community 70`, `Community 71`, `Community 75`, `Community 206`, `Community 352`, `Community 230`, `Community 103`, `Community 104`, `Community 107`, `Community 491`, `Community 109`, `Community 121`, `Community 122`, `Community 252`?** - **Why does `BaseController` connect `Community 108` to `Community 4`, `Community 6`, `Community 138`, `Community 139`, `Community 14`, `Community 15`, `Community 275`, `Community 20`, `Community 22`, `Community 26`, `Community 164`, `Community 295`, `Community 300`, `Community 301`, `Community 175`, `Community 176`, `Community 177`, `Community 58`, `Community 59`, `Community 63`, `Community 64`, `Community 70`, `Community 71`, `Community 75`, `Community 206`, `Community 230`, `Community 103`, `Community 104`, `Community 107`, `Community 109`, `Community 121`, `Community 122`, `Community 252`?**
_High betweenness centrality (0.030) - this node is a cross-community bridge._ _High betweenness centrality (0.032) - this node is a cross-community bridge._
- **Why does `AppointmentRepository` connect `Community 119` to `Community 53`?** - **Why does `AppointmentRepository` connect `Community 119` to `Community 53`?**
_High betweenness centrality (0.022) - this node is a cross-community bridge._ _High betweenness centrality (0.021) - this node is a cross-community bridge._
- **Why does `Version20260614181657` connect `Community 431` to `Community 404`?** - **Why does `Version20260614181657` connect `Community 431` to `Community 400`?**
_High betweenness centrality (0.015) - this node is a cross-community bridge._ _High betweenness centrality (0.015) - this node is a cross-community bridge._
- **What connects `ALLOWED_ROLES`, `Pricing`, `TenantInsurance` to the rest of the system?** - **What connects `ALLOWED_ROLES`, `Pricing`, `TenantInsurance` to the rest of the system?**
_3644 weakly-connected nodes found - possible documentation gaps or missing edges._ _3644 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `Community 0` be split into smaller, more focused modules?** - **Should `Community 0` be split into smaller, more focused modules?**
_Cohesion score 0.05137844611528822 - nodes in this community are weakly interconnected._ _Cohesion score 0.054426705370101594 - nodes in this community are weakly interconnected._
- **Should `Community 1` be split into smaller, more focused modules?** - **Should `Community 1` be split into smaller, more focused modules?**
_Cohesion score 0.028985507246376812 - 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?** - **Should `Community 2` be split into smaller, more focused modules?**
_Cohesion score 0.07692307692307693 - nodes in this community are weakly interconnected._ _Cohesion score 0.06565656565656566 - nodes in this community are weakly interconnected._
@@ -0,0 +1 @@
{"nodes": [], "edges": [], "skipped": "data json (non-object root)"}
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
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
+521 -479
View File
File diff suppressed because it is too large Load Diff
+12 -12
View File
@@ -345,8 +345,8 @@
"semantic_hash": "" "semantic_hash": ""
}, },
"assets/admin/pages/SettingsPage.tsx": { "assets/admin/pages/SettingsPage.tsx": {
"mtime": 1782894003.7974715, "mtime": 1782974557.7457983,
"ast_hash": "2916e104ddce46b458010eb2160bfb9a", "ast_hash": "e0b1c6e11b841e8c8bc367c2380663af",
"semantic_hash": "" "semantic_hash": ""
}, },
"assets/admin/pages/SettlementDetailPage.tsx": { "assets/admin/pages/SettlementDetailPage.tsx": {
@@ -1150,8 +1150,8 @@
"semantic_hash": "" "semantic_hash": ""
}, },
"src/Config/Controller/SiteConfigController.php": { "src/Config/Controller/SiteConfigController.php": {
"mtime": 1782929760.8594074, "mtime": 1782974471.6251059,
"ast_hash": "1a0cbe1845407beebacb2eba7d07024a", "ast_hash": "6bec4d13bccff8d60ceee16d65e6c71c",
"semantic_hash": "" "semantic_hash": ""
}, },
"src/Config/Entity/SiteConfig.php": { "src/Config/Entity/SiteConfig.php": {
@@ -1360,8 +1360,8 @@
"semantic_hash": "" "semantic_hash": ""
}, },
"src/Payment/Controller/PaymentController.php": { "src/Payment/Controller/PaymentController.php": {
"mtime": 1782896983.4736924, "mtime": 1782974625.5218852,
"ast_hash": "da4dadd9532dda783eb589c368f18801", "ast_hash": "1d84377c36b7d689201bc5324a2a0731",
"semantic_hash": "" "semantic_hash": ""
}, },
"src/Payment/Entity/Payment.php": { "src/Payment/Entity/Payment.php": {
@@ -2340,8 +2340,8 @@
"semantic_hash": "" "semantic_hash": ""
}, },
"docs/api/admin.md": { "docs/api/admin.md": {
"mtime": 1782932869.818139, "mtime": 1782974658.9906943,
"ast_hash": "27318238aa2741292c79a491870ba31b", "ast_hash": "5715227d2011fce8439a74c3d3324e20",
"semantic_hash": "" "semantic_hash": ""
}, },
"docs/api/appointment-settings.md": { "docs/api/appointment-settings.md": {
@@ -2415,8 +2415,8 @@
"semantic_hash": "" "semantic_hash": ""
}, },
"docs/api/payment.md": { "docs/api/payment.md": {
"mtime": 1782897235.6571848, "mtime": 1782974640.9762948,
"ast_hash": "839fec75d0238c39881d9339c26ad43e", "ast_hash": "fc916697880a8f302f4766d0a071c679",
"semantic_hash": "" "semantic_hash": ""
}, },
"docs/api/rating.md": { "docs/api/rating.md": {
@@ -3430,8 +3430,8 @@
"semantic_hash": "" "semantic_hash": ""
}, },
"data/seed/cities.json": { "data/seed/cities.json": {
"mtime": 1782973838.4322407, "mtime": 1782974609.7399116,
"ast_hash": "089a1a2c29c7dafdc0f279e72c23f556", "ast_hash": "a3210b7dbfa06d151018197534694ded",
"semantic_hash": "" "semantic_hash": ""
}, },
"data/seed/doctor_services.json": { "data/seed/doctor_services.json": {
@@ -32,9 +32,11 @@ class SiteConfigController extends BaseController
// payment gateways // payment gateways
'payment_test_mode', 'payment_test_mode',
'payment_allowed_frontend_hosts', 'payment_allowed_frontend_hosts',
'mellat_enabled',
'mellat_terminal_id', 'mellat_terminal_id',
'mellat_username', 'mellat_username',
'mellat_password', 'mellat_password',
'sep_enabled',
'sep_terminal_id', 'sep_terminal_id',
]; ];
+15 -4
View File
@@ -180,7 +180,7 @@ class PaymentController extends BaseController
$gateway = $this->resolveGateway($gatewayName); $gateway = $this->resolveGateway($gatewayName);
if ($gateway === null) { if ($gateway === null) {
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'درگاه پرداخت نامعتبر است', 422, 'gateway'); return $this->error(ErrorCodes::ERR_VALIDATION_001, 'درگاه پرداخت نامعتبر یا غیرفعال است', 422, 'gateway');
} }
if ($this->circuitBreaker->isOpen($gatewayName)) { if ($this->circuitBreaker->isOpen($gatewayName)) {
@@ -428,7 +428,7 @@ class PaymentController extends BaseController
$gateway = $this->resolveGateway($gatewayName); $gateway = $this->resolveGateway($gatewayName);
if ($gateway === null) { if ($gateway === null) {
return $this->error(ErrorCodes::ERR_VALIDATION_001, 'درگاه پرداخت نامعتبر است', 422, 'gateway'); return $this->error(ErrorCodes::ERR_VALIDATION_001, 'درگاه پرداخت نامعتبر یا غیرفعال است', 422, 'gateway');
} }
if ($this->circuitBreaker->isOpen($gatewayName)) { if ($this->circuitBreaker->isOpen($gatewayName)) {
@@ -567,8 +567,8 @@ class PaymentController extends BaseController
$labels = ['mellat' => 'بانک ملت', 'sep' => 'سپ (سامان کیش)']; $labels = ['mellat' => 'بانک ملت', 'sep' => 'سپ (سامان کیش)'];
$gateways = []; $gateways = [];
foreach ([$this->mellat, $this->sep] as $gateway) { foreach ([$this->mellat, $this->sep] as $gateway) {
if ($gateway->isConfigured()) { $name = $gateway->getName();
$name = $gateway->getName(); if ($gateway->isConfigured() && $this->isGatewayEnabled($name)) {
$gateways[] = ['name' => $name, 'label' => $labels[$name] ?? $name]; $gateways[] = ['name' => $name, 'label' => $labels[$name] ?? $name];
} }
} }
@@ -616,6 +616,10 @@ class PaymentController extends BaseController
return $this->mock; return $this->mock;
} }
if (!$this->isGatewayEnabled($name)) {
return null;
}
return match ($name) { return match ($name) {
'mellat' => $this->mellat, 'mellat' => $this->mellat,
'sep' => $this->sep, 'sep' => $this->sep,
@@ -623,6 +627,13 @@ class PaymentController extends BaseController
}; };
} }
/** آیا این درگاه در تنظیمات فعال است؟ کلید تنظیم‌نشده = فعال (سازگاری با نصب‌های قبلی). */
private function isGatewayEnabled(string $name): bool
{
$v = $this->configRepo->get($name . '_enabled');
return $v === null || $v === '1';
}
/** @return string[] allowed frontend hosts — from SiteConfig, falling back to env. */ /** @return string[] allowed frontend hosts — from SiteConfig, falling back to env. */
private function allowedHosts(): array private function allowedHosts(): array
{ {