# معماری — تسک ۰۲: ماژول احراز هویت ## ساختار فایل‌ها ``` src/Module/Auth/ ├── Controller/ │ ├── OtpController.php ← send-code, verify-code │ ├── AuthController.php ← register, session/token │ ├── OAuthController.php ← /oauth/token, /oauth/userinfo │ └── UserController.php ← delete, patch user ├── Service/ │ ├── OtpService.php ← تولید، ذخیره و تأیید OTP در Redis │ ├── JwtService.php ← صدور و تمدید JWT │ ├── CaptchaService.php ← اعتبارسنجی captcha_token │ └── UserService.php ← ایجاد، ویرایش، حذف کاربر ├── Repository/ │ └── UserRepository.php ├── Entity/ │ └── User.php ├── DTO/ │ ├── Request/ │ │ ├── SendCodeRequest.php │ │ ├── VerifyCodeRequest.php │ │ ├── RegisterRequest.php │ │ ├── RefreshTokenRequest.php │ │ └── UpdateUserRequest.php │ └── Response/ │ ├── TokenResponse.php │ └── UserInfoResponse.php └── Voter/ └── UserVoter.php ← فقط owner یا admin می‌تواند ویرایش/حذف کند ``` ## نمودار جریان احراز هویت ``` کاربر │ ├─► POST /send-code │ └─► OtpService: تولید کد ۵ رقمی │ └─► Redis: ذخیره با کلید otp:{mobile} (TTL=120s) │ └─► SmsService: ارسال پیامک │ ├─► POST /verify-code │ └─► OtpService: تأیید کد از Redis │ ├─► اگر کاربر جدید: ایجاد User با وضعیت pending │ └─► JwtService: صدور access_token + refresh_token │ └─► POST /register (با X-CSRF-Token) └─► UserService: تکمیل اطلاعات کاربر ``` ## Entity: User ```php #[ORM\Entity(repositoryClass: UserRepository::class)] #[ORM\Table(name: 'users')] class User implements UserInterface { #[ORM\Id, ORM\GeneratedValue, ORM\Column] private int $id; #[ORM\Column(type: UuidType::NAME, unique: true)] private Uuid $uuid; #[ORM\Column(length: 20, unique: true)] private string $mobile; #[ORM\Column(length: 100, nullable: true)] private ?string $firstName; #[ORM\Column(length: 100, nullable: true)] private ?string $lastName; #[ORM\Column(length: 180, nullable: true, unique: true)] private ?string $email; #[ORM\Column(length: 50)] private string $status = 'pending'; // pending, active, blocked #[ORM\Column(type: 'json')] private array $roles = ['ROLE_USER']; // TimestampableTrait } ```