initial commit

This commit is contained in:
2026-06-09 14:07:37 +03:30
parent 30ac533800
commit 996a4fcda7
121 changed files with 20557 additions and 3 deletions

255
README.md
View File

@@ -1,3 +1,252 @@
# esg
External Services Gateway. This project is for inquiry for all external services outside of company.
# Inquiry Gateway
Production-grade **NestJS + MongoDB** unified inquiry gateway for external service providers.
## 📚 Documentation
- **[Environment Configuration Guide](docs/ENVIRONMENT_CONFIGURATION.md)** - Complete guide for configuring providers, authentication, and inquiry routing
- **[API Documentation](docs/API_DOCUMENTATION.md)** - Full API reference with examples, Swagger definitions, and best practices
## Architecture
```
Client → POST /inquiries/person (unified)
→ InquiryController
→ InquiryService
→ ProviderOrchestratorService (strategy + fallback)
→ ProviderFactory → Hamta | Moallem | TejaratNou
→ LegacyApiProvider (shared base for identical APIs)
→ BaseProvider (retry, timeout, logging, error normalization)
→ MongoDB inquiry_logs
```
### Provider vs Authentication Service
The system distinguishes between:
- **Inquiry Providers** (HAMTA, MOALLEM, TEJARATNOU): Handle actual inquiry requests
- **Authentication Services** (AMITIS): Provide authentication tokens for providers
Each inquiry type can be configured with its own credentials and authentication method. See [Environment Configuration Guide](docs/ENVIRONMENT_CONFIGURATION.md) for details.
### Design patterns
| Pattern | Usage |
|---------|--------|
| **Strategy** | `ProviderOrchestratorService` selects and executes providers |
| **Factory** | `ProviderFactory` registers and resolves provider instances |
| **Template method** | `BaseProvider` defines execution pipeline; subclasses implement `callProvider` |
| **Shared adapter** | `LegacyApiProvider` for Hamta/Moallem identical APIs |
### Project structure
```
src/
├── main.ts
├── app.module.ts
├── common/ # DTOs, filters, interceptors, helpers, enums
├── config/ # @nestjs/config + inquiry routing
├── auth/ # JWT, RBAC, inquiry access guards
├── users/ # Unified users (ADMIN / USER / SUPER_ADMIN)
├── audit/ # Security audit logs
├── rate-limit/ # Global + per-user throttling
├── logging/ # MongoDB inquiry audit logs
├── providers/ # BaseProvider, LegacyApiProvider, factory, orchestrator
└── inquiry/ # Unified controllers & services
```
## Quick start
```bash
cp .env.example .env
# Edit .env with your provider credentials (see Environment Configuration Guide)
npm install
npm run cli:create-super-admin # interactive — creates SUPER_ADMIN
npm run start:dev
```
- API: `http://localhost:8085`
- Swagger: `http://localhost:8085/api/docs`
## Authentication & users
| Role | Capabilities |
|------|----------------|
| `SUPER_ADMIN` | Full access; create any user including other super admins |
| `ADMIN` | Manage users; all inquiry types |
| `USER` | Inquiry access per `allowedInquiries` |
**Auth endpoints:** `POST /auth/login`, `POST /auth/refresh`, `POST /auth/logout`, `GET /auth/profile`
**User management:** `POST/GET/PATCH /users`, block/unblock, reset password (ADMIN+ only)
```bash
# Login
curl -X POST http://localhost:8085/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"your-password"}'
# Person inquiry (JWT)
curl -X POST http://localhost:8085/inquiries/person \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <accessToken>" \
-d '{"nationalCode":"0012345678","birthDate":"1370-05-15"}'
```
Response envelope (`BaseInquiryResponseDto`):
```json
{
"success": true,
"provider": "HAMTA",
"trackingCode": "INQ-20250525-A1B2C3D4",
"message": "Person inquiry completed successfully",
"data": { "nationalCode": "0012345678", "birthDate": "1370-05-15", "fullName": "..." },
"duration": 342
}
```
## Provider configuration
Per-inquiry configuration via environment variables:
```env
# Default provider and fallback chain
PERSON_DEFAULT_PROVIDER=HAMTA
PERSON_FALLBACK_PROVIDERS=MOALLEM
# Per-inquiry credentials and authentication
HAMTA_PERSON_URL=https://api.example.com/person
HAMTA_PERSON_USERNAME=user123
HAMTA_PERSON_PASSWORD=pass123
HAMTA_PERSON_AUTH_METHOD=AMITIS
# AMITIS authentication service
AMITIS_LOGIN_URL=https://auth.services.centinsur.ir/api/security/login
AMITIS_REFRESH_URL=https://auth.services.centinsur.ir/api/security/RefreshToken
```
See [Environment Configuration Guide](docs/ENVIRONMENT_CONFIGURATION.md) for complete configuration options.
## Supported inquiry types
| Inquiry Type | Providers | Description |
|--------------|-----------|-------------|
| `PERSON_INQUIRY` | HAMTA, MOALLEM | Person information by national code and birth date |
| `REAL_ESTATE_INQUIRY` | HAMTA | Real estate ownership information |
| `POSTAL_CODE_INQUIRY` | HAMTA, MOALLEM | Address validation by postal code |
| `SHAHKAR_INQUIRY` | HAMTA, MOALLEM | Mobile number verification |
| `CIVIL_REGISTRATION_INQUIRY` | MOALLEM | Civil registration data |
| `SHEBA_INQUIRY` | MOALLEM | Bank account (SHEBA) validation |
| `SAYAH_INQUIRY` | TEJARATNOU | Sayah system inquiry |
See [API Documentation](docs/API_DOCUMENTATION.md) for detailed request/response formats.
## Authentication methods
| Method | Description | Use Case |
|--------|-------------|----------|
| `AMITIS` | Token-based auth via AMITIS service | Most CentInsur APIs |
| `SOAP` | Direct SOAP authentication | Legacy XML-based services |
| `OAUTH2` | OAuth 2.0 flow | Modern REST APIs |
| `NONE` | No authentication required | Public APIs |
## Token management
- **Token refresh**: Every 20 minutes automatically
- **Token expiration**: Daily at 23:59:59 Tehran time
- **Retry logic**: Automatic retry on HTTP 5xx errors and network failures
- **Error handling**: Graceful fallback to alternative providers
## Adding a new provider
1. Add `ProviderName` enum value in `src/common/enums/provider-name.enum.ts`
2. Add provider configuration in `src/config/configuration.ts`
3. Implement provider (extend `BaseProvider` or `LegacyApiProvider`)
4. Register in `src/providers/factory/provider.factory.ts`
5. Update inquiry routing env vars — **no new HTTP routes required**
## Adding a new inquiry type
1. Add `InquiryType` enum in `src/common/enums/inquiry-type.enum.ts`
2. Create request/response DTOs with `class-validator` in `src/inquiry/dto/`
3. Add `POST /inquiries/<type>` in `InquiryController`
4. Implement service method using `ProviderOrchestratorService`
5. Configure routing and credentials in `.env`
## Security
- **JWT**: access + refresh tokens (`JWT_SECRET`, `JWT_REFRESH_SECRET`)
- **RBAC**: `@Roles()` + `RolesGuard`
- **Inquiry access**: `allowedInquiries` + `InquiryAccessGuard` (e.g. `PERSON_INQUIRY`)
- **Rate limiting**: global throttler + per-user `requestLimitPerMinute` / `requestLimitPerDay`
- **Audit**: `audit_logs` for login, user lifecycle events
- **Request logging**: All inquiries logged to MongoDB with masked sensitive data
## Error handling
The system provides comprehensive error handling:
- Network errors: Automatic retry with exponential backoff
- HTTP 5xx errors: Automatic retry (configurable attempts)
- Provider failures: Automatic fallback to alternative providers
- Validation errors: Detailed error messages with field-level validation
- Authentication errors: Automatic token refresh and retry
## Monitoring & observability
- **OpenTelemetry**: Distributed tracing support
- **Inquiry logs**: MongoDB collection with full request/response audit trail
- **Audit logs**: Security events and user actions
- **Performance metrics**: Request duration, provider response times
- **Error tracking**: Normalized error codes and messages
## Development
```bash
# Development mode with hot reload
npm run start:dev
# Build for production
npm run build
# Run tests
npm run test
# Run tests with coverage
npm run test:cov
# Lint code
npm run lint
# Format code
npm run format
```
## Environment variables
Key environment variables (see `.env.example` for complete list):
```env
# Application
NODE_ENV=development
PORT=8085
API_PREFIX=api
# Database
MONGODB_URI=mongodb://localhost:27017/inquiry-gateway
# JWT
JWT_SECRET=your-secret-key
JWT_EXPIRES_IN=15m
JWT_REFRESH_SECRET=your-refresh-secret
JWT_REFRESH_EXPIRES_IN=7d
# Rate limiting
THROTTLE_TTL=60
THROTTLE_LIMIT=100
# Provider configuration (see Environment Configuration Guide)
```
## License
MIT