Fill the three previously-placeholder settings sections so every menu item
is now a real page inside the settings shell:
- حساب کاربری: new authenticated POST /api/v1/user/change-password
(verifies current password, ≥8 chars, must differ) + account page with a
profile summary and change-password form.
- برچسبها: new per-tenant TenantTag domain (entity/repo/controller +
migration) with tenant-scoped CRUD at /api/v1/tenant-tag(s), plus a tags
management page (list + color + add/edit/delete).
- مدیریت نوبت دهی: export the existing WeeklyScheduleTab from
DoctorDetailPage and reuse it in a standalone AppointmentSettingsPage
(current doctor's uuid + addresses).
Wire all three menu entries to their routes. Backend covered by PHPUnit
(change-password, tenant-tag CRUD + ownership); FE covered by Vitest.
API docs updated (auth.md, tag.md).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wrap the existing settings-area pages — doctor profile (مدیریت پزشک),
insurance pricing (بیمه), payment report (پرداخت), SMS wallet (پیامکها),
secretaries (منشی) and clinic info (مطب) — in SettingsLayout so they appear
under the settings sub-navigation like the Figma design, with the matching
menu item highlighted. Wire the doctor/clinic menu entries to their routes.
The نوبتدهی / برچسبها / حساب کاربری entries stay as disabled placeholders
until they have their own pages/designs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Created JSON representation for ServiceItemMultiStaffTest.php, detailing nodes, edges, and raw calls.
- Created JSON representation for Version20260713093327.php migration, including nodes, edges, and raw calls.
Render the clinic services page (sections → services) inside the settings
sub-navigation shell (SettingsLayout, "خدمات" active) to match the Figma
settings design. Restyle section cards to show the service count and a
status toggle with edit/delete actions, and service cards with labelled
price/duration and personnel chips.
A service can now have multiple personnel: add an additive many-to-many
ServiceItem↔ClinicStaff (staffMembers, EAGER) while keeping the legacy
single `staff` column mirrored for backward compatibility. Endpoints accept
`staff_uuids[]` (falling back to the legacy single `staff_uuid`) and return
`staff_members[]`; the section list now reports `items_count`.
Backfill-safe: pre-migration rows fall back to the single staff in toArray.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a doctor/clinic settings sub-navigation shell (SettingsLayout) with
"خرید اشتراک" as its first section, plus a mobile settings-list page.
Rebuild the plan-selection page with a per-plan billing-period toggle,
single price, most-popular badge and a current-plan status banner.
Add a payment-success page that reads the gateway return params
(?payment_uuid&status), shows the transaction receipt and the newly
active plan, and redirects to the plans page with a toast on any
non-success status.
Frontend only — reuses the existing /api/v1/subscription/* and
/api/v1/subscription-payment endpoints; no backend or API-doc changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Created a new JSON file for skills related to Figma features, including nodes and edges representing the structure and relationships of skills.
- Added another JSON file for the PatientUpdateProfileTest, detailing the test structure, methods, and their relationships with other components in the codebase.
Backend:
- Add profile columns field_of_study, province_id, city_id, postal_code,
referral_source (UserProfile + migration).
- Extend PATCH /api/v1/patient/{uuid} to persist all demographic fields
and return them in the patient profile payload.
- Support editable mobile (login identifier): validation, uniqueness,
User.setMobileNumber, new ERR_PROFILE_002.
- Update docs/api/patient.md.
Frontend:
- New reusable Input, Field, and PatientRecordInfoForm (RHF + Zod).
- usePatient/useUpdatePatient hooks and patientForm mapping helpers.
- Extend the existing "info" tab in MyPatientsPage to the full field set
via the shared form (province/city/insurance options, Jalali date).
Tests: Patient entity + PATCH integration (PHPUnit); form, hooks, and
mapping helpers (Vitest).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Introduced `PatientAppointment` interface to define appointment structure.
- Implemented `findByUserAndDoctorIds` method in `AppointmentRepository` to retrieve appointments for a user filtered by doctor IDs.
- Added `acceptedDoctorIdsByClinic` method in `ClinicDoctorInvitationRepository` to get accepted doctor IDs for a clinic.
- Created new endpoint in `PatientController` to fetch appointments for a patient, ensuring only relevant doctors' appointments are displayed.
Restyle PatientCard to the Figma patient card: overflow menu (edit/view),
name + orange user avatar, dividers, file number + phone rows, tags row.
Avatar now a solid accent circle with user icon.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Restructure to Figma: 4 stat cards (today appts, today/week payments,
total patients) -> two charts (revenue area + patient-count vertical
bars) -> today appointments table. Add today/week payments, total
patients, and 7-day revenue/appointments series to doctor + clinic
dashboard endpoints. Add SvgVBars chart. Update dashboard.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Restructure clinic-services from two-pane to Figma two-view flow:
sections card grid (name, edit, activate/deactivate, 'بخش جدید' modal) →
click a section → its services card grid with breadcrumb back. Service
card matches Figma: overflow menu, active badge, base price, average
time badge, staff chip. Add duration_minutes to ServiceItem (migration
+ create/update + form field). Update clinic-services.md.
(Version20260713050014 syncs pre-existing entity/schema drift.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replicate the Figma patient-service card chrome for catalog items:
overflow menu top-start, status square (active/inactive), name + section
subtitle, label:value rows, price, full-width primary action. Adapts the
frame's fields to catalog data (staff, insurance, price).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Convert clinic service items from rows to a Figma-style card grid using
cp-card/tokens; drop hardcoded oklch tint. Functionality unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move purple (h277 c0.177 = #5559CE) to first HUES entry so fresh users
get the tauri purple by default; color picker retained.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set primary to tauri purple, bg #fafafa/#1f1d2b, dark surface #222433,
text #D7D8ED/#A1A1A1. Sync sRGB fallbacks and @supports oklch block.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- national code: full Iranian checksum (control digit + reject all-same),
not just length 10 → "کد ملی نامعتبر است" on failure
- IBAN (شبا): validate IR + 24 digits + mod-97; input forces uppercase,
strips to IR/digits, maxLength 26
- Persian/Arabic digits converted to Latin on input and before validation
so the field behaves with an English/numeric keyboard
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- DoctorClaimController: ALTCHA CaptchaGuard on /claim (dev no-op via
ALTCHA_ENABLED=false); optional `mobile` field must match the logged-in
user's number (422 ERR_CONFLICT_001 on mismatch)
- DoctorController::delete: now IS_AUTHENTICATED_FULLY — admin (any) or the
owner of a claimed profile (IDOR-guarded); FK appointment guard kept
- DoctorDetailPage address map: MapController calls map.invalidateSize()
before flyTo (fixes needing to pick a city twice on a freshly-mounted map);
geocode retries once (nominatim empty/429 on first hit)
- tests: mobile mismatch, owner-delete allowed + others 403, unclaimed not
deletable by random user
- docs: doctor-claim.md (mobile+captcha), doctor.md (delete permission)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per request, doctors created via import now set active_doctor_appointment
= true (was false). DoctorImportTest updated to assert active.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Root cause of "دکتر دکتر …" (and ellipsis-truncated "…نی") in admin: IRIMC
names already contain the «دکتر» title, while the panel renders «دکتر {name}».
Convention is to store the bare name.
- DoctorImportService: normalize name via PersianText::stripDoctorTitle
(also fixes ي/ی, ك/ک, half-space)
- PersianText::stripDoctorTitle now strips consecutive «دکتر دکتر …» prefixes
- app:doctors:fix-irimc-names: one-off backfill for existing source='irimc'
rows (dry-run supported) — fixed 340 rows
- app:doctors:purge: FK-safe full wipe of doctors + all dependent tables +
orphan surrogate users, for a clean test DB (dry-run default, --force to
apply, prod-guarded)
- tests: PersianTextTest cases for the title stripping; DoctorImportTest
asserts stored name has no «دکتر» prefix
- docs/api/doctor-import.md: name convention + the two new commands
Verified: import "دکتر صفورا حجازی نیا" → stored "صفورا حجازی نیا" → panel
shows single «دکتر صفورا حجازی نیا».
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>