# ارسال city_id دامنه‌ی جاری هنگام رزرو نوبت

## پروژه

`nobat724_front` (سایت عمومی). **cross-repo**: پرامپت همتا `clinicpro/.claude/prompt/representation-domain-guard-dashboard-settlement.md` است که **اول** اجرا می‌شود (backend فیلد `city_id` را در `POST /api/v1/appointment` می‌پذیرد و نماینده‌ی شهر را برای گاردِ پورسانت ذخیره می‌کند). این پرامپت front را بعد از آن اجرا کن.

## زمینه

هر شهر دامنه‌ی جداگانه دارد و از `data/city.json` تشخیص داده می‌شود (`getStateInfo().matchedCity` سرور، `ProvinceProvider`/`window.location.hostname` کلاینت). هر شهر `id` دارد (مثلاً اراک `129`) و فیلد `representation_id`. نماینده در backend به همان `city_id` خورده است.

برای اینکه backend بتواند تشخیص دهد نوبت از **دامنه‌ی نماینده** ثبت شده (شرط لازم برای محاسبه‌ی پورسانت)، سایت باید `city_id` دامنه‌ی جاری را در payload رزرو بفرستد.

## مشکل / هدف

در حال حاضر `appointmentPayload` در `components/appointment/detail/SubmitData.js` فیلد `city_id` ندارد. باید `matchedCity.id` دامنه‌ی جاری به آن اضافه شود.

## فایل‌های مرتبط

| فایل | نقش |
|------|-----|
| `nobat724_front/components/appointment/detail/SubmitData.js` | ساخت `appointmentPayload` و فراخوانی `postAppointment` |
| `nobat724_front/context/ProvinceProvider.js` | منبع client-side شهر جاری (`useProvince`) |
| `nobat724_front/lib/getStateInfo.js` | منبع server-side شهر (`matchedCity.id`) |
| `nobat724_front/data/city.json` | `id` و `domain` هر شهر |
| `nobat724_front/services/response.js` | `postAppointment` (بدون تغییر؛ فقط payload عوض می‌شود) |

## وضعیت فعلی

`components/appointment/detail/SubmitData.js` (پس از تغییرِ قبلیِ national_code/gender):
```js
const appointmentPayload = {
  doctor_uuid: doctor.uuid,
  slot_start: selectedSlot.start,
  slot_end: selectedSlot.end,
  for_self: !isForAnother,
  note: data?.patient_reason?.value || "",
  patient_national_code: data?.national_code?.value || "",
  patient_gender: data?.gender?.value?.id || data?.gender?.value || "",
  ...(isForAnother ? { patient_name: ..., patient_mobile: ..., patient_reason: ... } : {}),
};
const res = await request.postAppointment(appointmentPayload);
```

`ProvinceProvider` (client) شهر را از `window.location.hostname` تشخیص می‌دهد. باید بررسی شود چه چیزی expose می‌کند — اگر فقط `isProvinceInclude` دارد، یک getter برای `matchedCity` (یا حداقل `matchedCity.id`) به آن اضافه شود تا کامپوننت کلاینت به `city.id` دسترسی داشته باشد.

## وظایف

### ۱. در دسترس قرار دادن city.id در کلاینت

اگر `useProvince()` فقط `isProvinceInclude` می‌دهد، آن را گسترش بده تا `matchedCity` (یا `cityId`) هم برگرداند. منطق تطبیق همان `getStateInfo` است: `subdomain = hostname.split('.')[0]`، سپس `citiesData.find(c => c.domain.split('.')[0] === subdomain)`. (در dev، `HOST=yazd-nobat.localhost` ⇒ subdomain = `yazd-nobat`.)

### ۲. افزودن city_id به payload رزرو

در `SubmitData.js`:
```js
import { useProvince } from "@/context/ProvinceProvider";
// ...
const { matchedCity } = useProvince();   // یا cityId مستقیم

const appointmentPayload = {
  doctor_uuid: doctor.uuid,
  slot_start: selectedSlot.start,
  slot_end: selectedSlot.end,
  for_self: !isForAnother,
  note: data?.patient_reason?.value || "",
  patient_national_code: data?.national_code?.value || "",
  patient_gender: data?.gender?.value?.id || data?.gender?.value || "",
  city_id: matchedCity?.id ?? null,   // ← جدید
  ...(isForAnother ? { ... } : {}),
};
```

## نکات مهم

- `city_id` همان `matchedCity.id` از `city.json` است (نه `representation_id` که ممکن است null باشد). backend خودش نماینده‌ی آن شهر را پیدا می‌کند.
- اگر شهر تشخیص داده نشد یا نماینده نداشت، `city_id` خالی/null ⇒ backend پورسانت محاسبه نمی‌کند. این رفتار مطلوب است؛ خطا نده.
- مبلغ پرداختیِ کاربر تغییر نمی‌کند؛ این فقط متادیتای رزرو است.
- App Router + کامپوننت کلاینت: `useProvince` فقط در client component کار می‌کند؛ `SubmitData` کلاینت است.
- بعد از تغییر: `npm run build` برای صحت. قرارداد `POST /api/v1/appointment` در `clinicpro/docs/api/appointment.md` (سمت backend) به‌روز است؛ فقط مطمئن شو نام فیلد `city_id` با backend یکی است.
