35 lines
1.7 KiB
Markdown
35 lines
1.7 KiB
Markdown
# Implementation Decisions
|
|
|
|
## Python gRPC Service
|
|
|
|
The challenge explicitly required Python with gRPC. The auth boundary is therefore a `grpc.aio` service instead of REST. A separate FastAPI demo service was added only as a browser-friendly client.
|
|
|
|
## OTP Storage
|
|
|
|
OTP codes are never stored in plaintext. Redis stores HMAC hashes with a short TTL, attempt counters, and request rate-limit counters. This keeps OTP state fast, temporary, and easy to expire.
|
|
|
|
## Token Model
|
|
|
|
Access tokens are signed JWTs with short TTLs. Refresh tokens are opaque random values, stored only as hashes in MongoDB, and rotated on every use.
|
|
|
|
## RabbitMQ SMS Dispatch
|
|
|
|
SMS delivery is asynchronous. The auth service publishes a durable message and returns quickly. The worker uses manual acknowledgement, bounded retries, and a dead-letter queue for failed deliveries.
|
|
|
|
## SMS Provider Strategy
|
|
|
|
Kavenegar, SMS.ir, and debug delivery implement the same `SmsClient` port. The provider is selected through configuration, which keeps the worker closed for modification when adding providers.
|
|
|
|
## Demo Service
|
|
|
|
Browsers do not speak native gRPC directly. A small FastAPI backend-for-frontend demonstrates how another microservice consumes the auth service through gRPC while serving a minimal UI.
|
|
|
|
## Local vs Production Compose
|
|
|
|
The base Compose file is production-safe and keeps service ports private. `docker-compose.local.yml` publishes developer ports. `docker-compose.prod.yml` adds Caddy as the only public entrypoint.
|
|
|
|
## Caddy Reverse Proxy
|
|
|
|
Caddy was chosen for automatic HTTPS and a compact configuration. Production serves only `https://gapido.amiirkhl.ir`; internal service ports are not published.
|
|
|