# Architecture The project demonstrates a production-shaped authentication microservice built around gRPC, OTP login, asynchronous SMS dispatch, and a small demo client service. ## System View ![Service architecture](assets/diagrams/service_architecture.png) The browser talks only to `demo-app`. The demo service acts as a backend-for-frontend and calls the gRPC `auth-service`. Auth data is split by responsibility: MongoDB persists users and refresh sessions, Redis stores short-lived OTP state and rate-limit counters, and RabbitMQ decouples OTP generation from SMS delivery. ## Clean Architecture ![Clean architecture layers](assets/diagrams/clean_architecture.png) The domain layer owns roles, users, refresh sessions, and ports. The application layer coordinates OTP, tokens, and access control. Infrastructure adapters implement MongoDB, Redis, RabbitMQ, and SMS providers. Transports translate gRPC and demo HTTP requests into application use cases. ## OTP Login Flow ![OTP login sequence](assets/diagrams/otp_login_flow.png) OTP codes are generated with `secrets`, stored only as HMAC hashes in Redis, and sent through RabbitMQ. Verification compares hashes and deletes successful OTP state before issuing an access token and opaque refresh token. ## Refresh Rotation ![Refresh token rotation](assets/diagrams/refresh_rotation_flow.png) Refresh tokens are opaque random values. Only SHA-256 hashes are stored in MongoDB. Every refresh creates a new session and revokes the old token hash. ## SMS Provider Strategy ![SMS provider strategy](assets/diagrams/sms_provider_strategy.png) The worker depends on the `SmsClient` port and receives the concrete provider from a small factory. Kavenegar, SMS.ir, and debug-local delivery share the same interface. ## Production Deployment ![Production deployment](assets/diagrams/production_deployment.png) Production exposes only Caddy on ports `80` and `443`. Caddy routes `gapido.amiirkhl.ir` to `demo-app`. gRPC, MongoDB, Redis, RabbitMQ, and the SMS worker remain private on the Docker network.