feat: Add City entity methods and migration for title field

- Created a new JSON file for the City entity's AST representation, detailing its methods and properties.
- Added a migration to alter the cities table by adding a nullable title column.
This commit is contained in:
hamed
2026-07-08 12:19:06 +03:30
parent 94541ad609
commit ccbb1d0b1f
25 changed files with 1328 additions and 925 deletions
+59 -30
View File
@@ -19,7 +19,7 @@
## فایل‌های مرتبط
| فایل | نقش |
|------|-----|
| ---------------------------------------------------- | ------------------------------------------------------------------------------- |
| `clinicpro/templates/public/home.html.twig` | کل HTML صفحه + JS inline منو/اسکرول (تک‌فایل، extends نمی‌کند) |
| `clinicpro/assets/home/styles.css` | تمام استایل صفحه، شامل `@media (max-width:1000px)` و `@media (max-width:640px)` |
| `clinicpro/src/Shared/Controller/HomeController.php` | فقط `return $this->render('public/home.html.twig')`**نیازی به تغییر ندارد** |
@@ -38,7 +38,10 @@
```html
<!-- Hero — خط ۴۸ تا ۵۲ -->
<h1 class="reveal">نوبت، پرونده و حساب مطب،<br />همه یک‌جا</h1>
<p class="reveal d1">کلینیک پرو کارهای روزمره‌ی مطب را سر و سامان می‌دهد؛ از نوبت‌دهی و پرونده‌ی بیمار تا فاکتور و گزارش مالی. دیگر خبری از دفتر نوبت و کاغذبازی نیست.</p>
<p class="reveal d1">
کلینیک پرو کارهای روزمره‌ی مطب را سر و سامان می‌دهد؛ از نوبت‌دهی و پرونده‌ی
بیمار تا فاکتور و گزارش مالی. دیگر خبری از دفتر نوبت و کاغذبازی نیست.
</p>
<button class="btn btn-coral" id="openRegModal2">ثبت نام دکتر / کلینیک</button>
<a href="#contact" class="btn btn-blue">تماس با ما</a>
```
@@ -46,13 +49,22 @@
```html
<!-- Feature columns — خط ۱۴۲ تا ۱۶۹ (۴ ستون) -->
<h3>پرونده‌ی بیمار</h3>
<p>سابقه، نسخه و آزمایش هر بیمار جای خودش است و هر وقت لازم شد، چند ثانیه‌ای پیدایش می‌کنید.</p>
<p>
سابقه، نسخه و آزمایش هر بیمار جای خودش است و هر وقت لازم شد، چند ثانیه‌ای
پیدایش می‌کنید.
</p>
<!-- ... نوبت‌دهی آنلاین / حساب و کتاب / +۵۰۰ مطب -->
```
```html
<!-- Why icon row — خط ۱۸۱ تا ۲۰۳ -->
<h3>راه‌اندازی با شما</h3> ... <h3>پشتیبانی همیشگی</h3> ... <h3>متناسب با مطب ایرانی</h3> ... <h3>گزارش‌گیری دقیق</h3>
<h3>راه‌اندازی با شما</h3>
...
<h3>پشتیبانی همیشگی</h3>
...
<h3>متناسب با مطب ایرانی</h3>
...
<h3>گزارش‌گیری دقیق</h3>
```
```html
@@ -73,7 +85,7 @@
- **همه‌ی** بخش‌های متنی صفحه را پوشش بده: nav، hero، feature columns، why band، devices، specialties (`پزشک عمومی`/`دندان‌پزشک`/`متخصص پوست`/`متخصص اطفال` و دو tick هرکدام)، app/desktop CTA (`کاملاً ایمن`/`نصب آسان`/`آپدیت رایگان`)، modal ثبت‌نام (`دکتر هستم`/...)، footer.
- اعداد و ادعاها را **باورپذیر** نگه‌دار (`+۵۰۰ مطب`, `۹۵٪ رضایت` می‌توانند بمانند یا کمی پانچی‌تر شوند، اما اغراق بی‌پایه نکن).
- آدرس/تلفن/ایمیل footer (`۰۷۴۹۱۰۱۲۱۷۸`، `info@clinic-pro.ir`، آدرس یاسوج) **دست‌نخورده** بماند.
- آدرس/تلفن/ایمیل footer (`02191550875`، `info@clinic-pro.ir`، آدرس یاسوج) **دست‌نخورده** بماند.
- لینک‌ها و `href`ها (`#hero`, `#features`, `/admin`, action مودال) عوض نشوند.
---
@@ -88,8 +100,16 @@
```html
<div class="nav-right">
<button class="nav-burger nav-toggle" id="navToggle" aria-label="منو">...</button>
<button class="btn btn-ghost" id="openRegModal" style="font-size:13px;padding:8px 20px">ثبت نام</button>
<button class="nav-burger nav-toggle" id="navToggle" aria-label="منو">
...
</button>
<button
class="btn btn-ghost"
id="openRegModal"
style="font-size:13px;padding:8px 20px"
>
ثبت نام
</button>
<a href="/admin" class="btn btn-blue" style="...">ورود به پنل</a>
</div>
```
@@ -98,15 +118,22 @@
```css
@media (max-width: 640px) {
.nav-right #openRegModal { display: none; } /* در منوی موبایل می‌آید */
.nav-right { gap: 10px; }
.brand small { display: none; } /* «مدیریت مطب» را جا باز کن */
.nav-right #openRegModal {
display: none;
} /* در منوی موبایل می‌آید */
.nav-right {
gap: 10px;
}
.brand small {
display: none;
} /* «مدیریت مطب» را جا باز کن */
}
```
### مشکل ۲٫۲ — منوی موبایل با inline-style شکننده باز می‌شود و بسته نمی‌شود
در `home.html.twig` خط ۷۵۶ تا ۷۷۲، توگل منو با ست‌کردن مستقیم `navLinks.style.*` کار می‌کند (position/background/... دستی). این روش:
- با کلیک روی آیتم منو بسته نمی‌شود،
- دکمه‌های ثبت‌نام/ورود را شامل نمی‌شود،
- شکننده است.
@@ -114,21 +141,21 @@
**وضعیت فعلی:**
```js
var navToggle = document.getElementById('navToggle');
var navLinks = document.getElementById('navLinks');
var navToggle = document.getElementById("navToggle");
var navLinks = document.getElementById("navLinks");
if (navToggle)
navToggle.addEventListener('click', function () {
var open = navLinks.style.display === 'flex';
navLinks.style.display = open ? '' : 'flex';
navToggle.addEventListener("click", function () {
var open = navLinks.style.display === "flex";
navLinks.style.display = open ? "" : "flex";
if (!open) {
navLinks.style.position = 'absolute';
navLinks.style.top = '84px';
navLinks.style.insetInline = '0';
navLinks.style.flexDirection = 'column';
navLinks.style.background = '#fff';
navLinks.style.padding = '20px 32px';
navLinks.style.gap = '18px';
navLinks.style.boxShadow = '0 16px 30px oklch(0.4 0.08 285 / 0.1)';
navLinks.style.position = "absolute";
navLinks.style.top = "84px";
navLinks.style.insetInline = "0";
navLinks.style.flexDirection = "column";
navLinks.style.background = "#fff";
navLinks.style.padding = "20px 32px";
navLinks.style.gap = "18px";
navLinks.style.boxShadow = "0 16px 30px oklch(0.4 0.08 285 / 0.1)";
}
});
```
@@ -138,14 +165,14 @@ if (navToggle)
JS تمیزتر:
```js
var navToggle = document.getElementById('navToggle');
var navLinks = document.getElementById('navLinks');
var navToggle = document.getElementById("navToggle");
var navLinks = document.getElementById("navLinks");
if (navToggle) {
navToggle.addEventListener('click', function () {
navLinks.classList.toggle('open');
navToggle.addEventListener("click", function () {
navLinks.classList.toggle("open");
});
navLinks.addEventListener('click', function (e) {
if (e.target.tagName === 'A') navLinks.classList.remove('open');
navLinks.addEventListener("click", function (e) {
if (e.target.tagName === "A") navLinks.classList.remove("open");
});
}
```
@@ -154,7 +181,9 @@ CSS متناظر در `styles.css` داخل `@media (max-width:640px)` (پنل d
```css
@media (max-width: 640px) {
.nav-links { display: none; }
.nav-links {
display: none;
}
.nav-links.open {
display: flex;
position: absolute;
+7
View File
@@ -371,6 +371,7 @@ function ProvincesTab() {
const citySchema = z.object({
name: z.string().min(1, 'نام الزامی است'),
site_name: z.string().optional(),
title: z.string().optional(),
province_id: z.number().nullable().optional(),
weight: z.string().optional(),
status: z.string().optional(),
@@ -438,6 +439,7 @@ function CitiesTab() {
province_id: d.province_id ?? null,
representation_id: d.representation_id ?? null,
...(d.site_name?.trim() && { site_name: d.site_name.trim() }),
...(d.title?.trim() && { title: d.title.trim() }),
...(d.contact_phone?.trim() && { contact_phone: d.contact_phone.trim() }),
...(d.email?.trim() && { email: d.email.trim() }),
...(d.description?.trim() && { description: d.description.trim() }),
@@ -470,6 +472,7 @@ function CitiesTab() {
reset({
name: c.name, weight: String(c.weight), status: String(c.status),
site_name: c.site_name ?? '',
title: c.title ?? '',
province_id: c.province_id ?? null,
representation_id: c.representation_id ?? null,
contact_phone: c.contact_phone ?? '',
@@ -519,6 +522,10 @@ function CitiesTab() {
<label>نام سایت</label>
<input {...register('site_name')} className="input" placeholder="مثال: یزد نوبت" />
</div>
<div className="form-row" style={{ marginTop: 12 }}>
<label>عنوان سئو (title)</label>
<input {...register('title')} className="input" placeholder="مثال: نوبت‌دهی آنلاین پزشکان یزد | یزد نوبت" />
</div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginTop: 12 }}>
<div className="form-row">
<label>استان</label>
+1
View File
@@ -239,6 +239,7 @@ export interface City {
uuid: string;
name: string;
site_name?: string | null;
title?: string | null;
status: number;
weight: number;
province_id: number | null;
+102 -102
View File
@@ -4,7 +4,7 @@
"uuid": "7bfba4b5-646b-11f1-84d7-f26ca1845824",
"name": "اراک",
"site_name": "اراک نوبت",
"title": "نوبت‌دهی آنلاین پزشکان اراک | رزرو نوبت دکتر",
"title": "نوبت‌دهی آنلاین پزشکان اراک | اراک نوبت",
"status": 1,
"weight": 0,
"province_id": 28,
@@ -13,9 +13,9 @@
"contact_phone": "+98 086 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت اراک، آنلاین از پزشکان متخصص و عمومی استان مرکزی نوبت بگیرید. جست‌وجوی دکتر بر اساس تخصص، بیمه و منطقه در اراک و رزرو نوبت بدون مراجعه حضوری.",
"slogan": "در اراک، نوبت دکتر فقط با چند کلیک",
"slogan": "نوبت دکتر اراک، ساده، سریع، آنلاین",
"domain": "arak-nobat.ir",
"keywords": "نوبت اراک, دکتر اراک, پزشک متخصص اراک, رزرو نوبت اینترنتی اراک, کلینیک اراک, بهترین پزشک استان مرکزی, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر اراک, نوبت‌دهی آنلاین اراک, دکتر خوب اراک, پزشک متخصص اراک, رزرو نوبت پزشک اراک, نوبت اینترنتی دکتر اراک, نوبت آنلاین استان مرکزی, اراک نوبت",
"footer_description": "نوبت اراک، مرجع نوبت‌دهی آنلاین پزشکان و مراکز درمانی استان مرکزی است و رزرو نوبت را برای شهروندان اراک ساده می‌کند.",
"social_media": {
"instagram": "arak_nobat",
@@ -29,7 +29,7 @@
"uuid": "7bfb6d65-646b-11f1-84d7-f26ca1845824",
"name": "اردبیل",
"site_name": "اردبیل نوبت",
"title": "رزرو نوبت اینترنتی پزشک اردبیل | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان اردبیل | اردبیل نوبت",
"status": 1,
"weight": 0,
"province_id": 3,
@@ -38,9 +38,9 @@
"contact_phone": "+98 045 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت اردبیل، سریع‌ترین راه رزرو نوبت پزشکان اردبیل است. بدون صف و اتلاف وقت، دکتر متخصص خود را انتخاب کنید و نوبت آنلاین بگیرید؛ ۲۴ساعته و در دسترس.",
"slogan": "نوبت پزشک اردبیل، بدون صف و اتلاف وقت",
"slogan": "نوبت پزشک اردبیل، هر ساعت که بخواهید",
"domain": "ardabil-nobat.ir",
"keywords": "نوبت اردبیل, دکتر اردبیل, رزرو نوبت پزشک اردبیل, نوبت آنلاین اردبیل, کلینیک اردبیل, متخصصین اردبیل, نوبت اینترنتی دکتر",
"keywords": "نوبت دکتر اردبیل, نوبت‌دهی آنلاین اردبیل, دکتر خوب اردبیل, پزشک متخصص اردبیل, رزرو نوبت پزشک اردبیل, نوبت اینترنتی دکتر اردبیل, بیمارستان اردبیل, اردبیل نوبت",
"footer_description": "نوبت اردبیل، سامانه‌ای برای رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان اردبیل، بدون نیاز به مراجعه حضوری.",
"social_media": {
"instagram": "ardabil_nobat",
@@ -54,7 +54,7 @@
"uuid": "7bfb6ac3-646b-11f1-84d7-f26ca1845824",
"name": "ارومیه",
"site_name": "ارومیه نوبت",
"title": "نوبت دکتر ارومیه | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان ارومیه | ارومیه نوبت",
"status": 1,
"weight": 0,
"province_id": 2,
@@ -63,9 +63,9 @@
"contact_phone": "+98 044 33333333",
"email": "nobat724@gmail.com",
"description": "در ارومیه آنلاین نوبت بگیرید؛ نوبت ارومیه دسترسی به پزشکان متخصص و عمومی آذربایجان غربی را فراهم می‌کند. جست‌وجوی دکتر و رزرو نوبت در سریع‌ترین زمان.",
"slogan": "نوبت پزشک ارومیه، در سریع‌ترین زمان",
"slogan": "پزشکان ارومیه، یک کلیک تا ویزیت",
"domain": "urmia-nobat.ir",
"keywords": "نوبت ارومیه, دکتر ارومیه, پزشک متخصص ارومیه, رزرو نوبت اینترنتی ارومیه, کلینیک ارومیه, درمانگاه ارومیه, نوبت آنلاین آذربایجان غربی",
"keywords": "نوبت دکتر ارومیه, نوبت‌دهی آنلاین ارومیه, دکتر خوب ارومیه, پزشک متخصص ارومیه, رزرو نوبت پزشک ارومیه, نوبت اینترنتی دکتر ارومیه, نوبت آنلاین آذربایجان غربی, ارومیه نوبت",
"footer_description": "نوبت ارومیه، همراه شهروندان آذربایجان غربی برای رزرو آنلاین نوبت پزشکان و مراکز درمانی ارومیه در مسیر سلامت.",
"social_media": {
"instagram": "urmia_nobat",
@@ -79,7 +79,7 @@
"uuid": "7bfb6f78-646b-11f1-84d7-f26ca1845824",
"name": "اصفهان",
"site_name": "اصفهان نوبت",
"title": "نوبت‌دهی آنلاین پزشکان اصفهان | رزرو نوبت دکتر",
"title": "نوبت‌دهی آنلاین پزشکان اصفهان | اصفهان نوبت",
"status": 1,
"weight": 0,
"province_id": 4,
@@ -88,9 +88,9 @@
"contact_phone": "+98 031 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت اصفهان از بهترین پزشکان نصف‌جهان آنلاین نوبت بگیرید. جست‌وجو در شبکه متخصصان و بیمارستان‌های اصفهان و رزرو نوبت در کمتر از یک دقیقه.",
"slogan": "بهترین پزشکان اصفهان، تنها با چند کلیک",
"slogan": "پزشکان اصفهان، یک کلیک تا سلامتی",
"domain": "esf-nobat.ir",
"keywords": "نوبت اصفهان, دکتر اصفهان, پزشک متخصص اصفهان, رزرو نوبت اینترنتی اصفهان, بیمارستان اصفهان, کلینیک اصفهان, نوبت آنلاین نصف جهان",
"keywords": "نوبت دکتر اصفهان, نوبت‌دهی آنلاین اصفهان, دکتر خوب اصفهان, پزشک متخصص اصفهان, رزرو نوبت پزشک اصفهان, نوبت اینترنتی دکتر اصفهان, بیمارستان اصفهان, اصفهان نوبت",
"footer_description": "نوبت اصفهان، دروازه دسترسی به شبکه پزشکان و بیمارستان‌های استان اصفهان برای رزرو آنلاین و سریع نوبت.",
"social_media": {
"instagram": "esfahan_nobat",
@@ -104,7 +104,7 @@
"uuid": "7bfb8171-646b-11f1-84d7-f26ca1845824",
"name": "اهواز",
"site_name": "اهواز نوبت",
"title": "رزرو نوبت اینترنتی پزشک اهواز | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان اهواز | اهواز نوبت",
"status": 1,
"weight": 0,
"province_id": 13,
@@ -113,9 +113,9 @@
"contact_phone": "+98 061 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت اهواز، آنلاین از پزشکان متخصص و عمومی خوزستان نوبت بگیرید. جست‌وجوی دکتر بر اساس تخصص، بیمه و منطقه در اهواز؛ رزرو ۲۴ساعته بدون مراجعه حضوری.",
"slogan": "در اهواز، نوبت دکتر فقط با چند کلیک",
"slogan": "سلامت اهواز، بدون صف و انتظار",
"domain": "ahvaz-nobat.ir",
"keywords": "نوبت اهواز, دکتر اهواز, پزشک متخصص اهواز, رزرو نوبت اینترنتی اهواز, کلینیک اهواز, بیمارستان اهواز, نوبت آنلاین خوزستان",
"keywords": "نوبت دکتر اهواز, نوبت‌دهی آنلاین اهواز, دکتر خوب اهواز, پزشک متخصص اهواز, رزرو نوبت پزشک اهواز, نوبت اینترنتی دکتر اهواز, نوبت آنلاین خوزستان, اهواز نوبت",
"footer_description": "نوبت اهواز، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی خوزستان است و دسترسی سریع به متخصصان اهواز را ممکن می‌کند.",
"social_media": {
"instagram": "ahvaz_nobat",
@@ -129,7 +129,7 @@
"uuid": "7bfb738a-646b-11f1-84d7-f26ca1845824",
"name": "ایلام",
"site_name": "ایلام نوبت",
"title": "نوبت دکتر ایلام | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان ایلام | ایلام نوبت",
"status": 1,
"weight": 0,
"province_id": 6,
@@ -138,9 +138,9 @@
"contact_phone": "+98 084 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت ایلام، اولین سامانه تخصصی نوبت‌دهی پزشکی استان ایلام است. پزشک را بر اساس تخصص انتخاب کنید و نوبت آنلاین بگیرید؛ آسان، سریع و ۲۴ساعته.",
"slogan": "نوبت پزشک ایلام، آسان و بدون مراجعه حضوری",
"slogan": "پزشک ایلام، همیشه در دسترس شما",
"domain": "ilam-nobat.ir",
"keywords": "نوبت ایلام, دکتر ایلام, پزشک متخصص ایلام, رزرو نوبت اینترنتی ایلام, کلینیک ایلام, درمانگاه ایلام, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر ایلام, نوبت‌دهی آنلاین ایلام, دکتر خوب ایلام, پزشک متخصص ایلام, رزرو نوبت پزشک ایلام, نوبت اینترنتی دکتر ایلام, بیمارستان ایلام, ایلام نوبت",
"footer_description": "نوبت ایلام، سامانه جامع نوبت‌دهی آنلاین پزشکان و مراکز درمانی استان ایلام برای شهروندان ایلامی.",
"social_media": {
"instagram": "ilam_nobat",
@@ -154,7 +154,7 @@
"uuid": "7bfb7f73-646b-11f1-84d7-f26ca1845824",
"name": "بجنورد",
"site_name": "بجنورد نوبت",
"title": "نوبت‌دهی آنلاین پزشکان بجنورد | رزرو نوبت",
"title": "نوبت‌دهی آنلاین پزشکان بجنورد | بجنورد نوبت",
"status": 1,
"weight": 0,
"province_id": 12,
@@ -163,9 +163,9 @@
"contact_phone": "+98 058 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت بجنورد، رزرو آنلاین نوبت پزشکان و مراکز درمانی خراسان شمالی را ساده می‌کند. با انتخاب دکتر و ثبت نوبت اینترنتی، در وقت و هزینه صرفه‌جویی کنید.",
"slogan": "نوبت پزشک بجنورد، تنها با چند کلیک",
"slogan": "نوبت دکتر بجنورد، ساده مثل یک کلیک",
"domain": "bojnord-nobat.ir",
"keywords": "نوبت بجنورد, دکتر بجنورد, پزشک متخصص بجنورد, رزرو نوبت اینترنتی بجنورد, کلینیک بجنورد, نوبت آنلاین خراسان شمالی, مطب بجنورد",
"keywords": "نوبت دکتر بجنورد, نوبت‌دهی آنلاین بجنورد, دکتر خوب بجنورد, پزشک متخصص بجنورد, رزرو نوبت پزشک بجنورد, نوبت اینترنتی دکتر بجنورد, نوبت آنلاین خراسان شمالی, بجنورد نوبت",
"footer_description": "نوبت بجنورد، همراه مردم خراسان شمالی برای رزرو هوشمند و آنلاین نوبت از پزشکان و مراکز درمانی بجنورد.",
"social_media": {
"instagram": "bojnord_nobat",
@@ -179,7 +179,7 @@
"uuid": "7bfba6b9-646b-11f1-84d7-f26ca1845824",
"name": "بندرعباس",
"site_name": "بندرعباس نوبت",
"title": "رزرو نوبت اینترنتی پزشک بندرعباس | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان بندرعباس | بندرعباس نوبت",
"status": 1,
"weight": 0,
"province_id": 29,
@@ -188,9 +188,9 @@
"contact_phone": "+98 076 33333333",
"email": "nobat724@gmail.com",
"description": "در بندرعباس آنلاین نوبت بگیرید؛ نوبت بندرعباس دسترسی به پزشکان متخصص و عمومی هرمزگان را فراهم می‌کند. جست‌وجوی دکتر و رزرو نوبت بدون مراجعه حضوری.",
"slogan": "نوبت دکتر بندرعباس، ساده و آنلاین",
"slogan": "نوبت پزشک بندرعباس، ۲۴ساعته آنلاین",
"domain": "bandar-nobat.ir",
"keywords": "نوبت بندرعباس, دکتر بندرعباس, پزشک متخصص بندرعباس, رزرو نوبت اینترنتی بندرعباس, کلینیک بندرعباس, نوبت آنلاین هرمزگان, بیمارستان بندرعباس",
"keywords": "نوبت دکتر بندرعباس, نوبت‌دهی آنلاین بندرعباس, دکتر خوب بندرعباس, پزشک متخصص بندرعباس, رزرو نوبت پزشک بندرعباس, نوبت اینترنتی دکتر بندرعباس, نوبت آنلاین هرمزگان, بندرعباس نوبت",
"footer_description": "نوبت بندرعباس، مرجع نوبت‌دهی آنلاین پزشکان و مراکز درمانی استان هرمزگان برای شهروندان بندرعباس.",
"social_media": {
"instagram": "bandarabbas_nobat",
@@ -204,7 +204,7 @@
"uuid": "7bfb7583-646b-11f1-84d7-f26ca1845824",
"name": "بوشهر",
"site_name": "بوشهر نوبت",
"title": "نوبت دکتر بوشهر | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان بوشهر | بوشهر نوبت",
"status": 1,
"weight": 0,
"province_id": 7,
@@ -213,9 +213,9 @@
"contact_phone": "+98 077 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت بوشهر، سریع‌ترین راه رزرو نوبت پزشکان بوشهر است. دکتر متخصص یا عمومی خود را انتخاب کنید و نوبت اینترنتی بگیرید؛ ۲۴ساعته و بدون صف.",
"slogan": "نوبت پزشک بوشهر، بدون صف و انتظار",
"slogan": "نوبت دکتر بوشهر، سریع و بدون انتظار",
"domain": "bushehr-nobat.ir",
"keywords": "نوبت بوشهر, دکتر بوشهر, پزشک متخصص بوشهر, رزرو نوبت اینترنتی بوشهر, کلینیک بوشهر, درمانگاه بوشهر, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر بوشهر, نوبت‌دهی آنلاین بوشهر, دکتر خوب بوشهر, پزشک متخصص بوشهر, رزرو نوبت پزشک بوشهر, نوبت اینترنتی دکتر بوشهر, بیمارستان بوشهر, بوشهر نوبت",
"footer_description": "نوبت بوشهر، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان بوشهر بدون نیاز به مراجعه حضوری.",
"social_media": {
"instagram": "bushehr_nobat",
@@ -229,7 +229,7 @@
"uuid": "7bfb7b9b-646b-11f1-84d7-f26ca1845824",
"name": "بیرجند",
"site_name": "بیرجند نوبت",
"title": "نوبت‌دهی آنلاین پزشکان بیرجند | رزرو نوبت",
"title": "نوبت‌دهی آنلاین پزشکان بیرجند | بیرجند نوبت",
"status": 1,
"weight": 0,
"province_id": 10,
@@ -238,9 +238,9 @@
"contact_phone": "+98 056 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت بیرجند، آنلاین از پزشکان متخصص و عمومی خراسان جنوبی نوبت بگیرید. جست‌وجوی دکتر و رزرو نوبت اینترنتی در بیرجند، ساده و در دسترس.",
"slogan": "نوبت دکتر بیرجند، آسان و اینترنتی",
"slogan": "دکتر بیرجند، آنلاین در جیب شما",
"domain": "birjand-nobat.ir",
"keywords": "نوبت بیرجند, دکتر بیرجند, پزشک متخصص بیرجند, رزرو نوبت اینترنتی بیرجند, کلینیک بیرجند, نوبت آنلاین خراسان جنوبی, مطب بیرجند",
"keywords": "نوبت دکتر بیرجند, نوبت‌دهی آنلاین بیرجند, دکتر خوب بیرجند, پزشک متخصص بیرجند, رزرو نوبت پزشک بیرجند, نوبت اینترنتی دکتر بیرجند, نوبت آنلاین خراسان جنوبی, بیرجند نوبت",
"footer_description": "نوبت بیرجند، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان خراسان جنوبی برای شهروندان بیرجند.",
"social_media": {
"instagram": "birjand_nobat",
@@ -254,7 +254,7 @@
"uuid": "7bfb684b-646b-11f1-84d7-f26ca1845824",
"name": "تبریز",
"site_name": "تبریز نوبت",
"title": "رزرو نوبت اینترنتی پزشک تبریز | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان تبریز | تبریز نوبت",
"status": 1,
"weight": 0,
"province_id": 1,
@@ -263,9 +263,9 @@
"contact_phone": "+98 041 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت تبریز، سامانه تخصصی نوبت‌دهی پزشکی شمال‌غرب کشور است. از پزشکان متخصص و مراکز درمانی معتبر تبریز، در هر ساعت شبانه‌روز آنلاین نوبت بگیرید.",
"slogan": "سریع‌ترین نوبت‌دهی پزشکی تبریز",
"slogan": "نوبت دکتر در تبریز، ساده‌تر از همیشه",
"domain": "tabriz-nobat.ir",
"keywords": "نوبت تبریز, دکتر تبریز, پزشک متخصص تبریز, رزرو نوبت اینترنتی تبریز, کلینیک تبریز, بیمارستان تبریز, نوبت آنلاین آذربایجان شرقی",
"keywords": "نوبت دکتر تبریز, نوبت‌دهی آنلاین تبریز, دکتر خوب تبریز, پزشک متخصص تبریز, رزرو نوبت پزشک تبریز, نوبت اینترنتی دکتر تبریز, نوبت آنلاین آذربایجان شرقی, تبریز نوبت",
"footer_description": "نوبت تبریز، سامانه تخصصی رزرو آنلاین نوبت از پزشکان و مراکز درمانی معتبر آذربایجان شرقی در کمترین زمان.",
"social_media": {
"instagram": "tabriz_nobat",
@@ -279,7 +279,7 @@
"uuid": "7bfb777e-646b-11f1-84d7-f26ca1845824",
"name": "تهران",
"site_name": "تهران نوبت",
"title": "نوبت‌دهی آنلاین پزشکان تهران | رزرو نوبت دکتر",
"title": "نوبت‌دهی آنلاین پزشکان تهران | تهران نوبت",
"status": 1,
"weight": 0,
"province_id": 8,
@@ -288,9 +288,9 @@
"contact_phone": "+98 021 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت تهران از هزاران پزشک متخصص و فوق‌تخصص پایتخت آنلاین نوبت بگیرید. جست‌وجوی دکتر بر اساس تخصص، بیمه و منطقه در تهران و رزرو نوبت بدون صف.",
"slogan": "نوبت بهترین پزشکان تهران، بدون صف",
"slogan": "تهران بزرگ، نوبت دکتر در چند ثانیه",
"domain": "tehran-nobat.ir",
"keywords": "نوبت تهران, دکتر تهران, پزشک متخصص تهران, رزرو نوبت اینترنتی تهران, فوق تخصص تهران, کلینیک تهران, بیمارستان تهران",
"keywords": "نوبت دکتر تهران, نوبت‌دهی آنلاین تهران, دکتر خوب تهران, پزشک متخصص تهران, رزرو نوبت پزشک تهران, نوبت اینترنتی دکتر تهران, بیمارستان تهران, تهران نوبت",
"footer_description": "نوبت تهران، دسترسی به شبکه گسترده پزشکان متخصص و فوق‌تخصص و مراکز درمانی پایتخت برای رزرو آنلاین نوبت.",
"social_media": {
"instagram": "tehran_nobat",
@@ -304,7 +304,7 @@
"uuid": "7bfba0b0-646b-11f1-84d7-f26ca1845824",
"name": "خرم‌آباد",
"site_name": "خرم‌آباد نوبت",
"title": "نوبت دکتر خرم‌آباد | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان خرم‌آباد | خرم‌آباد نوبت",
"status": 1,
"weight": 0,
"province_id": 26,
@@ -313,9 +313,9 @@
"contact_phone": "+98 066 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت خرم‌آباد، رزرو آنلاین نوبت پزشکان و مراکز درمانی لرستان را ساده می‌کند. دکتر خود را انتخاب کنید و نوبت اینترنتی بگیرید؛ سریع و بدون مراجعه حضوری.",
"slogan": "نوبت پزشک خرم‌آباد، ساده و سریع",
"slogan": "نوبت دکتر خرم‌آباد، سریع و هوشمند",
"domain": "lorestan-nobat.ir",
"keywords": "نوبت خرم‌آباد, دکتر خرم‌آباد, پزشک متخصص خرم‌آباد, رزرو نوبت اینترنتی خرم‌آباد, کلینیک خرم‌آباد, نوبت آنلاین لرستان, مطب خرم‌آباد",
"keywords": "نوبت دکتر خرم‌آباد, نوبت‌دهی آنلاین خرم‌آباد, دکتر خوب خرم‌آباد, پزشک متخصص خرم‌آباد, رزرو نوبت پزشک خرم‌آباد, نوبت اینترنتی دکتر خرم‌آباد, نوبت آنلاین لرستان, خرم‌آباد نوبت",
"footer_description": "نوبت خرم‌آباد، همراه مردم لرستان برای رزرو آنلاین نوبت از پزشکان و مراکز درمانی خرم‌آباد.",
"social_media": {
"instagram": "khorramabad_nobat",
@@ -329,7 +329,7 @@
"uuid": "7bfb9ea9-646b-11f1-84d7-f26ca1845824",
"name": "رشت",
"site_name": "رشت نوبت",
"title": "رزرو نوبت اینترنتی پزشک رشت | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان رشت | رشت نوبت",
"status": 1,
"weight": 0,
"province_id": 25,
@@ -338,9 +338,9 @@
"contact_phone": "+98 013 33333333",
"email": "nobat724@gmail.com",
"description": "در رشت آنلاین نوبت بگیرید؛ نوبت رشت دسترسی به پزشکان متخصص و عمومی گیلان را فراهم می‌کند. جست‌وجوی دکتر بر اساس تخصص و بیمه و رزرو نوبت بدون صف.",
"slogan": "نوبت دکتر رشت، آنلاین و بدون صف",
"slogan": "نوبت پزشک رشت، راحت‌تر از همیشه",
"domain": "rasht-nobat.ir",
"keywords": "نوبت رشت, دکتر رشت, پزشک متخصص رشت, رزرو نوبت اینترنتی رشت, کلینیک رشت, بیمارستان رشت, نوبت آنلاین گیلان",
"keywords": "نوبت دکتر رشت, نوبت‌دهی آنلاین رشت, دکتر خوب رشت, پزشک متخصص رشت, رزرو نوبت پزشک رشت, نوبت اینترنتی دکتر رشت, نوبت آنلاین گیلان, رشت نوبت",
"footer_description": "نوبت رشت، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان گیلان برای شهروندان رشت.",
"social_media": {
"instagram": "rasht_nobat",
@@ -354,7 +354,7 @@
"uuid": "7bfb88eb-646b-11f1-84d7-f26ca1845824",
"name": "زاهدان",
"site_name": "زاهدان نوبت",
"title": "نوبت‌دهی آنلاین پزشکان زاهدان | رزرو نوبت",
"title": "نوبت‌دهی آنلاین پزشکان زاهدان | زاهدان نوبت",
"status": 1,
"weight": 0,
"province_id": 16,
@@ -363,9 +363,9 @@
"contact_phone": "+98 054 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت زاهدان، آنلاین از پزشکان متخصص و عمومی سیستان و بلوچستان نوبت بگیرید. انتخاب دکتر و ثبت نوبت اینترنتی در زاهدان، آسان و در دسترس.",
"slogan": "نوبت پزشک زاهدان، آسان و اینترنتی",
"slogan": "نوبت دکتر زاهدان، آسان‌تر از تماس",
"domain": "zahedan-nobat.ir",
"keywords": "نوبت زاهدان, دکتر زاهدان, پزشک متخصص زاهدان, رزرو نوبت اینترنتی زاهدان, کلینیک زاهدان, نوبت آنلاین سیستان و بلوچستان, مطب زاهدان",
"keywords": "نوبت دکتر زاهدان, نوبت‌دهی آنلاین زاهدان, دکتر خوب زاهدان, پزشک متخصص زاهدان, رزرو نوبت پزشک زاهدان, نوبت اینترنتی دکتر زاهدان, نوبت آنلاین سیستان و بلوچستان, زاهدان نوبت",
"footer_description": "نوبت زاهدان، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان سیستان و بلوچستان.",
"social_media": {
"instagram": "zahedan_nobat",
@@ -379,7 +379,7 @@
"uuid": "7bfb8454-646b-11f1-84d7-f26ca1845824",
"name": "زنجان",
"site_name": "زنجان نوبت",
"title": "نوبت دکتر زنجان | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان زنجان | زنجان نوبت",
"status": 1,
"weight": 0,
"province_id": 14,
@@ -388,9 +388,9 @@
"contact_phone": "+98 024 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت زنجان، سریع‌ترین راه رزرو نوبت پزشکان زنجان است. دکتر متخصص خود را انتخاب کنید و نوبت آنلاین بگیرید؛ ۲۴ساعته، بدون صف و اتلاف وقت.",
"slogan": "نوبت پزشک زنجان، بدون اتلاف وقت",
"slogan": "نوبت پزشک زنجان، همین حالا آنلاین",
"domain": "zanjan-nobat.ir",
"keywords": "نوبت زنجان, دکتر زنجان, پزشک متخصص زنجان, رزرو نوبت اینترنتی زنجان, کلینیک زنجان, درمانگاه زنجان, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر زنجان, نوبت‌دهی آنلاین زنجان, دکتر خوب زنجان, پزشک متخصص زنجان, رزرو نوبت پزشک زنجان, نوبت اینترنتی دکتر زنجان, بیمارستان زنجان, زنجان نوبت",
"footer_description": "نوبت زنجان، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان زنجان بدون مراجعه حضوری.",
"social_media": {
"instagram": "zanjan_nobat",
@@ -404,7 +404,7 @@
"uuid": "7bfba2b0-646b-11f1-84d7-f26ca1845824",
"name": "ساری",
"site_name": "ساری نوبت",
"title": "رزرو نوبت اینترنتی پزشک ساری | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان ساری | ساری نوبت",
"status": 1,
"weight": 0,
"province_id": 27,
@@ -413,9 +413,9 @@
"contact_phone": "+98 011 33333333",
"email": "nobat724@gmail.com",
"description": "در ساری آنلاین نوبت بگیرید؛ نوبت ساری دسترسی به پزشکان متخصص و عمومی مازندران را فراهم می‌کند. جست‌وجوی دکتر و رزرو نوبت بدون مراجعه حضوری.",
"slogan": "نوبت دکتر ساری، ساده و آنلاین",
"slogan": "پزشکان ساری، یک کلیک با شما فاصله",
"domain": "sari-nobat.ir",
"keywords": "نوبت ساری, دکتر ساری, پزشک متخصص ساری, رزرو نوبت اینترنتی ساری, کلینیک ساری, بیمارستان ساری, نوبت آنلاین مازندران",
"keywords": "نوبت دکتر ساری, نوبت‌دهی آنلاین ساری, دکتر خوب ساری, پزشک متخصص ساری, رزرو نوبت پزشک ساری, نوبت اینترنتی دکتر ساری, نوبت آنلاین مازندران, ساری نوبت",
"footer_description": "نوبت ساری، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان مازندران برای شهروندان ساری.",
"social_media": {
"instagram": "sari_nobat",
@@ -429,7 +429,7 @@
"uuid": "7bfb8666-646b-11f1-84d7-f26ca1845824",
"name": "سمنان",
"site_name": "سمنان نوبت",
"title": "نوبت‌دهی آنلاین پزشکان سمنان | رزرو نوبت",
"title": "نوبت‌دهی آنلاین پزشکان سمنان | سمنان نوبت",
"status": 1,
"weight": 0,
"province_id": 15,
@@ -438,9 +438,9 @@
"contact_phone": "+98 023 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت سمنان، آنلاین از پزشکان متخصص و عمومی استان سمنان نوبت بگیرید. انتخاب دکتر بر اساس تخصص و ثبت نوبت اینترنتی، سریع و بدون صف.",
"slogan": "نوبت پزشک سمنان، سریع و بدون صف",
"slogan": "دکتر سمنان، چند ثانیه تا نوبت",
"domain": "semnan-nobat.ir",
"keywords": "نوبت سمنان, دکتر سمنان, پزشک متخصص سمنان, رزرو نوبت اینترنتی سمنان, کلینیک سمنان, درمانگاه سمنان, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر سمنان, نوبت‌دهی آنلاین سمنان, دکتر خوب سمنان, پزشک متخصص سمنان, رزرو نوبت پزشک سمنان, نوبت اینترنتی دکتر سمنان, بیمارستان سمنان, سمنان نوبت",
"footer_description": "نوبت سمنان، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان سمنان بدون نیاز به مراجعه حضوری.",
"social_media": {
"instagram": "semnan_nobat",
@@ -454,7 +454,7 @@
"uuid": "7bfb90fb-646b-11f1-84d7-f26ca1845824",
"name": "سنندج",
"site_name": "سنندج نوبت",
"title": "نوبت دکتر سنندج | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان سنندج | سنندج نوبت",
"status": 1,
"weight": 0,
"province_id": 20,
@@ -463,9 +463,9 @@
"contact_phone": "+98 087 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت سنندج، رزرو آنلاین نوبت پزشکان و مراکز درمانی کردستان را ساده می‌کند. دکتر خود را انتخاب کنید و نوبت اینترنتی بگیرید؛ سریع و در دسترس.",
"slogan": "نوبت پزشک سنندج، ساده و سریع",
"slogan": "دکتر سنندج، به سادگی یک کلیک",
"domain": "sanandaj-nobat.ir",
"keywords": "نوبت سنندج, دکتر سنندج, پزشک متخصص سنندج, رزرو نوبت اینترنتی سنندج, کلینیک سنندج, نوبت آنلاین کردستان, مطب سنندج",
"keywords": "نوبت دکتر سنندج, نوبت‌دهی آنلاین سنندج, دکتر خوب سنندج, پزشک متخصص سنندج, رزرو نوبت پزشک سنندج, نوبت اینترنتی دکتر سنندج, نوبت آنلاین کردستان, سنندج نوبت",
"footer_description": "نوبت سنندج، همراه مردم کردستان برای رزرو آنلاین نوبت از پزشکان و مراکز درمانی سنندج.",
"social_media": {
"instagram": "sanandaj_nobat",
@@ -479,7 +479,7 @@
"uuid": "7bfb797f-646b-11f1-84d7-f26ca1845824",
"name": "شهرکرد",
"site_name": "شهرکرد نوبت",
"title": "رزرو نوبت اینترنتی پزشک شهرکرد | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان شهرکرد | شهرکرد نوبت",
"status": 1,
"weight": 0,
"province_id": 9,
@@ -488,9 +488,9 @@
"contact_phone": "+98 038 33333333",
"email": "nobat724@gmail.com",
"description": "در شهرکرد آنلاین نوبت بگیرید؛ نوبت شهرکرد دسترسی به پزشکان متخصص و عمومی چهارمحال و بختیاری را فراهم می‌کند. جست‌وجوی دکتر و رزرو نوبت بدون صف.",
"slogan": "نوبت دکتر شهرکرد، آنلاین و بدون صف",
"slogan": "نوبت پزشک شهرکرد، بدون معطلی",
"domain": "shkord-nobat.ir",
"keywords": "نوبت شهرکرد, دکتر شهرکرد, پزشک متخصص شهرکرد, رزرو نوبت اینترنتی شهرکرد, کلینیک شهرکرد, نوبت آنلاین چهارمحال و بختیاری, مطب شهرکرد",
"keywords": "نوبت دکتر شهرکرد, نوبت‌دهی آنلاین شهرکرد, دکتر خوب شهرکرد, پزشک متخصص شهرکرد, رزرو نوبت پزشک شهرکرد, نوبت اینترنتی دکتر شهرکرد, نوبت آنلاین چهارمحال و بختیاری, شهرکرد نوبت",
"footer_description": "نوبت شهرکرد، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان چهارمحال و بختیاری.",
"social_media": {
"instagram": "shahrekord_nobat",
@@ -504,7 +504,7 @@
"uuid": "7bfb8b02-646b-11f1-84d7-f26ca1845824",
"name": "شیراز",
"site_name": "شیراز نوبت",
"title": "نوبت‌دهی آنلاین پزشکان شیراز | رزرو نوبت دکتر",
"title": "نوبت‌دهی آنلاین پزشکان شیراز | شیراز نوبت",
"status": 1,
"weight": 0,
"province_id": 17,
@@ -513,9 +513,9 @@
"contact_phone": "+98 071 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت شیراز از بهترین پزشکان متخصص و فوق‌تخصص فارس آنلاین نوبت بگیرید. جست‌وجوی دکتر بر اساس تخصص، بیمه و منطقه در شیراز و رزرو سریع نوبت.",
"slogan": "بهترین پزشکان شیراز، تنها با چند کلیک",
"slogan": "پزشکان شیراز، یک کلیک تا آرامش",
"domain": "shiraz-nobat.ir",
"keywords": "نوبت شیراز, دکتر شیراز, پزشک متخصص شیراز, رزرو نوبت اینترنتی شیراز, فوق تخصص شیراز, کلینیک شیراز, بیمارستان فارس",
"keywords": "نوبت دکتر شیراز, نوبت‌دهی آنلاین شیراز, دکتر خوب شیراز, پزشک متخصص شیراز, رزرو نوبت پزشک شیراز, نوبت اینترنتی دکتر شیراز, نوبت آنلاین فارس, شیراز نوبت",
"footer_description": "نوبت شیراز، دسترسی به شبکه پزشکان متخصص و فوق‌تخصص و مراکز درمانی استان فارس برای رزرو آنلاین نوبت.",
"social_media": {
"instagram": "shiraz_nobat",
@@ -529,7 +529,7 @@
"uuid": "7bfb8d02-646b-11f1-84d7-f26ca1845824",
"name": "قزوین",
"site_name": "قزوین نوبت",
"title": "نوبت دکتر قزوین | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان قزوین | قزوین نوبت",
"status": 1,
"weight": 0,
"province_id": 18,
@@ -538,9 +538,9 @@
"contact_phone": "+98 028 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت قزوین، سریع‌ترین راه رزرو نوبت پزشکان قزوین است. دکتر متخصص یا عمومی خود را انتخاب کنید و نوبت آنلاین بگیرید؛ ۲۴ساعته و بدون مراجعه حضوری.",
"slogan": "نوبت پزشک قزوین، بدون مراجعه حضوری",
"slogan": "نوبت دکتر قزوین، هوشمند و سریع",
"domain": "qazvin-nobat.ir",
"keywords": "نوبت قزوین, دکتر قزوین, پزشک متخصص قزوین, رزرو نوبت اینترنتی قزوین, کلینیک قزوین, درمانگاه قزوین, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر قزوین, نوبت‌دهی آنلاین قزوین, دکتر خوب قزوین, پزشک متخصص قزوین, رزرو نوبت پزشک قزوین, نوبت اینترنتی دکتر قزوین, بیمارستان قزوین, قزوین نوبت",
"footer_description": "نوبت قزوین، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان قزوین بدون صف و اتلاف وقت.",
"social_media": {
"instagram": "qazvin_nobat",
@@ -554,7 +554,7 @@
"uuid": "7bfb8efd-646b-11f1-84d7-f26ca1845824",
"name": "قم",
"site_name": "قم نوبت",
"title": "رزرو نوبت اینترنتی پزشک قم | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان قم | قم نوبت",
"status": 1,
"weight": 0,
"province_id": 19,
@@ -563,9 +563,9 @@
"contact_phone": "+98 025 33333333",
"email": "nobat724@gmail.com",
"description": "در قم آنلاین نوبت بگیرید؛ نوبت قم دسترسی به پزشکان متخصص و عمومی استان قم را فراهم می‌کند. جست‌وجوی دکتر بر اساس تخصص و رزرو نوبت بدون صف.",
"slogan": "نوبت دکتر قم، آنلاین و بدون صف",
"slogan": "نوبت پزشک قم، آنلاین در هر ساعت",
"domain": "qom-nobat.ir",
"keywords": "نوبت قم, دکتر قم, پزشک متخصص قم, رزرو نوبت اینترنتی قم, کلینیک قم, بیمارستان قم, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر قم, نوبت‌دهی آنلاین قم, دکتر خوب قم, پزشک متخصص قم, رزرو نوبت پزشک قم, نوبت اینترنتی دکتر قم, بیمارستان قم, قم نوبت",
"footer_description": "نوبت قم، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان قم برای شهروندان قم.",
"social_media": {
"instagram": "qom_nobat",
@@ -579,7 +579,7 @@
"uuid": "7bfb718c-646b-11f1-84d7-f26ca1845824",
"name": "کرج",
"site_name": "کرج نوبت",
"title": "نوبت‌دهی آنلاین پزشکان کرج | رزرو نوبت دکتر",
"title": "نوبت‌دهی آنلاین پزشکان کرج | کرج نوبت",
"status": 1,
"weight": 0,
"province_id": 5,
@@ -588,9 +588,9 @@
"contact_phone": "+98 026 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت کرج، آنلاین از پزشکان متخصص و عمومی استان البرز نوبت بگیرید. جست‌وجوی دکتر بر اساس تخصص، بیمه و منطقه در کرج و رزرو نوبت بدون مراجعه حضوری.",
"slogan": "در کرج، نوبت دکتر فقط با چند کلیک",
"slogan": "نوبت دکتر کرج، در لحظه و آنلاین",
"domain": "karaj-nobat.ir",
"keywords": "نوبت کرج, دکتر کرج, پزشک متخصص کرج, رزرو نوبت اینترنتی کرج, کلینیک کرج, بیمارستان کرج, نوبت آنلاین البرز",
"keywords": "نوبت دکتر کرج, نوبت‌دهی آنلاین کرج, دکتر خوب کرج, پزشک متخصص کرج, رزرو نوبت پزشک کرج, نوبت اینترنتی دکتر کرج, نوبت آنلاین البرز, کرج نوبت",
"footer_description": "نوبت کرج، مرجع نوبت‌دهی آنلاین پزشکان و مراکز درمانی استان البرز و دسترسی سریع به متخصصان کرج.",
"social_media": {
"instagram": "karaj_nobat",
@@ -604,7 +604,7 @@
"uuid": "7bfb93e4-646b-11f1-84d7-f26ca1845824",
"name": "کرمان",
"site_name": "کرمان نوبت",
"title": "نوبت دکتر کرمان | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان کرمان | کرمان نوبت",
"status": 1,
"weight": 0,
"province_id": 21,
@@ -613,9 +613,9 @@
"contact_phone": "+98 034 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت کرمان، رزرو آنلاین نوبت پزشکان و مراکز درمانی استان کرمان را ساده می‌کند. دکتر متخصص خود را انتخاب کنید و نوبت اینترنتی بگیرید؛ سریع و بدون صف.",
"slogan": "نوبت پزشک کرمان، سریع و بدون صف",
"slogan": "نوبت پزشک کرمان، بی‌وقفه و آنلاین",
"domain": "kerman-nobat.ir",
"keywords": "نوبت کرمان, دکتر کرمان, پزشک متخصص کرمان, رزرو نوبت اینترنتی کرمان, کلینیک کرمان, بیمارستان کرمان, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر کرمان, نوبت‌دهی آنلاین کرمان, دکتر خوب کرمان, پزشک متخصص کرمان, رزرو نوبت پزشک کرمان, نوبت اینترنتی دکتر کرمان, بیمارستان کرمان, کرمان نوبت",
"footer_description": "نوبت کرمان، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان کرمان بدون نیاز به مراجعه حضوری.",
"social_media": {
"instagram": "kerman_nobat",
@@ -629,7 +629,7 @@
"uuid": "7bfb9685-646b-11f1-84d7-f26ca1845824",
"name": "کرمانشاه",
"site_name": "کرمانشاه نوبت",
"title": "رزرو نوبت اینترنتی پزشک کرمانشاه | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان کرمانشاه | کرمانشاه نوبت",
"status": 1,
"weight": 0,
"province_id": 22,
@@ -638,9 +638,9 @@
"contact_phone": "+98 083 33333333",
"email": "nobat724@gmail.com",
"description": "در کرمانشاه آنلاین نوبت بگیرید؛ نوبت کرمانشاه دسترسی به پزشکان متخصص و عمومی استان را فراهم می‌کند. جست‌وجوی دکتر و رزرو نوبت بدون مراجعه حضوری.",
"slogan": "نوبت دکتر کرمانشاه، ساده و آنلاین",
"slogan": "نوبت دکتر کرمانشاه، در چند ثانیه",
"domain": "kermanshah-nobat.ir",
"keywords": "نوبت کرمانشاه, دکتر کرمانشاه, پزشک متخصص کرمانشاه, رزرو نوبت اینترنتی کرمانشاه, کلینیک کرمانشاه, بیمارستان کرمانشاه, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر کرمانشاه, نوبت‌دهی آنلاین کرمانشاه, دکتر خوب کرمانشاه, پزشک متخصص کرمانشاه, رزرو نوبت پزشک کرمانشاه, نوبت اینترنتی دکتر کرمانشاه, بیمارستان کرمانشاه, کرمانشاه نوبت",
"footer_description": "نوبت کرمانشاه، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان کرمانشاه برای شهروندان کرمانشاه.",
"social_media": {
"instagram": "kermanshah_nobat",
@@ -654,7 +654,7 @@
"uuid": "7bfb9cb5-646b-11f1-84d7-f26ca1845824",
"name": "گرگان",
"site_name": "گرگان نوبت",
"title": "نوبت‌دهی آنلاین پزشکان گرگان | رزرو نوبت",
"title": "نوبت‌دهی آنلاین پزشکان گرگان | گرگان نوبت",
"status": 1,
"weight": 0,
"province_id": 24,
@@ -663,9 +663,9 @@
"contact_phone": "+98 017 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت گرگان، آنلاین از پزشکان متخصص و عمومی استان گلستان نوبت بگیرید. انتخاب دکتر بر اساس تخصص و ثبت نوبت اینترنتی در گرگان، سریع و در دسترس.",
"slogan": "نوبت پزشک گرگان، سریع و در دسترس",
"slogan": "دکتر گرگان، رزرو آنلاین در لحظه",
"domain": "golestan-nobat.ir",
"keywords": "نوبت گرگان, دکتر گرگان, پزشک متخصص گرگان, رزرو نوبت اینترنتی گرگان, کلینیک گرگان, نوبت آنلاین گلستان, مطب گرگان",
"keywords": "نوبت دکتر گرگان, نوبت‌دهی آنلاین گرگان, دکتر خوب گرگان, پزشک متخصص گرگان, رزرو نوبت پزشک گرگان, نوبت اینترنتی دکتر گرگان, نوبت آنلاین گلستان, گرگان نوبت",
"footer_description": "نوبت گرگان، همراه مردم گلستان برای رزرو آنلاین نوبت از پزشکان و مراکز درمانی گرگان.",
"social_media": {
"instagram": "gorgan_nobat",
@@ -679,7 +679,7 @@
"uuid": "7bfb7d86-646b-11f1-84d7-f26ca1845824",
"name": "مشهد",
"site_name": "مشهد نوبت",
"title": "نوبت دکتر مشهد | سامانه نوبت‌دهی پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان مشهد | مشهد نوبت",
"status": 1,
"weight": 0,
"province_id": 11,
@@ -688,9 +688,9 @@
"contact_phone": "+98 051 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت مشهد از پزشکان متخصص و فوق‌تخصص خراسان رضوی آنلاین نوبت بگیرید. جست‌وجوی دکتر بر اساس تخصص، بیمه و منطقه در مشهد و رزرو سریع نوبت.",
"slogan": "بهترین پزشکان مشهد، تنها با چند کلیک",
"slogan": وبت پزشکان مشهد، هوشمند و آنی",
"domain": "mashhad-nobat.ir",
"keywords": "نوبت مشهد, دکتر مشهد, پزشک متخصص مشهد, رزرو نوبت اینترنتی مشهد, فوق تخصص مشهد, کلینیک مشهد, بیمارستان خراسان رضوی",
"keywords": "نوبت دکتر مشهد, نوبت‌دهی آنلاین مشهد, دکتر خوب مشهد, پزشک متخصص مشهد, رزرو نوبت پزشک مشهد, نوبت اینترنتی دکتر مشهد, نوبت آنلاین خراسان رضوی, مشهد نوبت",
"footer_description": "نوبت مشهد، دسترسی به شبکه پزشکان متخصص و فوق‌تخصص و مراکز درمانی خراسان رضوی برای رزرو آنلاین نوبت.",
"social_media": {
"instagram": "mashhad_nobat",
@@ -704,7 +704,7 @@
"uuid": "7bfbad3c-646b-11f1-84d7-f26ca1845824",
"name": "نوبت 724",
"site_name": "نوبت 724",
"title": "نوبت ۷۲۴ | سامانه سراسری نوبت‌دهی آنلاین پزشکی ایران",
"title": "نوبت‌دهی آنلاین پزشکان ایران | نوبت 724",
"status": 1,
"weight": 0,
"province_id": null,
@@ -713,9 +713,9 @@
"contact_phone": "+98 021 724724724",
"email": "nobat724@gmail.com",
"description": "نوبت ۷۲۴، سامانه سراسری نوبت‌دهی آنلاین پزشکی در ایران. از پزشکان متخصص و عمومی سراسر کشور، ۲۴ساعته و بدون مراجعه حضوری، آنلاین نوبت بگیرید.",
"slogan": "نوبت‌دهی آنلاین پزشکی ایران، ۲۴ ساعته",
"slogan": "نوبت 724، نوبت‌دهی آنلاین پزشکان ایران",
"domain": "nobat724.com",
"keywords": "نوبت ۷۲۴, نوبت‌دهی آنلاین, رزرو نوبت پزشک, نوبت اینترنتی دکتر, سامانه نوبت‌دهی پزشکی, نوبت آنلاین بیمارستان, رزرو نوبت آنلاین",
"keywords": "نوبت 724, نوبت‌دهی آنلاین, نوبت دکتر, رزرو نوبت پزشک آنلاین, دکتر خوب, پزشک متخصص ایران, نوبت اینترنتی دکتر, سامانه نوبت‌دهی پزشکی",
"footer_description": "نوبت ۷۲۴، سامانه سراسری رزرو آنلاین نوبت از پزشکان و مراکز درمانی ایران بدون نیاز به مراجعه حضوری.",
"social_media": {
"instagram": "nobat724",
@@ -729,7 +729,7 @@
"uuid": "7bfba8b7-646b-11f1-84d7-f26ca1845824",
"name": "همدان",
"site_name": "همدان نوبت",
"title": "رزرو نوبت اینترنتی پزشک همدان | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان همدان | همدان نوبت",
"status": 1,
"weight": 0,
"province_id": 30,
@@ -738,9 +738,9 @@
"contact_phone": "+98 081 33333333",
"email": "nobat724@gmail.com",
"description": "در همدان آنلاین نوبت بگیرید؛ نوبت همدان دسترسی به پزشکان متخصص و عمومی استان همدان را فراهم می‌کند. جست‌وجوی دکتر و رزرو نوبت بدون صف و انتظار.",
"slogan": "نوبت دکتر همدان، بدون صف و انتظار",
"slogan": "دکتر همدان، نوبت آنلاین در یک دقیقه",
"domain": "hamadan-nobat.ir",
"keywords": "نوبت همدان, دکتر همدان, پزشک متخصص همدان, رزرو نوبت اینترنتی همدان, کلینیک همدان, بیمارستان همدان, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر همدان, نوبت‌دهی آنلاین همدان, دکتر خوب همدان, پزشک متخصص همدان, رزرو نوبت پزشک همدان, نوبت اینترنتی دکتر همدان, بیمارستان همدان, همدان نوبت",
"footer_description": "نوبت همدان، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان همدان برای شهروندان همدان.",
"social_media": {
"instagram": "hamedan_nobat",
@@ -754,7 +754,7 @@
"uuid": "7bfb989e-646b-11f1-84d7-f26ca1845824",
"name": "یاسوج",
"site_name": "یاسوج نوبت",
"title": "نوبت‌دهی آنلاین پزشکان یاسوج | رزرو نوبت",
"title": "نوبت‌دهی آنلاین پزشکان یاسوج | یاسوج نوبت",
"status": 1,
"weight": 0,
"province_id": 23,
@@ -763,9 +763,9 @@
"contact_phone": "+98 074 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت یاسوج، آنلاین از پزشکان متخصص و عمومی کهگیلویه و بویراحمد نوبت بگیرید. انتخاب دکتر و ثبت نوبت اینترنتی در یاسوج، آسان و در دسترس.",
"slogan": "نوبت پزشک یاسوج، آسان و اینترنتی",
"slogan": "پزشک یاسوج، آنلاین کنار شماست",
"domain": "yasuj-nobat.ir",
"keywords": "نوبت یاسوج, دکتر یاسوج, پزشک متخصص یاسوج, رزرو نوبت اینترنتی یاسوج, کلینیک یاسوج, نوبت آنلاین کهگیلویه و بویراحمد, مطب یاسوج",
"keywords": "نوبت دکتر یاسوج, نوبت‌دهی آنلاین یاسوج, دکتر خوب یاسوج, پزشک متخصص یاسوج, رزرو نوبت پزشک یاسوج, نوبت اینترنتی دکتر یاسوج, نوبت آنلاین کهگیلویه و بویراحمد, یاسوج نوبت",
"footer_description": "نوبت یاسوج، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان کهگیلویه و بویراحمد.",
"social_media": {
"instagram": "yasuj_nobat",
@@ -779,7 +779,7 @@
"uuid": "7bfbaacd-646b-11f1-84d7-f26ca1845824",
"name": "یزد",
"site_name": "یزد نوبت",
"title": "نوبت دکتر یزد | سامانه نوبت‌دهی آنلاین پزشکی",
"title": "نوبت‌دهی آنلاین پزشکان یزد | یزد نوبت",
"status": 1,
"weight": 0,
"province_id": 100,
@@ -788,9 +788,9 @@
"contact_phone": "+98 035 33333333",
"email": "nobat724@gmail.com",
"description": "نوبت یزد، کامل‌ترین سامانه نوبت‌دهی آنلاین پزشکی استان یزد است. از پزشکان و مراکز پاراکلینیکی شهر جهانی یزد با کمترین انتظار نوبت اینترنتی بگیرید.",
"slogan": "نوبت‌گیری آنلاین پزشکان یزد، ۲۴ساعته",
"slogan": "نوبت پزشک یزد، هوشمند و بدون انتظار",
"domain": "yazd-nobat.ir",
"keywords": "نوبت یزد, دکتر یزد, پزشک متخصص یزد, رزرو نوبت اینترنتی یزد, کلینیک یزد, مراکز پاراکلینیک یزد, نوبت آنلاین دکتر",
"keywords": "نوبت دکتر یزد, نوبت‌دهی آنلاین یزد, دکتر خوب یزد, پزشک متخصص یزد, رزرو نوبت پزشک یزد, نوبت اینترنتی دکتر یزد, بیمارستان یزد, یزد نوبت",
"footer_description": "نوبت یزد، سامانه جامع رزرو آنلاین نوبت از پزشکان و مراکز درمانی استان یزد بدون نیاز به مراجعه حضوری.",
"social_media": {
"instagram": "yazd_nobat",
@@ -804,7 +804,7 @@
"uuid": "7bfbcc01-646b-11f1-84d7-f26ca1845824",
"name": "دهدشت",
"site_name": "دهدشت نوبت",
"title": "رزرو نوبت اینترنتی پزشک دهدشت | نوبت آنلاین",
"title": "نوبت‌دهی آنلاین پزشکان دهدشت | دهدشت نوبت",
"status": 1,
"weight": 0,
"province_id": 23,
@@ -813,9 +813,9 @@
"contact_phone": "+98 074 33333333",
"email": "nobat724@gmail.com",
"description": "در دهدشت آنلاین نوبت بگیرید؛ نوبت دهدشت دسترسی به پزشکان متخصص و عمومی کهگیلویه و بویراحمد را فراهم می‌کند. جست‌وجوی دکتر و رزرو نوبت بدون صف.",
"slogan": "نوبت دکتر دهدشت، آنلاین و بدون صف",
"slogan": "نوبت دکتر دهدشت، آنلاین و در دسترس",
"domain": "dehdasht-nobat.ir",
"keywords": "نوبت دهدشت, دکتر دهدشت, پزشک متخصص دهدشت, رزرو نوبت اینترنتی دهدشت, کلینیک دهدشت, نوبت آنلاین کهگیلویه و بویراحمد, مطب دهدشت",
"keywords": "نوبت دکتر دهدشت, نوبت‌دهی آنلاین دهدشت, دکتر خوب دهدشت, پزشک متخصص دهدشت, رزرو نوبت پزشک دهدشت, نوبت اینترنتی دکتر دهدشت, نوبت آنلاین کهگیلویه و بویراحمد, دهدشت نوبت",
"footer_description": "نوبت دهدشت، مرجع رزرو آنلاین نوبت پزشکان و مراکز درمانی استان کهگیلویه و بویراحمد.",
"social_media": {
"instagram": "dehdasht_nobat",
@@ -829,7 +829,7 @@
"uuid": "7bfbcc02-646b-11f1-84d7-f26ca1845824",
"name": "بهبهان",
"site_name": "بهبهان نوبت",
"title": "نوبت‌دهی آنلاین پزشکان بهبهان | رزرو نوبت",
"title": "نوبت‌دهی آنلاین پزشکان بهبهان | بهبهان نوبت",
"status": 1,
"weight": 0,
"province_id": 13,
@@ -838,9 +838,9 @@
"contact_phone": "+98 061 33333333",
"email": "nobat724@gmail.com",
"description": "با نوبت بهبهان، آنلاین از پزشکان متخصص و عمومی شهر بهبهان نوبت بگیرید. انتخاب دکتر بر اساس تخصص و ثبت نوبت اینترنتی، سریع و بدون مراجعه حضوری.",
"slogan": "نوبت پزشک بهبهان، سریع و اینترنتی",
"slogan": "پزشک بهبهان، یک کلیک تا نوبت شما",
"domain": "behbahan-nobat.ir",
"keywords": "نوبت بهبهان, دکتر بهبهان, پزشک متخصص بهبهان, رزرو نوبت اینترنتی بهبهان, کلینیک بهبهان, بیمارستان بهبهان, نوبت آنلاین خوزستان",
"keywords": "نوبت دکتر بهبهان, نوبت‌دهی آنلاین بهبهان, دکتر خوب بهبهان, پزشک متخصص بهبهان, رزرو نوبت پزشک بهبهان, نوبت اینترنتی دکتر بهبهان, نوبت آنلاین خوزستان, بهبهان نوبت",
"footer_description": "نوبت بهبهان، سامانه رزرو آنلاین نوبت از پزشکان و مراکز درمانی بهبهان در استان خوزستان.",
"social_media": {
"instagram": "behbahan_nobat",
+7
View File
@@ -42,6 +42,11 @@ table columns (the same keys an import expects), so export → import is lossles
}
```
For `cities` the export rows carry every column plus `province_name`, and
`social_media` is returned as a JSON **object** — the exact shape
`nobat724_front/data/city.json` uses, so the export file can be dropped into the
frontend (and re-imported) without any transformation.
### Errors
| Code | HTTP | Description |
|------|------|-------------|
@@ -84,6 +89,8 @@ A non-empty array of records, or `{ "items": [ … ] }`. Max **5000** rows.
| `parent_id` | `specialties`: null, or an `id` present **in the same file** |
| `specialty_id` | `doctor_services`: null, or an existing `specialties.id` |
| `province_id` / `representation_id` | `cities`: null, or an existing id in the referenced table |
| `title`, `site_name`, `slogan`, `domain`, `keywords`, `description`, `footer_description`, `contact_phone`, `email`, `logo_url` | `cities`: optional SEO/branding strings (`title` = meta title of the city website) |
| `social_media` | `cities`: optional; JSON object (e.g. `{"instagram": "…"}`) or its string form — stored as JSON |
### Response `200`
```json
+1
View File
@@ -188,6 +188,7 @@ Create a new city.
|-------|------|----------|-------------|
| `name` | string | ✅ | City name |
| `site_name` | string | ❌ | Public site name shown on the city's booking website (e.g. `"یزد نوبت"`) |
| `title` | string | ❌ | SEO meta title for the city's booking website (e.g. `"نوبت‌دهی آنلاین پزشکان یزد | یزد نوبت"`) |
| `province_id` | integer | ❌ | Parent province ID |
| `status` | string | ❌ | `"active"` or `"inactive"` |
| `weight` | integer | ❌ | Sort weight |
+8 -1
View File
@@ -733,5 +733,12 @@
"731": "Community 731",
"732": "Community 732",
"733": "Community 733",
"734": "Community 734"
"734": "Community 734",
"735": "Community 735",
"736": "Community 736",
"737": "Community 737",
"738": "Community 738",
"739": "Community 739",
"740": "Community 740",
"741": "Community 741"
}
+126 -107
View File
@@ -1,16 +1,16 @@
# Graph Report - clinicpro (2026-07-08)
## Corpus Check
- 717 files · ~525,524 words
- 718 files · ~526,180 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 9059 nodes · 12502 edges · 735 communities (593 shown, 142 thin omitted)
- 9068 nodes · 12516 edges · 742 communities (596 shown, 146 thin omitted)
- Extraction: 98% EXTRACTED · 2% INFERRED · 0% AMBIGUOUS · INFERRED: 277 edges (avg confidence: 0.8)
- Token cost: 0 input · 0 output
## Graph Freshness
- Built from commit: `8f4f7fc9`
- Built from commit: `94541ad6`
- Run `git rev-parse HEAD` and compare to check if the graph is stale.
- Run `graphify update .` after code changes (no API cost).
@@ -735,6 +735,13 @@
- [[_COMMUNITY_Community 732|Community 732]]
- [[_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]]
- [[_COMMUNITY_Community 740|Community 740]]
- [[_COMMUNITY_Community 741|Community 741]]
## God Nodes (most connected - your core abstractions)
1. `BaseController` - 76 edges
@@ -753,21 +760,21 @@
assets/admin/components/ServiceTariffModal.tsx → assets/admin/lib/utils.ts
- `Pagination()` --calls--> `formatNumber()` [EXTRACTED]
assets/admin/components/ui/Pagination.tsx → assets/admin/lib/utils.ts
- `MyFinancialPage()` --calls--> `formatRial()` [EXTRACTED]
assets/admin/pages/MyFinancialPage.tsx → assets/admin/lib/utils.ts
- `RepresentationSettlementPage()` --calls--> `formatRial()` [EXTRACTED]
assets/admin/pages/RepresentationSettlementPage.tsx → assets/admin/lib/utils.ts
- `PersianDatePicker()` --calls--> `formatDate()` [EXTRACTED]
assets/admin/components/ui/PersianDatePicker.tsx → assets/admin/lib/utils.ts
- `SettlementsPage()` --calls--> `formatRial()` [EXTRACTED]
assets/admin/pages/SettlementsPage.tsx → assets/admin/lib/utils.ts
- `NewAppointmentModal()` --calls--> `useAuthStore` [EXTRACTED]
assets/admin/pages/AppointmentsPage.tsx → assets/admin/stores/authStore.ts
## Import Cycles
- None detected.
## Communities (735 total, 142 thin omitted)
## Communities (742 total, 146 thin omitted)
### Community 0 - "Community 0"
Cohesion: 0.05
Nodes (38): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, DEGREE_OPTIONS, DoctorFormPage() (+30 more)
Cohesion: 0.06
Nodes (36): ALLOWED_ROLES, PrivateRoute(), PublicRoute(), RoleRoute(), queryClient, toastStyle, DEGREE_OPTIONS, DoctorFormPage() (+28 more)
### Community 1 - "Community 1"
Cohesion: 0.03
@@ -782,16 +789,16 @@ 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.06
Nodes (8): DoctorService, Doctor, DoctorServiceRepository, Collection, self, User, WeeklySchedule, ManagerRegistry
### Community 5 - "Community 5"
Cohesion: 0.07
Nodes (3): UserProfile, self, User
### Community 6 - "Community 6"
Cohesion: 0.12
Nodes (12): SettlementController, SettlementRepository, WalletTransactionRepository, Settlement, JsonResponse, Request, User, ManagerRegistry (+4 more)
Cohesion: 0.17
Nodes (8): SettlementController, SettlementRepository, Settlement, JsonResponse, Request, User, ManagerRegistry, User
### Community 7 - "Community 7"
Cohesion: 0.07
@@ -815,15 +822,15 @@ Nodes (4): UserActiveContextRepository, ManagerRegistry, User, UserActiveContext
### Community 12 - "Community 12"
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 (39): Clinic Doctor Invitation API, DELETE `/api/v1/admin/clinic/invitation/{invUuid}`, Errors, Errors, Errors, Errors, Errors, Errors (+31 more)
### Community 13 - "Community 13"
Cohesion: 0.05
Nodes (33): get, PaymentConfig, PaymentGatewayInfo, api, ApiError, ApiResponse, getToken(), refreshOnce() (+25 more)
Cohesion: 0.08
Nodes (20): get, api, ApiError, getToken(), refreshOnce(), request(), { refreshMock, logoutMock }, replaceMock (+12 more)
### Community 14 - "Community 14"
Cohesion: 0.10
Nodes (12): AppointmentSettingsController, DateOverride, Holiday, DateOverrideRepository, HolidayRepository, JsonResponse, Request, User (+4 more)
Cohesion: 0.15
Nodes (8): AppointmentSettingsController, Holiday, HolidayRepository, JsonResponse, Request, User, Doctor, ManagerRegistry
### Community 15 - "Community 15"
Cohesion: 0.25
@@ -834,8 +841,8 @@ Cohesion: 0.07
Nodes (7): PatientSession, SmsWallet, Appointment, Collection, PatientRecord, self, SessionService
### Community 17 - "Community 17"
Cohesion: 0.06
Nodes (33): DELETE `/api/v1/comment/{uuid}`, Errors, Errors, Errors, Errors, Errors, Errors, Errors (+25 more)
Cohesion: 0.05
Nodes (38): DELETE `/api/v1/comment/{uuid}`, Errors, Errors, Errors, Errors, Errors, Errors, Errors (+30 more)
### Community 18 - "Community 18"
Cohesion: 0.05
@@ -843,7 +850,7 @@ Nodes (38): API, API, API, API, API, Route, Route, Route (+30 more)
### Community 19 - "Community 19"
Cohesion: 0.05
Nodes (41): PaginatedResponse, FILTERS, Breakdown, SOURCE_LABEL, Summary, LEVEL_FILTER_OPTIONS, LEVEL_META, Tab (+33 more)
Nodes (44): PaginatedResponse, formatDate(), STATUS_FILTERS, FILTERS, Breakdown, SOURCE_LABEL, Summary, LEVEL_FILTER_OPTIONS (+36 more)
### Community 20 - "Community 20"
Cohesion: 0.14
@@ -851,18 +858,18 @@ Nodes (3): AdminApiController, JsonResponse, Request
### Community 21 - "Community 21"
Cohesion: 0.05
Nodes (40): usePaymentConfig(), formatNumber(), formatRial(), ClinicDetailPage(), AdminCharts, AdminDashboard(), AdminRecent, AdminStats (+32 more)
Nodes (33): formatNumber(), ClinicDetailPage(), AdminCharts, AdminDashboard(), AdminRecent, AdminStats, APPT_CLS, APPT_COLOR (+25 more)
### Community 22 - "Community 22"
Cohesion: 0.12
Nodes (10): RatingController, Like, CommentListNPlusOneTest, LikeRepository, JsonResponse, Request, User, Comment (+2 more)
Cohesion: 0.15
Nodes (9): RatingController, Like, LikeRepository, JsonResponse, Request, User, Comment, ManagerRegistry (+1 more)
### Community 23 - "Community 23"
Cohesion: 0.05
Nodes (36): Changes Applied, `config/packages/rate_limiter.yaml` (new), `config/packages/security.yaml`, Configuration Changes, CRIT-01 — Weak APP_SECRET Committed to Version Control, CRIT-02 — JWT Passphrase Hardcoded in `.env`, CRIT-03 — Payment Gateway Test Credentials Committed, CRIT-04 — Unhandled Exceptions Leaking Stack Traces (+28 more)
### Community 24 - "Community 24"
Cohesion: 0.08
Cohesion: 0.07
Nodes (3): City, Province, self
### Community 25 - "Community 25"
@@ -870,8 +877,8 @@ Cohesion: 0.05
Nodes (39): Appointment API, Error Responses, Errors, Errors, Errors, Errors, Errors, Errors (+31 more)
### Community 26 - "Community 26"
Cohesion: 0.24
Nodes (4): InsuranceController, JsonResponse, Request, User
Cohesion: 0.15
Nodes (7): InsuranceController, EntityInsurancePricing, EntityInsurancePricingRepository, JsonResponse, Request, User, ManagerRegistry
### Community 27 - "Community 27"
Cohesion: 0.06
@@ -925,6 +932,10 @@ Nodes (5): DoctorAddress, City, Doctor, Province, self
Cohesion: 0.09
Nodes (4): User, PasswordAuthenticatedUserInterface, self, UserInterface
### Community 41 - "Community 41"
Cohesion: 0.21
Nodes (5): DateOverrideOwnershipTest, DateOverride, DateOverrideRepository, Doctor, ManagerRegistry
### Community 42 - "Community 42"
Cohesion: 0.07
Nodes (29): API calls (با `useMutation`):, API موجود:, Frontend موجود:, `PATCH /api/v1/clinic/{clinicUuid}/doctor/{doctorUuid}/deactivate`, `PATCH /api/v1/clinic/{clinicUuid}/doctor/{doctorUuid}/reactivate`, UX نکات:, آپدیت `GET /api/v1/clinic/doctor-list/{clinicUuid}` (فیلدهای جدید), آپدیت interface: (+21 more)
@@ -971,7 +982,7 @@ Nodes (26): الزامات UI, باگ‌فیکس صفحه نوبت‌ها, با
### Community 53 - "Community 53"
Cohesion: 0.10
Nodes (13): AppLogRepository, ClaimItemRepository, PreRegistrationRepository, SessionServiceRepository, SmsSettingsRepository, ServiceEntityRepository, SmsSettings, ManagerRegistry (+5 more)
Nodes (13): AppLogRepository, ClaimItemRepository, DoctorInsuranceRepository, InvoiceItemRepository, PreRegistrationRepository, ServiceEntityRepository, ManagerRegistry, ManagerRegistry (+5 more)
### Community 54 - "Community 54"
Cohesion: 0.10
@@ -990,8 +1001,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.15
Nodes (8): Blog, BlogController, BlogRepository, JsonResponse, Request, User, ManagerRegistry, QueryBuilder
Cohesion: 0.28
Nodes (4): Blog, BlogRepository, ManagerRegistry, QueryBuilder
### Community 59 - "Community 59"
Cohesion: 0.22
@@ -1010,8 +1021,8 @@ Cohesion: 0.08
Nodes (25): Bulk import / export, DELETE `/api/v1/admin/specialty/{id}`, Errors, Errors, Errors, Errors, GET `/api/v1/admin/specialties`, GET `/api/v1/specialties` (+17 more)
### Community 63 - "Community 63"
Cohesion: 0.21
Nodes (5): ErrorCodes, AuthController, JsonResponse, Request, User
Cohesion: 0.22
Nodes (5): AuthController, RateLimiterFactory, JsonResponse, Request, User
### Community 64 - "Community 64"
Cohesion: 0.29
@@ -1038,8 +1049,8 @@ Cohesion: 0.15
Nodes (12): رفع بهم‌ریختگی کامل پنل ادمین روی iPhone 8 (Safari/Chrome iOS), زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی, وظایف, پروژه (+4 more)
### Community 71 - "Community 71"
Cohesion: 0.09
Nodes (20): AddForm, addSchema, ClinicsPage(), HUES_LIST, EMPTY, PreRegistration, STATUS_META, STATUS_TABS (+12 more)
Cohesion: 0.05
Nodes (37): ApiResponse, ClinicAddress, ClinicDoctorItem, ClinicInvitation, EditForm, editSchema, HUES_LIST, INV_STATUS_MAP (+29 more)
### Community 72 - "Community 72"
Cohesion: 0.09
@@ -1091,7 +1102,7 @@ Nodes (30): devDependencies, @babel/core, @babel/preset-env, @babel/preset-react
### Community 86 - "Community 86"
Cohesion: 0.08
Nodes (13): AppointmentExpiryServiceTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, ServiceItemStaffOwnershipTest, EntityManagerInterface, KernelBrowser, CommentPaginationTest (+5 more)
Nodes (13): AppointmentExpiryServiceTest, LowTierFixesTest, SendCodeMobileRateLimitTest, ClaimsListPaginationTest, ServiceItemDeleteCleanupTest, ServiceItemStaffOwnershipTest, EntityManagerInterface, KernelBrowser (+5 more)
### Community 87 - "Community 87"
Cohesion: 0.10
@@ -1162,8 +1173,8 @@ Cohesion: 0.11
Nodes (18): `AdminApiController::paymentDetail` — الان فقط GET, `MellatGateway.php` — الگوی موجود REST/SOAP (پس از کار sandbox), `PaymentGatewayInterface.php`, `PaymentManager.php` — الگوی log و transaction, برگشت/استرداد وجه ملت از پنل ادمین (bpReversalRequest / bpRefundRequest), زمینه, فایل‌های مرتبط, نکات مهم (+10 more)
### Community 104 - "Community 104"
Cohesion: 0.35
Nodes (3): TagController, JsonResponse, Request
Cohesion: 0.18
Nodes (6): TagController, TagRepository, JsonResponse, Request, ManagerRegistry, Tag
### Community 105 - "Community 105"
Cohesion: 0.11
@@ -1386,8 +1397,8 @@ Cohesion: 0.13
Nodes (13): Architecture, Auth, Backend (PHP/Symfony), Backend — `src/`, Category / Bundle system, Commands, Database, First-time setup (+5 more)
### Community 163 - "Community 163"
Cohesion: 0.11
Nodes (18): autoload, autoload-dev, psr-4, psr-4, conflict, symfony/symfony, description, extra (+10 more)
Cohesion: 0.13
Nodes (14): autoload, autoload-dev, psr-4, psr-4, conflict, symfony/symfony, description, license (+6 more)
### Community 164 - "Community 164"
Cohesion: 0.29
@@ -1410,8 +1421,8 @@ Cohesion: 0.10
Nodes (20): api.ir (استعلام هویت — Shahkar / IbanMatch), اتصال به دیتابیس‌های مستقل (الزامی), اسرار (الزامی — قبل از اولین دیپلوی), امنیت و منابع, بررسی سلامت, دامنه‌ها و CORS, دیپلوی‌های بعدی, راهنمای دیپلوی ClinicPro (Coolify + Docker Compose) (+12 more)
### Community 169 - "Community 169"
Cohesion: 0.36
Nodes (5): ClinicServiceController, JsonResponse, Request, ServiceSection, User
Cohesion: 0.31
Nodes (6): ErrorCodes, ClinicServiceController, JsonResponse, Request, ServiceSection, User
### Community 170 - "Community 170"
Cohesion: 0.13
@@ -1434,8 +1445,8 @@ Cohesion: 0.14
Nodes (14): Doctor Management, Errors, Errors, GET `/api/v1/admin/doctors`, GET `/api/v1/admin/doctors/stats`, POST `/api/v1/admin/clinic`, POST `/api/v1/admin/doctors`, POST `/api/v1/admin/doctors/{uuid}/status` (+6 more)
### Community 175 - "Community 175"
Cohesion: 0.07
Nodes (20): Contract, InsuranceOption, KIND_LABEL, ALL_STATUSES, AppointmentDetailPage(), timeOf(), Claim, ClaimItem (+12 more)
Cohesion: 0.10
Nodes (13): Claim, ClaimItem, DebtRow, InsuranceOption, KIND_LABEL, STATUS_FILTERS, STATUS_META, IbanItem (+5 more)
### Community 176 - "Community 176"
Cohesion: 0.25
@@ -1531,7 +1542,7 @@ Nodes (13): Endpoint ها, PATCH /api/v1/secretary/{uuid}, POST /api/v1/secretar
### Community 201 - "Community 201"
Cohesion: 0.15
Nodes (13): Admin API, Clinic Invitation Management, GET `/api/v1/admin/pre-registrations`, GET `/api/v1/admin/secretaries`, GET /api/v1/admin/settings, PATCH /api/v1/admin/settings, POST `/api/v1/admin/pre-registrations/{uuid}/approve`, POST `/api/v1/admin/pre-registrations/{uuid}/reject` (+5 more)
Nodes (13): Admin API, Clinic Invitation Management, GET `/api/v1/admin/secretaries`, GET /api/v1/admin/settings, GET `/api/v1/admin/settlements`, PATCH /api/v1/admin/settings, Query Parameters, Query Parameters (+5 more)
### Community 202 - "Community 202"
Cohesion: 0.15
@@ -1542,8 +1553,8 @@ 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.16
Nodes (6): ExceptionSubscriber, SecurityHeadersSubscriber, EventSubscriberInterface, ExceptionEvent, LoggerInterface, ResponseEvent
Cohesion: 0.23
Nodes (5): ExceptionSubscriber, SecurityHeadersSubscriber, EventSubscriberInterface, ExceptionEvent, ResponseEvent
### Community 205 - "Community 205"
Cohesion: 0.10
@@ -1610,8 +1621,8 @@ Cohesion: 0.23
Nodes (5): PaymentRepository, Appointment, ManagerRegistry, Payment, User
### Community 225 - "Community 225"
Cohesion: 0.03
Nodes (54): CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema, LogoUploadField(), ProvinceForm, provinceSchema (+46 more)
Cohesion: 0.06
Nodes (36): PaymentConfig, PaymentGatewayInfo, usePaymentConfig(), buildKavenegarPattern(), KavenegarGuide(), STATUS_LOG_META, Tab, TAG_FILTER_OPTIONS (+28 more)
### Community 226 - "Community 226"
Cohesion: 0.15
@@ -1626,8 +1637,8 @@ 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)
### Community 229 - "Community 229"
Cohesion: 0.17
Nodes (11): DELETE `/api/v1/representation/{uuid}`, Errors, Errors, GET `/api/v1/representation/{uuid}`, GET `/api/v1/representation/{uuid}/dashboard/yearly`, Path Parameters, Query Parameters, Representation (Agent) API (+3 more)
Cohesion: 0.15
Nodes (12): DELETE `/api/v1/representation/{uuid}`, Errors, Errors, GET `/api/v1/representation/{uuid}/dashboard/monthly`, GET `/api/v1/representation/{uuid}/dashboard/yearly`, Path Parameters, Query Parameters, Query Parameters (+4 more)
### Community 230 - "Community 230"
Cohesion: 0.35
@@ -1762,8 +1773,8 @@ Cohesion: 0.33
Nodes (4): RepresentationRepository, ManagerRegistry, Representation, User
### Community 265 - "Community 265"
Cohesion: 0.08
Nodes (27): calcFinalPrice(), EMPTY_RECORDS, EMPTY_SESSIONS, fileNumber(), getPatientName(), getPatientPhone(), InsurancePricing, MyPatientsPageInner() (+19 more)
Cohesion: 0.06
Nodes (33): Contract, InsuranceOption, KIND_LABEL, calcFinalPrice(), EMPTY_RECORDS, EMPTY_SESSIONS, fileNumber(), getPatientName() (+25 more)
### Community 266 - "Community 266"
Cohesion: 0.33
@@ -1798,7 +1809,7 @@ Cohesion: 0.18
Nodes (10): Endpoint های موجود که تغییر می‌کنند, GET /api/v1/admin/dashboard/charts?from=UNIX&to=UNIX, GET /api/v1/dashboard/clinic, GET /api/v1/dashboard/doctor, تسک ۱۶: داشبورد هوشمند — چارت + فیلتر زمانی, توضیح, زمان تخمینی, فیلتر بازه زمانی (+2 more)
### Community 274 - "Community 274"
Cohesion: 0.20
Cohesion: 0.21
Nodes (5): Authentication, ClinicPro — API Documentation Index, Error Code Reference, Modules, Standard Response Envelope
### Community 275 - "Community 275"
@@ -1902,8 +1913,8 @@ Cohesion: 0.42
Nodes (3): PreRegistrationController, JsonResponse, Request
### Community 301 - "Community 301"
Cohesion: 0.08
Nodes (31): FreeVisitPrice(), Pricing, cn(), formatDateTime(), iranMobileOptionalSchema, iranMobileSchema, isValidIranMobile(), maskMobile() (+23 more)
Cohesion: 0.04
Nodes (55): FreeVisitPrice(), Pricing, cn(), formatDateTime(), formatRial(), iranMobileOptionalSchema, iranMobileSchema, isValidIranMobile() (+47 more)
### Community 302 - "Community 302"
Cohesion: 0.12
@@ -1962,8 +1973,8 @@ Cohesion: 0.31
Nodes (3): SubscriptionPlanRepository, ManagerRegistry, SubscriptionPlan
### Community 318 - "Community 318"
Cohesion: 0.25
Nodes (8): AbstractAuthenticator, AuthenticationException, Passport, RateLimiterFactory, PasswordAuthenticator, Request, Response, TokenInterface
Cohesion: 0.28
Nodes (7): AbstractAuthenticator, AuthenticationException, Passport, PasswordAuthenticator, Request, Response, TokenInterface
### Community 319 - "Community 319"
Cohesion: 0.39
@@ -2086,8 +2097,8 @@ Cohesion: 0.11
Nodes (18): `Appointment.php`, `PaymentController::pay` (نوبت را اصلاً چک نمی‌کند), `PaymentController::startOrderPayment` (فقط status، بدون چک زمان), `renderPaymentResult` labels (برچسب `expired` ندارد), الگوی موجود انقضا (`AppointmentExpiryService`) — برای مرجع, زمینه, فایل‌های مرتبط, مشکل / هدف (+10 more)
### Community 352 - "Community 352"
Cohesion: 0.15
Nodes (5): EntityInsurancePricing, TenantInsuranceCleanupTest, EntityInsurancePricingRepository, TenantInsuranceCleanupService, ManagerRegistry
Cohesion: 0.06
Nodes (23): CityForm, citySchema, ImportError, InsuranceForm, insuranceSchema, LogoUploadField(), ProvinceForm, provinceSchema (+15 more)
### Community 354 - "Community 354"
Cohesion: 0.36
@@ -2261,10 +2272,6 @@ Nodes (6): ClaimAmountBoundsTest, ClaimsListNPlusOneTest, ClaimItem, Claim, Doct
Cohesion: 0.22
Nodes (7): initiate(), refund(), reverse(), verify(), PaymentInitResult, PaymentRefundResult, PaymentVerifyResult
### Community 399 - "Community 399"
Cohesion: 0.23
Nodes (5): AbstractMigration, Schema, Version20260609130407, Schema, Version20260614182950
### Community 401 - "Community 401"
Cohesion: 0.12
Nodes (15): `lib/utils.ts`, `SettingsPage.tsx` (ورودی‌ها ریال ذخیره می‌شوند), زمینه, فایل‌های مرتبط, مشکل / هدف, نمونهٔ نمایش (Subscription), نکات مهم, واحد پول = تومان در پنل ادمین (نمایش ÷۱۰ / ورودی ×۱۰) — ذخیره و درگاه ریال می‌ماند (+7 more)
@@ -2274,8 +2281,8 @@ Cohesion: 0.11
Nodes (17): بازطراحی معماری پرداخت — سرویس‌محور، امن، توسعه‌پذیر (Backend), تست دستی (ddev، در حالت `payment_test_mode=1`), خروجی نهایی (طبق spec — در گزارش اجرا ارائه شود), زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی (+9 more)
### Community 407 - "Community 407"
Cohesion: 0.17
Nodes (11): MessageBusInterface, MockObject, SmsLogRepository, SmsServiceLookupOnlyTest, SmsLog, SmsLogRepository, SmsMessageTemplateRepository, SmsService (+3 more)
Cohesion: 0.27
Nodes (8): MessageBusInterface, MockObject, SmsServiceLookupOnlyTest, SmsLogRepository, SmsMessageTemplateRepository, SmsService, SmsTextResolver, KavehNegarProvider
### Community 418 - "Community 418"
Cohesion: 0.17
@@ -2285,6 +2292,10 @@ Nodes (11): دیپلوی ClinicPro روی Coolify (Docker Compose), رفع اش
Cohesion: 0.33
Nodes (5): SecretaryController, DoctorSecretary, JsonResponse, Request, User
### Community 431 - "Community 431"
Cohesion: 0.23
Nodes (5): AbstractMigration, Schema, Version20260614181657, Schema, Version20260615061938
### Community 432 - "Community 432"
Cohesion: 0.12
Nodes (16): backend (آماده — فقط annotation/doc ناقص), افزودن فیلد «تاریخ شروع فعالیت» (سال تجربه) در پنل ادمین با تقویم شمسی, زمینه, فایل‌های مرتبط, فرم ساخت پزشک — `DoctorFormPage.tsx` (خط ~282), فرم ویرایش پزشک — `DoctorDetailPage.tsx` (وضعیت فعلی، بدون فیلد تاریخ), مشکل / هدف, نکات مهم (+8 more)
@@ -2293,6 +2304,10 @@ Nodes (16): backend (آماده — فقط annotation/doc ناقص), افزود
Cohesion: 0.39
Nodes (3): ClinicStaffRepository, ClinicStaff, ManagerRegistry
### Community 435 - "Community 435"
Cohesion: 0.33
Nodes (4): BlogController, JsonResponse, Request, User
### Community 439 - "Community 439"
Cohesion: 0.40
Nodes (5): 31. 🟡 `PATCH` patch, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
@@ -2302,8 +2317,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)
### Community 452 - "Community 452"
Cohesion: 0.08
Nodes (16): ClinicAddress, ClinicDoctorItem, ClinicInvitation, EditForm, editSchema, HUES_LIST, INV_STATUS_MAP, IRAN_CENTER (+8 more)
Cohesion: 0.24
Nodes (5): WalletTransactionRepository, WalletTransactionsPaginationTest, ManagerRegistry, User, WalletTransaction
### Community 456 - "Community 456"
Cohesion: 0.15
@@ -2314,8 +2329,8 @@ Cohesion: 0.47
Nodes (6): formatPersianDate(), gToJ(), jFirstDayOfWeek(), PersianDateInput(), todayGregorian(), toPersianNums()
### Community 459 - "Community 459"
Cohesion: 0.40
Nodes (5): API موجود (نیاز به تغییر ندارند), اپیک ۳ — منشی (Secretary) — تکمیل, تغییرات مورد نیاز, توضیح, نیازمندی‌های کارکردی
Cohesion: 0.33
Nodes (6): API موجود (نیاز به تغییر ندارند), اپیک‌ها, اپیک ۳ — منشی (Secretary) — تکمیل, تغییرات مورد نیاز, توضیح, نیازمندی‌های کارکردی
### Community 460 - "Community 460"
Cohesion: 0.33
@@ -2454,8 +2469,8 @@ Cohesion: 0.40
Nodes (5): addMinutes(), calcSlotCount(), hasOverlap(), parseMinutes(), SessionEditor()
### Community 500 - "Community 500"
Cohesion: 0.33
Nodes (6): API موجود (نیاز به endpoint جدید ندارد), اپیک‌ها, اپیک ۷ — داشبورد هوشمند (Smart Dashboard), تغییر مورد نیاز, توضیح, نیازمندی‌های کارکردی
Cohesion: 0.40
Nodes (5): API موجود (نیاز به endpoint جدید ندارد), اپیک ۷ — داشبورد هوشمند (Smart Dashboard), تغییر مورد نیاز, توضیح, نیازمندی‌های کارکردی
### Community 501 - "Community 501"
Cohesion: 0.40
@@ -2574,8 +2589,8 @@ Cohesion: 0.50
Nodes (4): Errors, POST `/api/v1/user/verify-code`, Request Body, Response `200`
### Community 534 - "Community 534"
Cohesion: 0.07
Nodes (25): formatDate(), IbanItem, RepMe, RepresentationSettlementPage(), RepSummary, SettlementRow, STATUS_CLASS, STATUS_LABEL (+17 more)
Cohesion: 0.13
Nodes (12): AdminUserDetail, AVATAR_COLORS, EditForm, editSchema, GENDER_LABELS, getPrimaryRole(), MARITAL_LABELS, MEDICAL_SECTIONS (+4 more)
### Community 536 - "Community 536"
Cohesion: 0.12
@@ -2658,8 +2673,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.25
Nodes (4): SmsMessageTemplateRepository, SmsTextResolver, SmsMessageTemplate, ManagerRegistry
Cohesion: 0.16
Nodes (7): SmsMessageController, SmsMessageTemplateRepository, SmsTextResolver, SmsMessageTemplate, JsonResponse, Request, ManagerRegistry
### Community 560 - "Community 560"
Cohesion: 0.50
@@ -2782,8 +2797,8 @@ Cohesion: 0.67
Nodes (3): بک‌اند, فرانت‌اند, وضعیت فعلی کد (مهم — قبل از تغییر بخوان)
### Community 618 - "Community 618"
Cohesion: 0.16
Nodes (5): ServiceItemDeleteCleanupTest, ServiceCoverageNPlusOneTest, TenantServiceCoverageRepository, ManagerRegistry, TenantServiceCoverage
Cohesion: 0.12
Nodes (6): ServiceCoverageNPlusOneTest, TenantInsuranceCleanupTest, TenantServiceCoverageRepository, TenantInsuranceCleanupService, ManagerRegistry, TenantServiceCoverage
### Community 625 - "Community 625"
Cohesion: 0.16
@@ -2870,8 +2885,8 @@ Cohesion: 0.31
Nodes (4): ClinicInvitationService, Clinic, ClinicDoctorInvitation, User
### Community 661 - "Community 661"
Cohesion: 0.39
Nodes (3): TagRepository, ManagerRegistry, Tag
Cohesion: 0.36
Nodes (3): DoctorServiceController, JsonResponse, Request
### Community 662 - "Community 662"
Cohesion: 0.29
@@ -2906,8 +2921,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 681 - "Community 681"
Cohesion: 0.48
Nodes (3): DoctorInsuranceRepository, DoctorInsurance, ManagerRegistry
Cohesion: 0.43
Nodes (3): SmsLogRepository, SmsLog, ManagerRegistry
### Community 684 - "Community 684"
Cohesion: 0.50
@@ -2922,8 +2937,8 @@ Cohesion: 0.50
Nodes (4): Errors, PATCH `/api/v1/admin/insurance/{id}`, Path Parameters, Response `200`
### Community 688 - "Community 688"
Cohesion: 0.40
Nodes (5): Errors, Path Parameters, POST `/api/v1/like/{commentUuid}`, Request Body (`application/json`), Response `200`
Cohesion: 0.48
Nodes (3): SmsSettingsRepository, SmsSettings, ManagerRegistry
### Community 689 - "Community 689"
Cohesion: 0.50
@@ -2953,10 +2968,6 @@ Nodes (3): DELETE `/api/v1/sms/template/{uuid}`, Errors, Response `200`
Cohesion: 0.67
Nodes (3): Errors, POST `/api/v1/sms/send` — ⛔ غیرفعال (Deprecated), Response `422` (همیشه)
### Community 697 - "Community 697"
Cohesion: 0.43
Nodes (3): SmsMessageController, JsonResponse, Request
### Community 698 - "Community 698"
Cohesion: 0.17
Nodes (11): رفع خطاهای ارسال پیامک کاوه‌نگار در سرور prod (431 + Idle timeout), زمینه, فایل‌های مرتبط, مشکل / هدف, نکات مهم, وضعیت فعلی, وظایف, پروژه (+3 more)
@@ -3029,10 +3040,6 @@ Nodes (4): GET /api/v1/categories/cities — شهرها, GET /api/v1/categories/
Cohesion: 0.50
Nodes (4): ۲.۱۳ نظرات، لایک و امتیازدهی, ۲.۱۳.۱ نظر (Comment), ۲.۱۳.۲ لایک (Like), ۲.۱۳.۳ امتیاز (Rate)
### Community 718 - "Community 718"
Cohesion: 0.14
Nodes (3): AppLog, LogPruneService, AppointmentExpiryService
### Community 720 - "Community 720"
Cohesion: 0.33
Nodes (3): Closure, CorsRegexEnvProcessor, EnvVarProcessorInterface
@@ -3041,10 +3048,6 @@ Nodes (3): Closure, CorsRegexEnvProcessor, EnvVarProcessorInterface
Cohesion: 0.67
Nodes (3): 34. 🔵 `POST` image logo, هدرهای اضافی, پاسخ‌ها
### Community 722 - "Community 722"
Cohesion: 0.43
Nodes (3): InvoiceItemRepository, InvoiceItem, ManagerRegistry
### Community 723 - "Community 723"
Cohesion: 0.67
Nodes (3): 42. 🔴 `DELETE` delete, هدرهای اضافی, پاسخ‌ها
@@ -3062,39 +3065,55 @@ Cohesion: 0.53
Nodes (4): Money, BillingCalculator, CoverageRule, ShareBreakdown
### Community 730 - "Community 730"
Cohesion: 0.40
Nodes (5): Errors, GET `/api/v1/representation/{uuid}/dashboard/monthly`, Path Parameters, Query Parameters, Response `200`
Cohesion: 0.53
Nodes (3): SessionServiceRepository, ManagerRegistry, SessionService
### Community 731 - "Community 731"
Cohesion: 0.40
Nodes (5): 61. 🔵 `POST` post, Request Body, مثال Request, هدرهای اضافی, پاسخ‌ها
### Community 732 - "Community 732"
Cohesion: 0.50
Nodes (4): GET `/api/v1/admin/settlements`, Query Parameters, Response `200`, Settlement Management
Cohesion: 0.40
Nodes (5): Errors, Path Parameters, POST `/api/v1/doctor/invitation/{invUuid}/respond`, Request Body, Response `200`
### Community 734 - "Community 734"
Cohesion: 0.67
Nodes (3): 29. 🟢 `GET` clinic list 🆕, پارامترهای Query, پاسخ‌ها
### Community 736 - "Community 736"
Cohesion: 0.40
Nodes (3): Props, StatTone, TONE
### Community 737 - "Community 737"
Cohesion: 0.50
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 738 - "Community 738"
Cohesion: 0.50
Nodes (4): Errors, GET `/api/v1/representation/{uuid}`, Path Parameters, Response `200`
### Community 739 - "Community 739"
Cohesion: 0.50
Nodes (4): extra, symfony, allow-contrib, require
## Knowledge Gaps
- **3964 isolated node(s):** `ALLOWED_ROLES`, `Pricing`, `ImageCropModalProps`, `TenantInsurance`, `CoverageRow` (+3959 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **142 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
- **146 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **Why does `BaseController` connect `Community 108` to `Community 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 169`, `Community 300`, `Community 308`, `Community 697`, `Community 58`, `Community 59`, `Community 63`, `Community 64`, `Community 75`, `Community 77`, `Community 607`, `Community 227`, `Community 230`, `Community 104`, `Community 107`, `Community 109`, `Community 245`, `Community 121`, `Community 122`, `Community 252`?**
_High betweenness centrality (0.027) - this node is a cross-community bridge._
- **Why does `ApiTestCase` connect `Community 86` to `Community 397`, `Community 22`, `Community 535`, `Community 541`, `Community 41`, `Community 562`, `Community 565`, `Community 573`, `Community 574`, `Community 575`, `Community 594`, `Community 82`, `Community 728`, `Community 733`, `Community 352`, `Community 609`, `Community 484`, `Community 618`, `Community 497`, `Community 371`?**
- **Why does `BaseController` connect `Community 108` to `Community 6`, `Community 138`, `Community 139`, `Community 14`, `Community 654`, `Community 655`, `Community 15`, `Community 20`, `Community 661`, `Community 22`, `Community 26`, `Community 164`, `Community 295`, `Community 424`, `Community 169`, `Community 300`, `Community 559`, `Community 435`, `Community 308`, `Community 59`, `Community 63`, `Community 64`, `Community 75`, `Community 77`, `Community 607`, `Community 227`, `Community 230`, `Community 104`, `Community 107`, `Community 109`, `Community 245`, `Community 121`, `Community 122`, `Community 252`?**
_High betweenness centrality (0.031) - this node is a cross-community bridge._
- **Why does `ApiTestCase` connect `Community 86` to `Community 397`, `Community 535`, `Community 541`, `Community 41`, `Community 562`, `Community 565`, `Community 573`, `Community 574`, `Community 575`, `Community 452`, `Community 594`, `Community 82`, `Community 728`, `Community 733`, `Community 735`, `Community 609`, `Community 484`, `Community 618`, `Community 497`, `Community 371`?**
_High betweenness centrality (0.020) - this node is a cross-community bridge._
- **Why does `Version20260705070546` connect `Community 646` to `Community 431`?**
_High betweenness centrality (0.019) - this node is a cross-community bridge._
- **Why does `Version20260705070546` connect `Community 646` to `Community 399`?**
_High betweenness centrality (0.017) - this node is a cross-community bridge._
- **What connects `ALLOWED_ROLES`, `Pricing`, `ImageCropModalProps` to the rest of the system?**
_3964 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `Community 0` be split into smaller, more focused modules?**
_Cohesion score 0.05200501253132832 - nodes in this community are weakly interconnected._
_Cohesion score 0.055152394775036286 - nodes in this community are weakly interconnected._
- **Should `Community 1` be split into smaller, more focused modules?**
_Cohesion score 0.028985507246376812 - nodes in this community are weakly interconnected._
- **Should `Community 2` be split into smaller, more focused modules?**
@@ -0,0 +1 @@
{"nodes": [{"id": "users_hamed_pj_my_pj_clinic_pro_clinicpro_migrations_version20260708083446_php", "label": "Version20260708083446.php", "file_type": "code", "source_file": "migrations/Version20260708083446.php", "source_location": "L1"}, {"id": "migrations_version20260708083446_version20260708083446", "label": "Version20260708083446", "file_type": "code", "source_file": "migrations/Version20260708083446.php", "source_location": "L13"}, {"id": "abstractmigration", "label": "AbstractMigration", "file_type": "code", "source_file": "", "source_location": ""}, {"id": "migrations_version20260708083446_version20260708083446_getdescription", "label": ".getDescription()", "file_type": "code", "source_file": "migrations/Version20260708083446.php", "source_location": "L15"}, {"id": "migrations_version20260708083446_version20260708083446_up", "label": ".up()", "file_type": "code", "source_file": "migrations/Version20260708083446.php", "source_location": "L20"}, {"id": "schema", "label": "Schema", "file_type": "code", "source_file": "migrations/Version20260708083446.php", "source_location": "L20"}, {"id": "migrations_version20260708083446_version20260708083446_down", "label": ".down()", "file_type": "code", "source_file": "migrations/Version20260708083446.php", "source_location": "L26"}], "edges": [{"source": "users_hamed_pj_my_pj_clinic_pro_clinicpro_migrations_version20260708083446_php", "target": "schema", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L7", "weight": 1.0}, {"source": "users_hamed_pj_my_pj_clinic_pro_clinicpro_migrations_version20260708083446_php", "target": "abstractmigration", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L8", "weight": 1.0}, {"source": "users_hamed_pj_my_pj_clinic_pro_clinicpro_migrations_version20260708083446_php", "target": "migrations_version20260708083446_version20260708083446", "relation": "contains", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L13", "weight": 1.0}, {"source": "migrations_version20260708083446_version20260708083446", "target": "abstractmigration", "relation": "inherits", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L13", "weight": 1.0}, {"source": "migrations_version20260708083446_version20260708083446", "target": "migrations_version20260708083446_version20260708083446_getdescription", "relation": "method", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L15", "weight": 1.0}, {"source": "migrations_version20260708083446_version20260708083446", "target": "migrations_version20260708083446_version20260708083446_up", "relation": "method", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L20", "weight": 1.0}, {"source": "migrations_version20260708083446_version20260708083446_up", "target": "schema", "relation": "references", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L20", "weight": 1.0, "context": "parameter_type"}, {"source": "migrations_version20260708083446_version20260708083446", "target": "migrations_version20260708083446_version20260708083446_down", "relation": "method", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L26", "weight": 1.0}, {"source": "migrations_version20260708083446_version20260708083446_down", "target": "schema", "relation": "references", "confidence": "EXTRACTED", "source_file": "migrations/Version20260708083446.php", "source_location": "L26", "weight": 1.0, "context": "parameter_type"}], "raw_calls": [{"caller_nid": "migrations_version20260708083446_version20260708083446_up", "callee": "addSql", "is_member_call": true, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/migrations/Version20260708083446.php", "source_location": "L23", "receiver": null}, {"caller_nid": "migrations_version20260708083446_version20260708083446_down", "callee": "addSql", "is_member_call": true, "source_file": "/Users/hamed/pj/my_pj/clinic_pro/clinicpro/migrations/Version20260708083446.php", "source_location": "L29", "receiver": null}]}
@@ -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
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
+841 -605
View File
File diff suppressed because it is too large Load Diff
+23 -18
View File
@@ -190,8 +190,8 @@
"semantic_hash": ""
},
"assets/admin/pages/CategoriesPage.tsx": {
"mtime": 1782974127.331514,
"ast_hash": "43d7e427a556469e4374224c4e665117",
"mtime": 1783499911.7162325,
"ast_hash": "e82688eee9528ece183af52ac18e32c6",
"semantic_hash": ""
},
"assets/admin/pages/ClaimsPage.tsx": {
@@ -400,8 +400,8 @@
"semantic_hash": ""
},
"assets/admin/types/index.ts": {
"mtime": 1783456035.9569273,
"ast_hash": "576af13ec86ba70117b1a421e6044513",
"mtime": 1783499946.4879165,
"ast_hash": "edd28014dfe716c5bdaf1743e17bfea4",
"semantic_hash": ""
},
"assets/app.js": {
@@ -1295,13 +1295,13 @@
"semantic_hash": ""
},
"src/Location/Controller/LocationController.php": {
"mtime": 1782974061.7243073,
"ast_hash": "eeba5749c527b2712549c2dda539e368",
"mtime": 1783499628.8124676,
"ast_hash": "6d7efcacce3e5a1af0c58bd41eaeb554",
"semantic_hash": ""
},
"src/Location/Entity/City.php": {
"mtime": 1782974046.9918911,
"ast_hash": "b37a5c9d79443b32709a30a3decffd30",
"mtime": 1783499619.3652577,
"ast_hash": "2fd20499f23ea90b3c21dbf14736474f",
"semantic_hash": ""
},
"src/Location/Entity/Province.php": {
@@ -2405,8 +2405,8 @@
"semantic_hash": ""
},
"docs/api/location.md": {
"mtime": 1782974277.4647317,
"ast_hash": "237d13c1f44f23001d6e9ab287b80898",
"mtime": 1783499999.9915078,
"ast_hash": "ab3a2fc14a40c72decd5f1dc753e4a40",
"semantic_hash": ""
},
"docs/api/patient.md": {
@@ -3420,18 +3420,18 @@
"semantic_hash": ""
},
"tests/Category/CategoryImportTest.php": {
"mtime": 1782839178.8459258,
"ast_hash": "203f5500749a42f0be4f33dc2e3dbb1f",
"mtime": 1783499837.163828,
"ast_hash": "6ddcb6489cc74405678d6c67d8a760bb",
"semantic_hash": ""
},
"docs/api/category-import.md": {
"mtime": 1782844030.4935105,
"ast_hash": "d7eaf7bd2002ca82b3a95e16b0eb34dd",
"mtime": 1783500035.987979,
"ast_hash": "b9caf621738f67ba7b5a8eac64053760",
"semantic_hash": ""
},
"data/seed/cities.json": {
"mtime": 1783069922.2119036,
"ast_hash": "24bc6b07dfdf32298ef64a5dba0effbc",
"mtime": 1783499720.4733326,
"ast_hash": "8fa9399cc8295b14436b9e0a7d8daa13",
"semantic_hash": ""
},
"data/seed/doctor_services.json": {
@@ -3455,8 +3455,8 @@
"semantic_hash": ""
},
"src/Category/Service/CategoryImporter.php": {
"mtime": 1782974082.771482,
"ast_hash": "daaeddb090469fda67b5bdf08c52cacb",
"mtime": 1783499652.5651908,
"ast_hash": "12fc348a636eba9c7b689eeb1badb6d0",
"semantic_hash": ""
},
".claude/prompt/production-fixes-cors-payment-gateways.md": {
@@ -3748,5 +3748,10 @@
"mtime": 1783497352.078513,
"ast_hash": "e9c3240a7a86744c5e2d3119388c9119",
"semantic_hash": ""
},
"migrations/Version20260708083446.php": {
"mtime": 1783499693.0322785,
"ast_hash": "ecd96845ea3d18996543917b487864c5",
"semantic_hash": ""
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260708083446 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE cities ADD title VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE cities DROP title');
}
}
+10 -1
View File
@@ -38,13 +38,21 @@ class CategoryImporter
public function exportAll(string $bundle): array
{
$table = self::TABLES[$bundle];
$rows = $this->db->fetchAllAssociative('SELECT * FROM ' . $table . ' ORDER BY id ASC');
// cities export must match the shape nobat724_front/data/city.json consumes:
// social_media as an object (not the raw JSON string) and province_name included.
$sql = $bundle === 'cities'
? 'SELECT c.*, p.name AS province_name FROM cities c LEFT JOIN provinces p ON p.id = c.province_id ORDER BY c.id ASC'
: 'SELECT * FROM ' . $table . ' ORDER BY id ASC';
$rows = $this->db->fetchAllAssociative($sql);
foreach ($rows as &$r) {
foreach (['id', 'status', 'weight', 'parent_id', 'specialty_id', 'province_id', 'representation_id'] as $intCol) {
if (array_key_exists($intCol, $r) && $r[$intCol] !== null) {
$r[$intCol] = (int) $r[$intCol];
}
}
if ($bundle === 'cities' && is_string($r['social_media'] ?? null)) {
$r['social_media'] = json_decode($r['social_media'], true);
}
}
unset($r);
return $rows;
@@ -143,6 +151,7 @@ class CategoryImporter
break;
case 'cities':
$row['site_name'] = self::optStr($raw['site_name'] ?? null);
$row['title'] = self::optStr($raw['title'] ?? null);
$row['province_id'] = self::nullableId($raw['province_id'] ?? null, $add, 'province_id');
$row['representation_id'] = self::nullableId($raw['representation_id'] ?? null, $add, 'representation_id');
$row['contact_phone'] = self::optStr($raw['contact_phone'] ?? null);
@@ -224,6 +224,7 @@ class LocationController extends BaseController
if (array_key_exists('representation_id', $data))
$city->setRepresentationId($data['representation_id'] !== null ? (int) $data['representation_id'] : null);
if (array_key_exists('site_name', $data)) $city->setSiteName($data['site_name']);
if (array_key_exists('title', $data)) $city->setTitle($data['title']);
if (array_key_exists('contact_phone', $data)) $city->setContactPhone($data['contact_phone']);
if (array_key_exists('email', $data)) $city->setEmail($data['email']);
if (array_key_exists('description', $data)) $city->setDescription($data['description']);
+6
View File
@@ -27,6 +27,9 @@ class City
#[ORM\Column(name: 'site_name', type: 'string', length: 255, nullable: true)]
private ?string $siteName = null;
#[ORM\Column(type: 'string', length: 255, nullable: true)]
private ?string $title = null;
#[ORM\Column(type: 'smallint')]
private int $status = 1;
@@ -78,6 +81,7 @@ class City
public function getUuid(): string { return $this->uuid; }
public function getName(): string { return $this->name; }
public function getSiteName(): ?string { return $this->siteName; }
public function getTitle(): ?string { return $this->title; }
public function getStatus(): int { return $this->status; }
public function getWeight(): int { return $this->weight; }
public function getProvince(): ?Province { return $this->province; }
@@ -94,6 +98,7 @@ class City
public function setName(string $v): self { $this->name = $v; return $this; }
public function setSiteName(?string $v): self { $this->siteName = $v; return $this; }
public function setTitle(?string $v): self { $this->title = $v; return $this; }
public function setStatus(int $v): self { $this->status = $v; return $this; }
public function setWeight(int $v): self { $this->weight = $v; return $this; }
public function setProvince(?Province $v): self { $this->province = $v; return $this; }
@@ -115,6 +120,7 @@ class City
'uuid' => $this->uuid,
'name' => $this->name,
'site_name' => $this->siteName,
'title' => $this->title,
'status' => $this->status,
'weight' => $this->weight,
'province_id' => $this->province?->getId(),
+5 -2
View File
@@ -614,6 +614,7 @@ if (btn2)
btn2.addEventListener('click', openRegModal);
if (btn3)
btn3.addEventListener('click', function (e) {
e.preventDefault();
@@ -753,11 +754,11 @@ msg.style.border = type === 'success' ? '1px solid #bbf7d0' : '1px solid #fecaca
<div class="foot-contact">
<div class="fl">
<svg viewbox="0 0 24 24" fill="none"><path d="M12 21s-7-5.2-7-11a7 7 0 0 1 14 0c0 5.8-7 11-7 11Z" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/><circle cx="12" cy="10" r="2.6" stroke="currentColor" stroke-width="1.7"/></svg>
<span>یاسوج، مهریان، خیابان شهید ستاره شیرازی، خیابان امام‌زاده احمد، پلاک ۸</span>
<span>یاسوج، مهریان، خیابان شهید ستاره شیرازی، خیابان امام‌زاده احمد، پلاک ۸ شرکت توسعه فناوری اطلاعات حامی</span>
</div>
<div class="fl">
<svg viewbox="0 0 24 24" fill="none"><path d="M4 6.5C4 5 5 4 6.5 4h2c.6 0 1.1.4 1.3 1l1 3c.2.6 0 1.2-.5 1.6L9 11c1 2 2.5 3.5 4.5 4.5l1.4-1.3c.4-.4 1-.6 1.6-.4l3 1c.6.2 1 .7 1 1.3v2c0 1.5-1 2.5-2.5 2.4C10.5 20 4 13.5 4 6.5Z" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/></svg>
<a href="tel:07491012178" style="font-variant-numeric:tabular-nums" dir="ltr">۰۷۴۹۱۰۱۲۱۷۸</a>
<a href="tel:07491012178" style="font-variant-numeric:tabular-nums" dir="ltr">02191550875</a>
</div>
<div class="fl">
<svg viewbox="0 0 24 24" fill="none"><rect x="3" y="5" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.7"/><path d="m4 7 8 5 8-5" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/></svg>
@@ -829,6 +830,7 @@ if (e.target.tagName === 'A')
navLinks.classList.remove('open');
});
}
@@ -933,6 +935,7 @@ if (! slot)
return;
var a = document.createElement('a');
a.setAttribute('referrerpolicy', 'origin');
a.target = '_blank';
+33
View File
@@ -78,6 +78,39 @@ class CategoryImportTest extends ApiTestCase
$this->assertContains('parent_id', $fields);
}
public function testCityTitleAndSocialMediaRoundTripThroughImportExport(): void
{
$admin = $this->createUser(['ROLE_ADMIN']);
$this->authJson('POST', '/api/v1/admin/categories/cities/import', $admin, [
[
'id' => 95001, 'name' => 'شهر تست', 'status' => 1, 'weight' => 0,
'site_name' => 'تست نوبت',
'title' => 'نوبت‌دهی آنلاین پزشکان شهر تست | تست نوبت',
'slogan' => 'شعار تست',
'keywords' => 'کلمه یک, کلمه دو',
'province_id' => null,
'social_media' => ['instagram' => 'test_nobat'],
],
]);
$this->assertSame(200, $this->responseCode());
$this->assertSame(
'نوبت‌دهی آنلاین پزشکان شهر تست | تست نوبت',
$this->db()->fetchOne('SELECT title FROM cities WHERE id = 95001'),
);
// export must round-trip lossless in the shape nobat724_front/data/city.json uses
$body = $this->authJson('GET', '/api/v1/admin/categories/cities/export', $admin);
$row = null;
foreach ($body['data'] as $r) {
if (($r['id'] ?? null) === 95001) { $row = $r; break; }
}
$this->assertNotNull($row);
$this->assertSame('نوبت‌دهی آنلاین پزشکان شهر تست | تست نوبت', $row['title']);
$this->assertSame(['instagram' => 'test_nobat'], $row['social_media']);
$this->assertArrayHasKey('province_name', $row);
}
public function testNonAdminIsForbidden(): void
{
$user = $this->createUser(['ROLE_USER']);