Commit Graph
109 Commits
Author SHA1 Message Date
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