fix(orm): declare repositoryClass on all entities with a custom repository

On prod (opcache.preload + prod container), getRepository(Entity::class)
returned Doctrine's default repository instead of the custom one when the
entity's #[ORM\Entity] had no repositoryClass — so custom finders like
DoctorSecretaryRepository::findAllActiveBySecretary threw BadMethodCallException,
making /oauth/userinfo return 500 after login. Declare repositoryClass explicitly
on all 25 affected entities.

Also add app:create-admin command (create/promote a ROLE_ADMIN user by mobile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-06-28 16:19:07 +03:30
co-authored by Claude Opus 4.8
parent 5bcc97ceb6
commit 05fde81320
25 changed files with 50 additions and 25 deletions
+2 -1
View File
@@ -5,9 +5,10 @@ namespace App\Appointment\Entity;
use App\Auth\Entity\User;
use App\Doctor\Entity\Doctor;
use Doctrine\ORM\Mapping as ORM;
use App\Appointment\Repository\AppointmentRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: AppointmentRepository::class)]
#[ORM\Table(name: 'appointments')]
#[ORM\Index(columns: ['doctor_id', 'slot_start'], name: 'idx_appointments_doctor_slot')]
#[ORM\Index(columns: ['user_id', 'status'], name: 'idx_appointments_user_status')]
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\Appointment\Entity;
use App\Doctor\Entity\Doctor;
use Doctrine\ORM\Mapping as ORM;
use App\Appointment\Repository\DateOverrideRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: DateOverrideRepository::class)]
#[ORM\Table(name: 'date_overrides')]
#[ORM\Index(columns: ['doctor_id', 'date'], name: 'idx_date_overrides_doctor_date')]
class DateOverride
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\Appointment\Entity;
use App\Doctor\Entity\Doctor;
use Doctrine\ORM\Mapping as ORM;
use App\Appointment\Repository\HolidayRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: HolidayRepository::class)]
#[ORM\Table(name: 'holidays')]
#[ORM\Index(columns: ['doctor_id', 'start_date', 'end_date'], name: 'idx_holidays_doctor_range')]
class Holiday
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\Appointment\Entity;
use App\Doctor\Entity\Doctor;
use Doctrine\ORM\Mapping as ORM;
use App\Appointment\Repository\WeeklyScheduleRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: WeeklyScheduleRepository::class)]
#[ORM\Table(name: 'weekly_schedules')]
#[ORM\UniqueConstraint(name: 'idx_weekly_schedules_doctor', columns: ['doctor_id'])]
class WeeklySchedule
+2 -1
View File
@@ -3,11 +3,12 @@
namespace App\Auth\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Auth\Repository\UserRepository;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: 'users')]
#[ORM\UniqueConstraint(name: 'uniq_mobile', columns: ['mobile_number'])]
class User implements UserInterface, PasswordAuthenticatedUserInterface
+2 -1
View File
@@ -4,7 +4,8 @@ namespace App\Auth\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
use App\Auth\Repository\UserActiveContextRepository;
#[ORM\Entity(repositoryClass: UserActiveContextRepository::class)]
#[ORM\Table(name: 'user_active_context')]
class UserActiveContext
{
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\Blog\Entity;
use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use App\Blog\Repository\BlogRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: BlogRepository::class)]
#[ORM\Table(name: 'blogs')]
#[ORM\Index(columns: ['status', 'created_at'], name: 'idx_blogs_status')]
class Blog
+2 -1
View File
@@ -10,9 +10,10 @@ use App\Specialty\Entity\Specialty;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Clinic\Repository\ClinicRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: ClinicRepository::class)]
#[ORM\Table(name: 'clinics')]
#[ORM\Index(columns: ['user_id'], name: 'idx_clinics_owner')]
#[ORM\Index(columns: ['city_id'], name: 'idx_clinics_city')]
+2 -1
View File
@@ -4,7 +4,8 @@ namespace App\Config\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
use App\Config\Repository\SiteConfigRepository;
#[ORM\Entity(repositoryClass: SiteConfigRepository::class)]
#[ORM\Table(name: 'site_config')]
class SiteConfig
{
+2 -1
View File
@@ -5,7 +5,8 @@ namespace App\Config\Entity;
use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
use App\Config\Repository\TaxRateHistoryRepository;
#[ORM\Entity(repositoryClass: TaxRateHistoryRepository::class)]
#[ORM\Table(name: 'tax_rate_history')]
#[ORM\Index(columns: ['changed_at'], name: 'idx_tax_history_date')]
class TaxRateHistory
+2 -1
View File
@@ -11,9 +11,10 @@ use App\Specialty\Entity\Specialty;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Doctor\Repository\DoctorRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: DoctorRepository::class)]
#[ORM\Table(name: 'doctors')]
#[ORM\UniqueConstraint(name: 'idx_doctors_user', columns: ['user_id'])]
#[ORM\Index(columns: ['active_doctor_appointment'], name: 'idx_doctors_active')]
+2 -1
View File
@@ -5,9 +5,10 @@ namespace App\Doctor\Entity;
use App\Location\Entity\City;
use App\Location\Entity\Province;
use Doctrine\ORM\Mapping as ORM;
use App\Doctor\Repository\DoctorAddressRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: DoctorAddressRepository::class)]
#[ORM\Table(name: 'doctor_addresses')]
#[ORM\Index(columns: ['doctor_id'], name: 'idx_doctor_addresses_doctor')]
#[ORM\Index(columns: ['clinic_id'], name: 'idx_doctor_addr_clinic')]
+2 -1
View File
@@ -5,9 +5,10 @@ namespace App\Payment\Entity;
use App\Appointment\Entity\Appointment;
use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use App\Payment\Repository\PaymentRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: PaymentRepository::class)]
#[ORM\Table(name: 'payments')]
#[ORM\Index(columns: ['order_id'], name: 'idx_payments_order')]
#[ORM\Index(columns: ['user_id'], name: 'idx_payments_user')]
+2 -1
View File
@@ -7,9 +7,10 @@ use App\Doctor\Entity\Doctor;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Rating\Repository\CommentRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: CommentRepository::class)]
#[ORM\Table(name: 'comments')]
#[ORM\Index(columns: ['doctor_id', 'status'], name: 'idx_comments_doctor_status')]
class Comment
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\Rating\Entity;
use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use App\Rating\Repository\LikeRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: LikeRepository::class)]
#[ORM\Table(name: 'likes')]
#[ORM\UniqueConstraint(name: 'idx_likes_user_comment', columns: ['user_id', 'comment_id'])]
class Like
+2 -1
View File
@@ -5,9 +5,10 @@ namespace App\Rating\Entity;
use App\Auth\Entity\User;
use App\Doctor\Entity\Doctor;
use Doctrine\ORM\Mapping as ORM;
use App\Rating\Repository\RateRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: RateRepository::class)]
#[ORM\Table(name: 'rates')]
#[ORM\UniqueConstraint(name: 'idx_rates_user_doctor', columns: ['user_id', 'doctor_id'])]
class Rate
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\Representation\Entity;
use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use App\Representation\Repository\RepresentationRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: RepresentationRepository::class)]
#[ORM\Table(name: 'representations')]
class Representation
{
+2 -1
View File
@@ -5,10 +5,11 @@ namespace App\Secretary\Entity;
use App\Auth\Entity\User;
use App\Clinic\Entity\Clinic;
use App\Doctor\Entity\Doctor;
use App\Secretary\Repository\DoctorSecretaryRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: DoctorSecretaryRepository::class)]
#[ORM\Table(name: 'doctor_secretaries')]
#[ORM\UniqueConstraint(name: 'idx_doctor_secretary_scope', columns: ['doctor_id', 'secretary_id', 'owner_type'])]
class DoctorSecretary
+2 -1
View File
@@ -5,9 +5,10 @@ namespace App\Settlement\Entity;
use App\Auth\Entity\User;
use App\Payment\Entity\Payment;
use Doctrine\ORM\Mapping as ORM;
use App\Settlement\Repository\FinancialBreakdownRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: FinancialBreakdownRepository::class)]
#[ORM\Table(name: 'financial_breakdowns')]
#[ORM\Index(columns: ['representation_id', 'created_at'], name: 'idx_breakdown_rep_date')]
#[ORM\Index(columns: ['source', 'created_at'], name: 'idx_breakdown_source_date')]
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\Settlement\Entity;
use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use App\Settlement\Repository\SettlementRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: SettlementRepository::class)]
#[ORM\Table(name: 'settlements')]
#[ORM\Index(columns: ['user_id', 'status'], name: 'idx_settlements_user_status')]
class Settlement
+2 -1
View File
@@ -5,9 +5,10 @@ namespace App\Settlement\Entity;
use App\Auth\Entity\User;
use App\Payment\Entity\Payment;
use Doctrine\ORM\Mapping as ORM;
use App\Settlement\Repository\WalletTransactionRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: WalletTransactionRepository::class)]
#[ORM\Table(name: 'wallet_transactions')]
#[ORM\Index(columns: ['user_id', 'created_at'], name: 'idx_wallet_user_date')]
class WalletTransaction
+2 -1
View File
@@ -3,9 +3,10 @@
namespace App\Sms\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Sms\Repository\SmsLogRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: SmsLogRepository::class)]
#[ORM\Table(name: 'sms_logs')]
#[ORM\Index(columns: ['mobile', 'created_at'], name: 'idx_sms_logs_mobile')]
class SmsLog
+2 -1
View File
@@ -4,11 +4,12 @@ namespace App\Sms\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Sms\Repository\SmsMessageTemplateRepository;
/**
* متن ویرایش‌پذیرِ پیامک‌های سیستمی، کلیددار با تگ (SmsLog::TAG_*).
* body شامل placeholderهای {key} است که هنگام ارسال جایگزین می‌شوند.
*/
#[ORM\Entity]
#[ORM\Entity(repositoryClass: SmsMessageTemplateRepository::class)]
#[ORM\Table(name: 'sms_message_templates')]
class SmsMessageTemplate
{
+2 -1
View File
@@ -3,9 +3,10 @@
namespace App\Sms\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Sms\Repository\SmsTemplateRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: SmsTemplateRepository::class)]
#[ORM\Table(name: 'sms_templates')]
class SmsTemplate
{
+2 -1
View File
@@ -4,9 +4,10 @@ namespace App\UserProfile\Entity;
use App\Auth\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use App\UserProfile\Repository\UserProfileRepository;
use Symfony\Component\Uid\Uuid;
#[ORM\Entity]
#[ORM\Entity(repositoryClass: UserProfileRepository::class)]
#[ORM\Table(name: 'profiles')]
#[ORM\UniqueConstraint(name: 'idx_profiles_user', columns: ['user_id'])]
#[ORM\UniqueConstraint(name: 'uniq_profiles_national_code', columns: ['national_code'])]