Commit Graph
100 Commits
Author SHA1 Message Date
hamed 0f3bf68fdd feat(blog): refactor author data retrieval to handle potential missing authors 2026-06-19 00:35:07 +03:30
hamed 1e45b12aec feat(doctor): add filtering logic for clinic doctor list with pagination and sorting 2026-06-18 19:16:04 +03:30
hamed 89a8622e6a feat(clinic): enhance clinic detail response with location map and additional fields 2026-06-18 15:21:24 +03:30
hamed 4bb65c7502 feat(clinic): enhance clinic listing with additional details and address information
- Updated the clinic API response to include new fields: title, phone, logo, images_clinic, doctors_count, city, state, 24_7, and field_working_days.
- Modified the ClinicController to fetch and include city and state information based on the clinic's address.
- Refactored the toListArray method in the Clinic entity to accept city and state parameters.
- Added a new method in the ClinicRepository to retrieve city and province names for each clinic based on their address.
2026-06-18 15:03:36 +03:30
hamedandClaude Opus 4.8 eb576b7d98 chore: stop tracking .env and ignore it
.env holds credentials (API_DOC_PASSWORD, secrets) and must not be in git.
Removed it from tracking (file kept on disk) and added .env to .gitignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 15:03:01 +03:30
hamed fa41c15bb6 feat(clinic): update filtering logic to use clinic address for city/state 2026-06-18 09:06:36 +03:30
hamedandClaude Opus 4.8 404dd03247 feat(specialty): public doctor-counts endpoint (per city)
Add GET /api/v1/specialties/doctor-counts?city_id= returning every active
specialty with number_of_doctors (distinct doctors via doctor_specialties,
scoped by doctor_cities when city_id is given). Make /api/v1/specialties GET
public. Powers the /specialties page count. Docs updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 22:27:27 +03:30
hamedandClaude Opus 4.8 28011160a2 feat(appointment): include doctor specialties and clinic address in toArray
The appointment detail view needs the doctor's specialty and the clinic
address/phone/map, which toArray didn't return. Add doctor.specialties[] and
a top-level `address` (the doctor's first address via DoctorAddress::toArray —
address, telephone, map). Additive only; existing keys unchanged. Docs updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 12:01:32 +03:30
hamedandClaude Opus 4.8 b60dbdadba fix(profile): persist & expose birthday as a single Unix field
Birthday was never saved (hydrate forced null) and not returned in a form the
clients use. Now:
- hydrate stores the incoming `birthday` (Unix) into date_of_birth; `birthday`
  takes priority over a stray `date_of_birth: null` in the same payload so it
  can't be wiped.
- toArray exposes a single `birthday` (Unix) key — drop the duplicate
  `date_of_birth` output to avoid overlap.
- admin UserDetailPage reads profile.birthday (formatDate renders Jalali).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:42:31 +03:30
hamedandClaude Opus 4.8 800f9ad8cd fix(profile): sync User.real_name from profile name on create/update
When a user completes their profile (POST/PATCH /api/v1/user-profile), the
name was only stored on the profile (label/family) and User.real_name stayed
empty — so users who registered via booking showed with no name in the admin
user list. hydrate() now mirrors the profile's full name (label + family)
onto the owning User.realName, persisted in the same flush.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 10:45:29 +03:30
hamedandClaude Opus 4.8 492a7df989 feat(payment): canceled status, manageable origin allowlist, CORS subdomains
Unify and harden the payment flow (same API for the main site and all
consumer sites; per-client difference is only frontend_address).

- Payment gains STATUS_CANCELED. Gateways distinguish user-cancel from
  failure (Mellat ResCode=17, SEP CanceledByUser, mock cancel=1) via a new
  PaymentVerifyResult::canceled flag; callback sets canceled vs failed and
  skips the circuit-breaker on cancel.
- Expiry job now cancels the pending payment when a booking lapses
  (AppointmentExpiryService + PaymentRepository::findPendingByAppointment).
- frontend_address allowlist is read from the payment_allowed_frontend_hosts
  site setting (manageable via PATCH /api/v1/admin/settings), falling back to
  the ALLOWED_FRONTEND_HOSTS env var — so a new consumer site needs no code
  change.
- .env: broaden CORS_ALLOW_ORIGIN to city subdomains (*.localhost /
  *.clinic-pro.ddev.site) and add yazd-nobat.localhost to ALLOWED_FRONTEND_HOSTS.
- Update docs/api/payment.md and docs/api/admin.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 10:06:43 +03:30
hamedandClaude Opus 4.8 45242a3128 feat(rating): multi-dimensional ratings, rich comments, eligibility guard
Rebuild the doctor rating/review system to power the public site's rich
review UI, and restrict who may submit.

Ratings:
- Rate entity holds five 0–100 dimensions (waiting time, diagnosis
  accuracy, behaviour, cleanliness, expertise) instead of a single score.
- GET /rate/{uuid} returns aggregate {point, satisfaction, averages[]}.
- POST /rate upserts all five dimensions and returns the new aggregate.

Comments:
- Comment gains parent/replies (threaded) and a rich toArray with author,
  like_status (like/dislike counts + current user's vote) and nested
  approved replies. POST /comment accepts {comment, parent}.
- Likes are directional (value 1=like, -1=dislike) with toggle/replace;
  POST /like/{uuid} returns like_count/dislike_count/current_user_like.

Eligibility:
- Only a user with a confirmed appointment in the last 30 days may rate or
  comment (AppointmentRepository::hasRecentConfirmed); otherwise
  403 ERR_RATING_NOT_ELIGIBLE. New GET /rate/{uuid}/eligibility for the UI.
- security.yaml: narrow the public rate pattern so /eligibility stays auth'd.

Also updates admin rates listing to the new dimensions and the rating/admin
API docs. Includes migration for the new columns.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 00:25:59 +03:30
hamedandClaude Opus 4.8 a5fca5d1ba chore(dev): run scheduler worker as a ddev daemon + document it
Add a web_extra_daemons entry so ddev auto-runs
messenger:consume scheduler_default (time-limited to 1h, supervisor
restarts it) — the unpaid-booking expiry now runs every minute in dev
without manual steps. Document both messenger workers in CLAUDE.md. In
production this consume must run under supervisor/systemd.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:53:22 +03:30
hamedandClaude Opus 4.8 cc182e48f9 refactor(scheduler): use the recipe's default stateful schedule
Consolidate onto the symfony/scheduler recipe's App\Schedule (stateful +
processOnlyLastMissedRun, so missed runs after downtime still execute)
instead of a separate provider. Add the every-1-minute
ExpireAppointmentsMessage there, point scheduler_default at
schedule://default, and drop the redundant ExpireAppointmentsSchedule.
debug:scheduler shows the trigger registered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:47:38 +03:30
hamedandClaude Opus 4.8 71ab8892c9 feat(appointment): auto-expire unpaid bookings via Symfony Scheduler
Run the 15-min payment-expiry every minute through Symfony Scheduler so
unpaid pending bookings flip to expired without a system crontab. Install
symfony/scheduler; extract the expiry logic into AppointmentExpiryService
(reused by the existing command); add ExpireAppointmentsMessage + handler
and an #[AsSchedule] provider (RecurringMessage::every 1 minute); wire a
scheduler_default transport in messenger.yaml. Slots already free
just-in-time via isSlotTaken, so this only syncs the DB status.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:43:50 +03:30
hamedandClaude Opus 4.8 a348dcae5f fix(admin): render medical history with each section's real shape
The medical sections in other are structured objects, not flat strings:
allergies {substance,reaction,severity}, medications {name,dose,frequency},
surgeries {type,year,hospital}, family_history {relation,disease}, disease
{id,name,status}. The admin view printed raw JSON for all but disease.
Give each section a formatter, and for disease show only entries marked
active (status true) instead of the full 30-item checklist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:27:42 +03:30
hamedandClaude Opus 4.8 d9c0729fbb feat(admin): show user profile on the user detail page
Add a read-only پروفایل کاربر section to UserDetailPage that fetches
GET /api/v1/user-profile/{uuid} (admins are authorized) and renders the
patient profile — personal fields, insurance, and medical history from
other — with loading skeleton and an empty state when the user has no
profile. Response is double-nested (data.data).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:08:18 +03:30
hamedandClaude Opus 4.8 94d9f88cb2 fix(user-profile): don't lazy-create when an admin views another user
resolveProfile created an empty profile for any caller with create-intent,
including an admin merely viewing someone else's profile. Restrict
lazy-create to the user's own profile; an admin reading another user's
missing profile now gets 404 with no side-effect record. Doc updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 22:04:19 +03:30
hamedandClaude Opus 4.8 3f31f42fa0 docs(api): document GET /api/v1/my/payments
Add the user payments-list endpoint to payment.md: permission, query
params (page/limit/status), and the paginated response shape.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:22:07 +03:30
hamedandClaude Opus 4.8 038cb73ea7 feat(payment): add GET /api/v1/my/payments for the logged-in user
Add PaymentRepository::findByUser/countByUser and a paginated
my/payments endpoint that returns the authenticated user's own payments
(derived from the token, never a userId in the URL). Public dashboard's
transactions tab can now list payments instead of hitting a nonexistent
route.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:21:31 +03:30
hamedandClaude Opus 4.8 5d204d7460 docs(api): document user-profile resolve-by-user-uuid and lazy-create
GET/PATCH /api/v1/user-profile/{uuid} now accept either a profile uuid or
the owning user's uuid, and lazily create an empty profile for a user who
has none — documented with the double-nested response note.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:02:41 +03:30
hamedandClaude Opus 4.8 da57ac9c5b fix(user-profile): resolve profile by user uuid and auto-create when missing
GET/PATCH /api/v1/user-profile/{uuid} treated {uuid} as the profile's own
uuid, but clients pass the user's uuid — and a freshly OTP-registered user
has no profile row, so the call always 404'd. Add resolveProfile(): try
profile uuid, then user uuid → that user's profile, and (for the current
user or an admin) lazy-create an empty profile so the client always gets
an editable one. Foreign/unknown uuids still 404 with no leak.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 19:01:27 +03:30
hamedandClaude Opus 4.8 593b4decf4 chore(dev): relax rate limits for local testing
Add config/packages/dev/rate_limiter.yaml raising send_code and login
limits to 1000 in the dev environment only, so repeated OTP testing
isn't blocked by 'درخواست‌های زیاد'. Production limits in
config/packages/rate_limiter.yaml (5/hour, 10/min) are untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:58:18 +03:30
hamed daf2bd4b91 Merge branch 'feat/appointment-lock-patient'
# Conflicts:
#	src/Appointment/Controller/AppointmentController.php
2026-06-15 18:29:25 +03:30
hamed 6e7101f113 Merge branch 'fix/past-slots-unavailable'
# Conflicts:
#	docs/api/appointment.md
2026-06-15 18:28:06 +03:30
hamedandClaude Opus 4.8 ff90ffb9ca docs(api): document booking lock, patient fields, and payment confirm
appointment.md: for_self + patient_* request fields, expires_at and
patient_* response fields, the 15-minute lock/expiry behavior, and the
atomic-conflict 409. payment.md: successful appointment payment confirms
the booking and SMSes the patient.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:01:36 +03:30
hamedandClaude Opus 4.8 a52f412cfc feat(payment): confirm appointment and SMS the patient on success
The payment callback handled subscription and sms-wallet types but left
appointment payments pending. Add a TYPE_APPOINTMENT branch that
transitions the booking pending → confirmed (guarded by canTransitionTo,
so an already-expired booking is skipped) and dispatches a confirmation
SMS to the patient's mobile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:00:13 +03:30
hamedandClaude Opus 4.8 089badbb5a feat(appointment): expire pending bookings past their payment window
Add findPaymentExpired (pending with expires_at < now) and have the
cancel-expired command flip both payment-expired and slot-time-passed
pendings to expired (deduped). Run it on a schedule (e.g. every minute:
* * * * * php bin/console app:cancel-expired-appointments) to free locks
held by unpaid bookings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:58:28 +03:30
hamedandClaude Opus 4.8 aa2e46dfdb feat(appointment): book with patient data, TTL lock, atomic conflict
book() now accepts for_self plus patient_* fields: for_self fills the
patient from the paying user's profile, otherwise patient_name/mobile are
required (422 if missing) and the rest are stored. Every booking starts
pending with a 15-minute expires_at. Persisting goes through
bookAtomically (re-check inside a transaction) so two concurrent requests
for the same slot can't both win — the loser gets 409.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:56:56 +03:30
hamedandClaude Opus 4.8 14ac01d597 feat(appointment): treat expired pending bookings as free in isSlotTaken
A slot is taken only if confirmed, or pending with a still-valid lock
(expires_at null or in the future). An expired pending booking no longer
blocks the slot even before the cron flips it to expired.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:54:18 +03:30
hamedandClaude Opus 4.8 bff7001f49 feat(appointment): add expires_at and patient fields to Appointment
Add a 15-minute payment TTL (expires_at) plus patient_name/mobile/
national_code/gender/reason columns so a booking can hold a slot
temporarily and record a patient distinct from the paying user. New
markPendingWithTtl() sets the lock; transitioning out of pending clears
expires_at. All columns nullable (migration added).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 17:53:27 +03:30
hamedandClaude Opus 4.8 4216e67d68 fix(appointment): mark past-time slots as unavailable
is_available only checked whether a slot was booked, so on today's date
slots whose start time had already passed (e.g. 10:00 when it is 12:00)
still showed as bookable until the POST /appointment 422. Treat a slot
with start < now as unavailable in getAllSlotsWithAvailability, and drop
past slots in filterBookedSlots so getAvailableSlots agrees. Future days
are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:48:50 +03:30
hamedandClaude Opus 4.8 0f7a8c1162 docs(api): document booking window meta and month-availability endpoint
- appointment-settings.md: weekly-schedule meta (online_booking_enabled,
  booking_window value/unit), defaults, and the slot-gating behavior.
- appointment.md: new public month-availability endpoint (Gregorian
  year/month, disabled/enabled dates) and the empty-slots conditions for
  appointment-slots.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:27:10 +03:30
hamedandClaude Opus 4.8 874125c4e1 feat(admin): online-booking window UI in doctor weekly schedule
Add a نوبت‌دهی آنلاین card to the weekly-schedule tab: a toggle for
online_booking_enabled and a value+unit (هفته/ماه) booking window.
Hydrated from the schedule meta and sent in the weekly-schedule
POST/PATCH payload. Uses existing .input/.btn classes, RTL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:26:03 +03:30
hamedandClaude Opus 4.8 f443beb615 feat(appointment): public month-availability endpoint
Add GET /api/v1/appointment-settings/month-availability/{doctorUuid}
?year=&month= (Gregorian) returning disabled_dates / enabled_dates for
the month plus the doctor's online_booking flag and window. Lives in
AppointmentController (per-method guards) so it is genuinely public —
the class-level IsGranted on AppointmentSettingsController would have
forced auth. Whitelisted in security.yaml (firewall + access_control).
Uses SlotCalculator::hasAnyAvailability per day, so holidays, closed
overrides, non-working days and out-of-window dates all come back
disabled.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:23:12 +03:30
hamedandClaude Opus 4.8 f82d92b3ed feat(appointment): enforce booking window in slot calculation
buildAllSessions now rejects dates that are in the past, beyond the
doctor's booking window (today + value week|month), or when online
booking is disabled — gating overrides and weekly schedule alike. Add a
public hasAnyAvailability() for the month-availability endpoint. Window
config is read from the schedule meta, falling back to defaults.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:18:00 +03:30
hamedandClaude Opus 4.8 09aba878f8 feat(appointment): store online-booking window in WeeklySchedule meta
Add a reserved meta key inside WeeklySchedule.setting (no migration) holding
online_booking_enabled and a booking_window value+unit (week|month), with
sane defaults. Expose meta separately in toArray() and keep it out of the
day schedule map. setSetting now preserves meta when the day schedule is
replaced; the weekly-schedule POST/PATCH endpoints accept an optional meta.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:16:30 +03:30
hamed c662eb9b4f feat(doctor): update schedule fields in doctor API responses to reflect actual availability 2026-06-15 15:11:29 +03:30
hamed ec36eefeb8 feat: add OpenAPI tags to various controllers for improved API documentation 2026-06-15 14:54:10 +03:30
hamed e95c5c12d1 feat: update UI components to use CSS variables for dark mode compatibility 2026-06-15 14:50:45 +03:30
hamed df7a784701 feat: implement realistic data seeding for doctors, clinics, and secretaries
- Added seed_realistic_data.php to clean existing data and populate the database with realistic entries for doctors, clinics, and secretaries.
- Created a structured approach to generate 100 doctors per city with diverse specialties and services.
- Implemented database cleanup routines to ensure a fresh start for data seeding.
- Enhanced the DoctorSecretaryRepository with improved comments for clarity.
2026-06-15 14:18:25 +03:30
hamed 68dfe613a2 feat(payment): add test mode check for payment callback IP validation 2026-06-15 13:17:28 +03:30
hamed 5fd45b429e feat(subscription): include amount_rials in subscription payment mutation 2026-06-15 13:02:06 +03:30
hamed 3763c83471 feat(payment): refactor payment configuration retrieval into a custom hook 2026-06-15 12:56:43 +03:30
hamed d13d8436ab feat(patient): add search user functionality by mobile number 2026-06-15 12:52:45 +03:30
hamed 95f5918118 feat(secretary): enhance secretary management with name input and toggle activation feature 2026-06-15 12:23:07 +03:30
hamed fa6656df48 feat(subscription): implement feature gating for subscription-based access in admin panel 2026-06-15 12:00:36 +03:30
hamed 3d33cf09b8 feat(auth): enhance access control in PrivateRoute and display error message in LoginPage 2026-06-15 11:41:52 +03:30
hamed 8c0b3d8282 feat(payment): add endpoint for payment configuration and update UI for test mode 2026-06-15 11:35:23 +03:30
hamed 5f5b0fa548 fix: update permissions structure for secretary API interactions 2026-06-15 11:25:14 +03:30
hamed 4bf381ac94 feat(secretary): implement scope separation for secretaries in clinics and personal practices
- Added `owner_type` and `clinic_id` fields to `DoctorSecretary` entity to distinguish between clinic and personal practice relationships.
- Updated repository methods to be scope-aware, allowing for specific queries based on the context of the secretary's relationship (clinic or doctor).
- Modified `SecretaryController` to handle secretary creation with appropriate scope based on the current user's role.
- Enhanced `AuthController` to build contexts that reflect the scope of the secretary's access.
- Updated `DashboardController` and `PatientController` to respect the new scope logic when retrieving data.
- Created migration to update the database schema accordingly, dropping the old unique constraint and adding the new fields and constraints.
2026-06-15 11:19:37 +03:30
hamed 5cdcec23a9 feat: enhance staff management and payment gateway features
- Fix national code handling in staff creation and updates to support Persian digits.
- Update ClinicStaff entity to allow longer national codes (up to 15 characters).
- Implement support for clinic secretaries in SecretaryController, allowing creation without a doctor UUID.
- Add a new endpoint to retrieve doctors associated with a clinic for secretary management.
- Improve appointment management by ensuring doctors are selectable even when no appointments exist.
- Extend PatientController to allow secretaries to create patient records if they have the appropriate permissions.
- Introduce a PriceInput component for better price formatting in forms, supporting Persian digits.
- Add a MockGateway for testing payment processes without real transactions.
- Enhance SMS settings management with an approval flow for post-visit text messages, including new fields for pending text and status.
- Update migrations to reflect changes in database schema for national codes and SMS settings.
2026-06-15 11:03:56 +03:30
hamed 55f646e2d4 feat: redesign StaffPage with KPI bar, improved table layout, and enhanced form fields 2026-06-14 23:36:37 +03:30
hamedandClaude Sonnet 4.6 5be63a23b6 feat: redesign SubscriptionPage with improved UI/UX
- Active subscription card: colored gradient bg, icon, progress bar, expiry warning badge
- Trial banner: shown when no subscription and trial not used yet
- Plan cards: icon header, feature checklist (✓/✗), per-period buy buttons inline
- Free plan card shows "شما اکنون در این پنل هستید" when current
- Payment modal: order summary card + gateway selector with styled radio buttons
- Loading skeleton for plan cards
- Footer with trust signals

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 23:16:04 +03:30
hamedandClaude Sonnet 4.6 ab9d078bf0 fix: fix SubscriptionPage crash — align with API response structure
API returns { subscription: {...}|null, used_trial: bool } not flat MySubscription.
- Added MySubscriptionData interface with correct nested shape
- Extract my = myRaw.subscription and usedTrial = myRaw.used_trial separately
- Replace my.used_trial references with usedTrial variable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 23:12:22 +03:30
hamedandClaude Sonnet 4.6 94580894c8 feat: add MySecretariesPage and AdminSubscriptionPage (PRD completion)
- MySecretariesPage: doctor/clinic can manage their own secretaries
  with add/permissions-matrix/deactivate; uses GET /api/v1/secretaries/{doctorUuid}
- AdminSubscriptionPage: admin can create/edit plans and periods,
  view subscription sales report; tabs: پنل‌ها / گزارش فروش
- Sidebar: add منشیان link for doctor+clinic roles, add اشتراک‌ها link for admin
- App.tsx: add /my-secretaries and /admin-subscription routes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 22:57:30 +03:30
hamedandClaude Sonnet 4.6 5a4116fee0 feat: add date range filter and new stats to dashboard (TASK-16)
- AdminDashboard: adds this_week/this_month/3_months preset buttons; charts query now passes from/to params; renamed appointments_30d→appointments_by_day and revenue_30d→revenue_by_day; adds subscription_sales_by_plan table
- ClinicDashboard: adds preset filter; query passes from/to; adds sms_wallet_balance, unique_patients_count, revenue_period_rials KPI cards
- DoctorDashboard: adds preset filter; query passes from/to; adds unique_patients_count, revenue_period_rials KPI cards
- Shared: getRange() helper and DatePreset type extracted at module level

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 22:33:56 +03:30
hamedandClaude Sonnet 4.6 69df9947a9 feat: rewrite MyPatientsPage with patient records and sessions (TASK-15)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 22:27:15 +03:30
hamedandClaude Sonnet 4.6 ed18c260ca feat: add Staff, Subscription, ClinicServices, SmsWallet pages (TASK-10,11,13,14)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 22:23:30 +03:30
hamed 7ea3523830 feat: implement frontend for Phase 2 tasks including staff management, subscription, and clinic services 2026-06-14 22:15:50 +03:30
hamed b0244f28f5 feat: implement staff management and subscription system
- Added StaffController for managing clinic staff, including listing, creating, updating, and toggling staff status.
- Created ClinicStaff entity and repository for staff data handling.
- Developed SubscriptionController to manage subscription plans and periods, including trial subscriptions.
- Introduced SubscriptionPlan, SubscriptionPeriod, and ClinicSubscription entities for subscription management.
- Implemented SubscriptionService for handling subscription logic, including trial activation and subscription creation from payments.
- Added necessary repositories for subscription entities to facilitate data access and manipulation.
2026-06-14 22:10:28 +03:30
hamed dcd631f503 feat: implement Phase 2 backend tasks including staff management, subscription tiers, secretary completion, clinic services, SMS panel, patient records, and smart dashboard 2026-06-14 21:38:48 +03:30
hamed b58aacc37f Implement SMS panel user flow and patient records system; add wallet charging, automatic reminders, and patient session management with detailed database schema and user flows. 2026-06-14 21:15:40 +03:30
hamed a72a6da621 feat: create phase 2 task documentation for staff management, subscription, secretary completion, clinic services, SMS panel, patient records, and smart dashboard 2026-06-14 21:02:18 +03:30
hamed 6ddc66ad74 Update PRD for ClinicPro Phase 2: Enhance project requirements, add new modules, and refine existing functionalities. Include detailed specifications for Staff, Subscription tiers, Clinic services, Patient records, SMS panel, and more. Revise API documentation and frontend requirements for better clarity and implementation guidance. 2026-06-14 20:53:49 +03:30
hamed a1d3442b9b Refactor PRD documentation: Remove outdated pre_prd.md and create comprehensive prd.md for ClinicPro Phase 2, detailing new features, requirements, and API endpoints. Add initial pre_prd.md for settings and staff management. 2026-06-14 20:43:59 +03:30
hamed 9c935c341f feat: add initial PRD for ClinicPro Phase 2 outlining staff management, subscription tiers, and patient records 2026-06-14 20:41:37 +03:30
hamed ab5dca4fb6 feat: add doctor_uuid support in authStore and update DoctorDetailPage to prioritize doctorUuid 2026-06-13 19:19:50 +03:30
hamed 09c393a574 feat: update primaryRole handling in authStore and adjust context role for clinics 2026-06-13 18:47:26 +03:30
hamed d05c070661 feat: enhance doctor address management by including clinic addresses and enforcing required fields 2026-06-13 18:30:06 +03:30
hamed c1c57df4ff feat: add clinic role support to doctor profile access and update API endpoint for clinic owners 2026-06-13 18:10:44 +03:30
hamed 5c2e9fae3f feat: add EyeIcon button to view doctor profile in ClinicDetailPage 2026-06-13 18:03:41 +03:30
hamed aa15addcb9 feat: implement doctor invitation acceptance logic to add doctors to clinic_doctors 2026-06-13 17:53:27 +03:30
hamed 5c167b5d39 feat: add owner mobile information to ClinicsPage and update API to fetch owner mobile 2026-06-13 17:39:56 +03:30
hamed d50fb96542 pwa setting 2026-06-13 13:28:39 +03:30
hamed 0b5d017b14 feat: enhance DoctorDetailPage with edit form helpers and gender selection options 2026-06-12 22:58:28 +03:30
hamed 87966a90fa feat: update ClinicDetailPage and ClinicsPage for address handling and UI improvements 2026-06-12 22:39:11 +03:30
hamed 960ff1ab29 feat: enhance DoctorFormPage with searchable specialties and improved UI components
- Refactored DoctorFormPage to use Controller from react-hook-form for better form handling.
- Added a new Field component for consistent input styling and error handling.
- Implemented a SpecialtyPicker component with improved selection logic for specialties.
- Updated the layout and styling of the form sections for better user experience.
- Integrated SearchableSelect for selecting specialties and roles in DoctorsPage and UsersPage.
- Added createClinic API endpoint to handle clinic creation with validation for mobile and name fields.
2026-06-12 20:43:47 +03:30
hamed 9e8064e101 feat: enhance SpecialtyPicker to support parent-child relationship for specialties 2026-06-12 19:32:56 +03:30
hamed 762a4794cf docs: update CLAUDE.md with first-time setup instructions and enhance response helpers documentation 2026-06-12 18:18:41 +03:30
hamed d8c4248059 feat: add database backup file for clinic data preservation 2026-06-12 15:36:05 +03:30
hamed 34ba1b781c fix: update clinicAddresses assignment for improved data handling 2026-06-12 14:52:50 +03:30
hamed 0333b24071 feat: enhance DoctorAddress entity to support clinic addresses and types
- Added `clinic_id` and `type` fields to `DoctorAddress` entity to differentiate between personal and clinic addresses.
- Updated constructor to support creation of addresses for both doctors and clinics.
- Modified repository methods to handle new address types and added methods for counting and finding addresses by clinic.
- Implemented migration to update the database schema accordingly.
- Removed deprecated endpoint for creating addresses from clinics and updated related controller methods.
- Added new endpoints for managing clinic addresses, including CRUD operations.
- Updated frontend components to handle new address types and display accordingly.
2026-06-12 13:39:37 +03:30
hamed 63073c6a42 feat: implement OTP login and password reset functionality with corresponding API endpoints and frontend updates 2026-06-12 12:54:29 +03:30
hamed 8ad983310c feat: add clinic management and financial reporting features
- Implemented ClinicFormPage for adding new clinics with validation.
- Created MyFinancialPage to display financial summaries and charts.
- Developed MyPatientsPage for managing patient data with search and pagination.
- Added PreRegistrationsPage for handling pre-registration requests with approval and rejection functionalities.
- Introduced database migration for pre_registrations table.
- Built PreRegistrationController for managing pre-registration logic, including submission, approval, and rejection.
- Created PreRegistration entity and repository for handling pre-registration data.
2026-06-12 12:31:27 +03:30
hamed 92cb834c22 feat: implement pre-registration system for doctors and clinics with public endpoint and admin management 2026-06-12 11:45:16 +03:30
hamed 484d3024c1 Refactor code structure for improved readability and maintainability 2026-06-12 11:00:24 +03:30
hamed c05ac7ca51 feat: add past slot validation to appointment controllers and update SlotCard component 2026-06-11 20:00:02 +03:30
hamed c1df5b73e7 feat: add appointment time and patient name display to CancelledBadge component 2026-06-11 19:57:53 +03:30
hamed 5a7df22eda feat: enhance appointment scheduling with session management and availability checks 2026-06-11 19:56:27 +03:30
hamed 0b31eb7812 fix: resolve calendar crash and enhance appointment management
- Fixed calendar crash due to invalid array length in PersianCalendar.tsx by changing locale to 'en-u-ca-persian'.
- Added Persian weekday display in DateNavigator with appropriate styling and logic.
- Updated empty slot message to indicate when a day is off.
- Made patient name a required field in appointment creation and implemented find-or-create logic for patients in both admin and user endpoints.
- Corrected mobile number display to show the patient's number instead of the doctor's in appointment listings.
- Ensured booked appointments are displayed correctly in the schedule view.
- Removed unnecessary operations column from the appointments table view.
2026-06-11 19:35:12 +03:30
hamed 277922d4ae feat: add doctor profile page with sidebar integration and routing 2026-06-11 19:06:59 +03:30
hamed 704075770b feat(api): enhance appointment retrieval and add today stats endpoint 2026-06-11 14:32:10 +03:30
hamed 45ee725820 feat: update appointment management API and frontend components
- Added new endpoint to get today's appointment statistics with optional date filter.
- Enhanced appointment listing API to support filtering by date and doctor UUID.
- Updated Appointment model to include new fields and modified status values.
- Implemented AppointmentStatusDropdown component for status management with visual feedback.
- Created PersianCalendar component for date selection in Jalali format.
- Updated API documentation to reflect changes in appointment management.
2026-06-11 14:13:42 +03:30
hamed 92a258832b feat: complete redesign of the appointments page with new UI and functionality 2026-06-11 13:58:46 +03:30
hamed 82e1c264a1 feat: add doctor invitation modal and appointment creation API
- Implemented InviteDoctorModal component for inviting doctors to clinics.
- Updated ClinicDashboard to include a button for inviting doctors and handle modal state.
- Added createAppointment API endpoint in AdminApiController for scheduling appointments.
- Enhanced ClinicInvitationController to check user access when inviting doctors.
- Updated MyAppointmentsController to ensure unique appointment records.
- Added seed_test_data.php for populating test data including doctors, clinics, and appointments.
- Refactored styles to include new appointment status badges and updated font imports.
2026-06-11 13:36:54 +03:30
hamed 04b51273e3 feat: add test user creation script and documentation 2026-06-11 12:27:35 +03:30
hamed e7b90a6399 feat(api): add dashboard endpoints for clinic, doctor, and secretary roles
- Implemented GET /api/v1/dashboard/clinic to return clinic stats and today's schedule for clinic owners.
- Implemented GET /api/v1/dashboard/doctor to return doctor's stats and today's schedule for doctors.
- Implemented GET /api/v1/dashboard/secretary to return stats and conditional appointments for secretaries.

feat(migrations): create user_active_context and mobile_verification_otp tables

- Added migration to create user_active_context table for tracking active user sessions.
- Added migration to create mobile_verification_otp table for handling mobile number verification.

feat(migrations): create site_config table for application settings

- Added migration to create site_config table to store various site configuration settings.

feat(appointments): create MyAppointmentsController for user-specific appointments

- Added MyAppointmentsController to handle fetching user-specific appointments with pagination and filtering.

feat(auth): implement NotificationMobileController for mobile number verification

- Added NotificationMobileController to handle OTP requests and verification for mobile number changes.

feat(auth): create MobileVerificationOtp entity for OTP management

- Created MobileVerificationOtp entity to manage OTP records for mobile verification.

feat(auth): create UserActiveContext entity for user session management

- Created UserActiveContext entity to manage user active sessions.

feat(config): implement SiteConfigController for managing site settings

- Added SiteConfigController to handle fetching and updating site configuration settings.

feat(config): create SiteConfig entity and repository for configuration management

- Created SiteConfig entity and repository to manage site configuration data.
2026-06-11 12:20:12 +03:30
hamed 54c491c734 feat: enhance /oauth/userinfo endpoint to include primary_role and context in response 2026-06-11 10:56:48 +03:30
hamed c996aca96c feat: implement new API endpoints for multi-role dashboard and update documentation 2026-06-11 10:34:44 +03:30