forked from Yara724/api
Compare commits
9 Commits
8f8ed8a94e
...
7e597db423
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e597db423 | |||
| 8303bf4467 | |||
| ebe8671bd3 | |||
| 5022178569 | |||
| 2fbf40ef19 | |||
| dca9e1f8d4 | |||
| 87ece0d89d | |||
| 7af3f3627a | |||
| 7e1ae328ac |
578
docs/external-api-curls.md
Normal file
578
docs/external-api-curls.md
Normal file
@@ -0,0 +1,578 @@
|
|||||||
|
# External API Curl Guide
|
||||||
|
|
||||||
|
This file documents outbound HTTP calls made by the app or maintenance scripts.
|
||||||
|
Use placeholder values for secrets, tokens, IDs, plate values, and payloads before running any curl.
|
||||||
|
|
||||||
|
## Common Notes
|
||||||
|
|
||||||
|
- Internal app URLs in Swagger, localhost examples, and file download URLs are not listed.
|
||||||
|
- Package/build-time network calls such as npm registry, Sonar, and Docker setup are not runtime app requests.
|
||||||
|
- `firstValueFrom(this.httpService...)`, `lastValueFrom(this.httpService...)`, and `fetch(...)` call sites were checked.
|
||||||
|
- Several integrations cache bearer tokens in memory for about 55 minutes.
|
||||||
|
- Some Fanavaran credentials and the Map.ir API key are hardcoded in source. Treat them as sensitive and consider moving/rotating them.
|
||||||
|
|
||||||
|
## Fanavaran API Manager
|
||||||
|
|
||||||
|
Host:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
FANAVARAN_BASE_URL="https://apimanager.iraneit.com/BimeApiManager/api"
|
||||||
|
FANAVARAN_BIME_URL="$FANAVARAN_BASE_URL/BimeApi/v2.0"
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by:
|
||||||
|
|
||||||
|
- `src/fanavaran/fanavaran-lookup.service.ts`
|
||||||
|
- `src/fanavaran/fanavaran-lookup.config.ts`
|
||||||
|
- `src/claim-request-management/claim-request-management.service.ts`
|
||||||
|
|
||||||
|
### Sequence
|
||||||
|
|
||||||
|
1. Get `appToken`.
|
||||||
|
2. Login with `appToken` to get `authenticationToken`.
|
||||||
|
3. Call lookup, policy inquiry, or submit endpoint with `authenticationToken`, `CorpId`, `ContractId`, and `Location`.
|
||||||
|
|
||||||
|
### Tenant Credentials
|
||||||
|
|
||||||
|
The app supports these Fanavaran client profiles:
|
||||||
|
|
||||||
|
| Client | appname | secret | userName | password | CorpId | ContractId | Location |
|
||||||
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| tejaratno | from `src/core/config/fanavaran-client.config.ts` | hardcoded in source | hardcoded in source | hardcoded in source | `3539` | `263` | `100` |
|
||||||
|
| parsian | from `src/core/config/fanavaran-client.config.ts` | hardcoded in source | hardcoded in source | hardcoded in source | `543` | `28` | `210050` |
|
||||||
|
|
||||||
|
Set them as shell variables before running:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
APP_NAME="<appname>"
|
||||||
|
APP_SECRET="<secret>"
|
||||||
|
FANAVARAN_USERNAME="<userName>"
|
||||||
|
FANAVARAN_PASSWORD="<password>"
|
||||||
|
CORP_ID="<CorpId>"
|
||||||
|
CONTRACT_ID="<ContractId>"
|
||||||
|
LOCATION="<Location>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1. Get App Token
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -i -X POST "$FANAVARAN_BASE_URL/EITAuthentication/GetAppToken" \
|
||||||
|
-H "appname: $APP_NAME" \
|
||||||
|
-H "secret: $APP_SECRET" \
|
||||||
|
-H "Content-Length: 0"
|
||||||
|
```
|
||||||
|
|
||||||
|
The token is returned in a response header named `appToken` or `apptoken`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
APP_TOKEN="<response appToken header>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Login
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -i -X POST "$FANAVARAN_BASE_URL/EITAuthentication/Login" \
|
||||||
|
-H "appToken: $APP_TOKEN" \
|
||||||
|
-H "userName: $FANAVARAN_USERNAME" \
|
||||||
|
-H "password: $FANAVARAN_PASSWORD" \
|
||||||
|
-H "Content-Length: 0"
|
||||||
|
```
|
||||||
|
|
||||||
|
The token is returned in a response header or body field named `authenticationToken`, `authenticationtoken`, or `authentication_token`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
AUTHENTICATION_TOKEN="<response authenticationToken>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3A. Lookup Endpoints
|
||||||
|
|
||||||
|
These are fetched on demand and cached under `files/fanavaran-lookups/<client>/`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X GET "$FANAVARAN_BIME_URL/car/base-info/accident-causes" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
|
||||||
|
curl -X GET "$FANAVARAN_BIME_URL/car/code-list/accident-report-type" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
|
||||||
|
curl -X GET "$FANAVARAN_BIME_URL/car/base-info/vehicle-use-types" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
|
||||||
|
curl -X GET "$FANAVARAN_BIME_URL/car/code-list/dmg-pay-method" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
|
||||||
|
curl -X GET "$FANAVARAN_BIME_URL/car/base-info/driving-licence-types" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
|
||||||
|
curl -X GET "$FANAVARAN_BIME_URL/car/code-list/accident-culprit-type" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3B. Policy Inquiry By National Code
|
||||||
|
|
||||||
|
Used before Fanavaran claim submit to resolve a `PolicyId` when possible.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
NATIONAL_CODE="<insurer national code>"
|
||||||
|
|
||||||
|
curl -X GET "$FANAVARAN_BIME_URL/common/Policies/inquiry-my-policies?InsuranceLineId=5&NationalCode=$NATIONAL_CODE" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3C. Third-Party Car Financial Claim Submit
|
||||||
|
|
||||||
|
`fanavaranData` is built internally from a claim case/request. The shape is large; capture an app log or preview output and save it as JSON before replaying.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$FANAVARAN_BIME_URL/car/third-party-car-financial-claims" \
|
||||||
|
-H "authenticationToken: $AUTHENTICATION_TOKEN" \
|
||||||
|
-H "CorpId: $CORP_ID" \
|
||||||
|
-H "ContractId: $CONTRACT_ID" \
|
||||||
|
-H "Location: $LOCATION" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data @fanavaran-claim-submit.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tejarat Inquiry Provider
|
||||||
|
|
||||||
|
Default base URL:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
TEJARAT_INQUIRY_BASE_URL="${TEJARAT_INQUIRY_BASE_URL:-http://82.99.202.245:3027}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by `src/sand-hub/sand-hub.service.ts` for third-party plate and car-body plate inquiries when ESG is not selected.
|
||||||
|
|
||||||
|
### Sequence
|
||||||
|
|
||||||
|
1. Login to `/user/login`.
|
||||||
|
2. Use returned `accessToken` as `Authorization: Bearer ...`.
|
||||||
|
3. Call inquiry endpoint.
|
||||||
|
|
||||||
|
### Login
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$TEJARAT_INQUIRY_BASE_URL/user/login" \
|
||||||
|
-H "Accept: */*" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{
|
||||||
|
"email": "'"$TEJARAT_INQUIRY_EMAIL"'",
|
||||||
|
"password": "'"$TEJARAT_INQUIRY_PASSWORD"'"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
TEJARAT_ACCESS_TOKEN="<response accessToken>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Third-Party Plate / Policy Block Inquiry
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$TEJARAT_INQUIRY_BASE_URL/block-inquiry-tejarat" \
|
||||||
|
-H "Authorization: Bearer $TEJARAT_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"leftTwoDigits": "12",
|
||||||
|
"serialLetter": "ب",
|
||||||
|
"threeDigits": "345",
|
||||||
|
"rightTwoDigits": "67",
|
||||||
|
"nationalCode": "0012345678"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Car-Body Plate Inquiry
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$TEJARAT_INQUIRY_BASE_URL/block-inquiry-tejarat/badane" \
|
||||||
|
-H "Authorization: Bearer $TEJARAT_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"part1": 12,
|
||||||
|
"part2": "ب",
|
||||||
|
"part3": 345,
|
||||||
|
"part4": 67,
|
||||||
|
"nationalCode": "0012345678"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## ESG Inquiry Provider
|
||||||
|
|
||||||
|
Default/fallback base URL in some call sites:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ESG_URL="${ESG_URL:-http://192.168.20.22:8085}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Used by `src/sand-hub/sand-hub.service.ts` for selected tenants, for example when `CLIENT_ID=8`.
|
||||||
|
|
||||||
|
### Sequence
|
||||||
|
|
||||||
|
1. Login to `/auth/login`.
|
||||||
|
2. Use returned `accessToken` as `Authorization: Bearer ...`.
|
||||||
|
3. Call the inquiry endpoint.
|
||||||
|
|
||||||
|
### Login
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$ESG_URL/auth/login" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{
|
||||||
|
"username": "'"$ESG_USERNAME"'",
|
||||||
|
"password": "'"$ESG_PASSWORD"'"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ESG_ACCESS_TOKEN="<response accessToken>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Policy By Plate
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$ESG_URL/inquiry/policyByPlate" \
|
||||||
|
-H "Authorization: Bearer $ESG_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"nationalCode": "0012345678",
|
||||||
|
"plk1": "12",
|
||||||
|
"plk2": "ب",
|
||||||
|
"plk3": "345",
|
||||||
|
"plksrl": "67"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Person Inquiry
|
||||||
|
|
||||||
|
ESG expects Jalali birth date, normalized as `YYYY-MM-DD`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$ESG_URL/inquiry/person" \
|
||||||
|
-H "Authorization: Bearer $ESG_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"nationalCode": "0012345678",
|
||||||
|
"birthDate": "1378-11-24",
|
||||||
|
"dateHasPostfix": 0
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sheba Validation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$ESG_URL/inquiry/sheba" \
|
||||||
|
-H "Authorization: Bearer $ESG_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"accountOwnerType": "1",
|
||||||
|
"nationalCode": "0012345678",
|
||||||
|
"legalId": "",
|
||||||
|
"sheba": "IR000000000000000000000000"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## SandHub Provider
|
||||||
|
|
||||||
|
Used by `src/sand-hub/sand-hub.service.ts` for legacy inquiry flows.
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
SANHUB_URL_LOGIN="<login URL>"
|
||||||
|
SANHUB_BASE_URL="<base URL>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sequence
|
||||||
|
|
||||||
|
1. Login through `SANHUB_URL_LOGIN`.
|
||||||
|
2. Use returned `accessToken` as `Authorization: Bearer ...`.
|
||||||
|
3. Call the required endpoint under `SANHUB_BASE_URL`.
|
||||||
|
|
||||||
|
### Login
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$SANHUB_URL_LOGIN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{
|
||||||
|
"email": "'"$SANHUB_USERNAME"'",
|
||||||
|
"password": "'"$SANHUB_PASSWORD"'"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
SANHUB_ACCESS_TOKEN="<response accessToken>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Third-Party Plate / Policy Block Inquiry
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$SANHUB_BASE_URL/block-inquiry-tejarat" \
|
||||||
|
-H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"leftTwoDigits": "12",
|
||||||
|
"serialLetter": "ب",
|
||||||
|
"threeDigits": "345",
|
||||||
|
"rightTwoDigits": "67",
|
||||||
|
"nationalCode": "0012345678"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Personal Inquiry
|
||||||
|
|
||||||
|
The app converts Jalali birth dates to Gregorian before sending to SandHub.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$SANHUB_BASE_URL/personal-inquiry/tejarat-no" \
|
||||||
|
-H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"nationalCode": "0012345678",
|
||||||
|
"birthdate": "1999-02-13"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Driving License Check
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$SANHUB_BASE_URL/driver-license-check" \
|
||||||
|
-H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"driverLicenseNumber": "1234567890",
|
||||||
|
"nationalCode": "0012345678"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Car Ownership
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$SANHUB_BASE_URL/ownership" \
|
||||||
|
-H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"Plk1": "12",
|
||||||
|
"Plk2": "ب",
|
||||||
|
"Plk3": "345",
|
||||||
|
"plkSrl": "67",
|
||||||
|
"nationalCode": "0012345678"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sheba Validation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$SANHUB_BASE_URL/sheba/sheba-tejaratno" \
|
||||||
|
-H "Authorization: Bearer $SANHUB_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"AccountOwnerType": "1",
|
||||||
|
"NationalId": "0012345678",
|
||||||
|
"ShebaId": "IR000000000000000000000000"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Map.ir Reverse Geocoding
|
||||||
|
|
||||||
|
Used by `src/claim-request-management/claim-request-management.service.ts`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
MAP_IR_API_KEY="<x-api-key>"
|
||||||
|
LAT="35.6892"
|
||||||
|
LON="51.3890"
|
||||||
|
|
||||||
|
curl -X GET "https://map.ir/fast-reverse?lat=$LAT&lon=$LON" \
|
||||||
|
-H "accept: application/json" \
|
||||||
|
-H "x-api-key: $MAP_IR_API_KEY"
|
||||||
|
```
|
||||||
|
|
||||||
|
## SMS Providers
|
||||||
|
|
||||||
|
### Kavenegar
|
||||||
|
|
||||||
|
Used by `src/sms-orchestration/provider/kavenegar.service.ts`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
SMS_API_KEY="<kavenegar API key>"
|
||||||
|
KAVENEGAR_BASE_URL="https://api.kavenegar.com/v1/$SMS_API_KEY"
|
||||||
|
```
|
||||||
|
|
||||||
|
Send SMS:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST -G "$KAVENEGAR_BASE_URL/sms/send.json" \
|
||||||
|
--data-urlencode "receptor=09120000000" \
|
||||||
|
--data-urlencode "message=Hello" \
|
||||||
|
--data-urlencode "sender=<optional sender>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify lookup:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -G "$KAVENEGAR_BASE_URL/verify/lookup.json" \
|
||||||
|
--data-urlencode "receptor=09120000000" \
|
||||||
|
--data-urlencode "token=123456" \
|
||||||
|
--data-urlencode "template=<template>" \
|
||||||
|
--data-urlencode "token2=<optional token2>" \
|
||||||
|
--data-urlencode "token3=<optional token3>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parsian SMS Gateway
|
||||||
|
|
||||||
|
Used by `src/sms-orchestration/provider/parsian-sms.gateway.ts`.
|
||||||
|
|
||||||
|
`PARSIAN_SMS_URL` is expected to already include the provider URL prefix and query key before receptor. The app appends `=<receptor>&Message=<encoded message>`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PARSIAN_SMS_URL="<provider URL prefix>"
|
||||||
|
PARSIAN_API_KEY="<package API key>"
|
||||||
|
PARSIAN_BASIC_TOKEN="<basic token>"
|
||||||
|
RECEPTOR="09120000000"
|
||||||
|
MESSAGE="Hello"
|
||||||
|
|
||||||
|
curl -X GET "$PARSIAN_SMS_URL=$RECEPTOR&Message=$(printf %s "$MESSAGE" | jq -sRr @uri)" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-PACKAGE-API-KEY: $PARSIAN_API_KEY" \
|
||||||
|
-H "Authorization: Basic $PARSIAN_BASIC_TOKEN"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Car Price Provider
|
||||||
|
|
||||||
|
Used by `src/expert-claim/expert-claim.service.ts` to fetch car prices from `CW_URL`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
CW_URL="<base URL ending with slash if required by provider>"
|
||||||
|
|
||||||
|
curl -X GET "${CW_URL}price?akharin"
|
||||||
|
curl -X GET "${CW_URL}price?hamrah"
|
||||||
|
```
|
||||||
|
|
||||||
|
## AI Service Calls Currently Disabled
|
||||||
|
|
||||||
|
`src/ai/ai.service.ts` contains configured URLs but the actual axios calls are commented out. If re-enabled, the sequence is:
|
||||||
|
|
||||||
|
1. `POST $AI_URL_V2/auth/login`
|
||||||
|
2. `GET $AI_URL_V2/auth/profile`
|
||||||
|
3. `POST $AI_URL_V2/services/car-damage/detector?version=ai-v7`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
AI_URL_V2="<AI service base URL>"
|
||||||
|
|
||||||
|
curl -X POST "$AI_URL_V2/auth/login" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
--data '{
|
||||||
|
"username": "'"$AI_USERNAME"'",
|
||||||
|
"password": "'"$AI_PASSWORD"'"
|
||||||
|
}'
|
||||||
|
|
||||||
|
AI_ACCESS_TOKEN="<response accessToken>"
|
||||||
|
|
||||||
|
curl -X GET "$AI_URL_V2/auth/profile" \
|
||||||
|
-H "Authorization: Bearer $AI_ACCESS_TOKEN"
|
||||||
|
|
||||||
|
GATEWAY_API_KEY="<profile apiKey.key>"
|
||||||
|
|
||||||
|
curl -X POST "$AI_URL_V2/services/car-damage/detector?version=ai-v7" \
|
||||||
|
-H "Authorization: Bearer $AI_ACCESS_TOKEN" \
|
||||||
|
-H "gateway-api-key: $GATEWAY_API_KEY" \
|
||||||
|
-F "images=@/path/to/car-image.jpg"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Refresh Blame Inquiries Script
|
||||||
|
|
||||||
|
Used by `scripts/refresh-blame-inquiries.js`. This script does not login; it expects pre-provided bearer tokens:
|
||||||
|
|
||||||
|
- `TEJARAT_THIRD_PARTY_TOKEN` or `TEJARAT_TOKEN`
|
||||||
|
- `TEJARAT_CAR_BODY_TOKEN` or `TEJARAT_TOKEN`
|
||||||
|
- `TEJARAT_PERSON_TOKEN` or `TEJARAT_TOKEN`
|
||||||
|
|
||||||
|
Default URLs:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
TEJARAT_THIRD_PARTY_URL="${TEJARAT_THIRD_PARTY_URL:-http://82.99.202.245:3027/block-inquiry-tejarat}"
|
||||||
|
TEJARAT_CAR_BODY_URL="${TEJARAT_CAR_BODY_URL:-http://82.99.202.245:3027/block-inquiry-tejarat/badane}"
|
||||||
|
TEJARAT_PERSON_URL="${TEJARAT_PERSON_URL:-http://82.99.202.245:3027/personal-inquiry/tejarat-no}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Third-party inquiry:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$TEJARAT_THIRD_PARTY_URL" \
|
||||||
|
-H "authorization: Bearer $TEJARAT_THIRD_PARTY_TOKEN" \
|
||||||
|
-H "content-type: application/json" \
|
||||||
|
-H "accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"leftTwoDigits": "12",
|
||||||
|
"serialLetter": "ب",
|
||||||
|
"threeDigits": "345",
|
||||||
|
"rightTwoDigits": "67",
|
||||||
|
"nationalCode": "0012345678"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Car-body inquiry:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$TEJARAT_CAR_BODY_URL" \
|
||||||
|
-H "authorization: Bearer $TEJARAT_CAR_BODY_TOKEN" \
|
||||||
|
-H "content-type: application/json" \
|
||||||
|
-H "accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"part1": 12,
|
||||||
|
"part2": "ب",
|
||||||
|
"part3": 345,
|
||||||
|
"part4": 67,
|
||||||
|
"nationalCode": "0012345678"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Personal inquiry:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -X POST "$TEJARAT_PERSON_URL" \
|
||||||
|
-H "authorization: Bearer $TEJARAT_PERSON_TOKEN" \
|
||||||
|
-H "content-type: application/json" \
|
||||||
|
-H "accept: application/json" \
|
||||||
|
--data '{
|
||||||
|
"nationalCode": "0012345678",
|
||||||
|
"birthdate": "1999-02-13"
|
||||||
|
}'
|
||||||
|
```
|
||||||
@@ -189,6 +189,7 @@ export interface FanavaranAutoSubmitResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FANAVARAN_ACCIDENT_LOCATION_ADDRESS = "استان تهران شهر تهران";
|
const FANAVARAN_ACCIDENT_LOCATION_ADDRESS = "استان تهران شهر تهران";
|
||||||
|
const FANAVARAN_DEFAULT_ACCIDENT_CAUSE_ID = 6;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ClaimRequestManagementService {
|
export class ClaimRequestManagementService {
|
||||||
@@ -3347,23 +3348,6 @@ export class ClaimRequestManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private resolveAccidentCauseId(accidentReason?: {
|
|
||||||
id?: string | number | null;
|
|
||||||
fanavaran?: number | null;
|
|
||||||
}): number | null {
|
|
||||||
const fanavaranValue = accidentReason?.fanavaran;
|
|
||||||
const idValue = accidentReason?.id;
|
|
||||||
|
|
||||||
if (fanavaranValue !== undefined && fanavaranValue !== null) {
|
|
||||||
if (fanavaranValue === 0) {
|
|
||||||
return idValue !== undefined && idValue !== null ? Number(idValue) : null;
|
|
||||||
}
|
|
||||||
return fanavaranValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private applyFanavaranDefaultFields(result: Record<string, unknown>): void {
|
private applyFanavaranDefaultFields(result: Record<string, unknown>): void {
|
||||||
result.ActualPremium = null;
|
result.ActualPremium = null;
|
||||||
result.ArchiveNo = null;
|
result.ArchiveNo = null;
|
||||||
@@ -3431,14 +3415,10 @@ export class ClaimRequestManagementService {
|
|||||||
input.defaults ?? this.TEJARATNO_FANAVARAN_DEFAULTS;
|
input.defaults ?? this.TEJARATNO_FANAVARAN_DEFAULTS;
|
||||||
const result: Record<string, unknown> = {
|
const result: Record<string, unknown> = {
|
||||||
...lookupDefaults,
|
...lookupDefaults,
|
||||||
AccidentCauseId: this.resolveAccidentCauseId(input.accidentReason),
|
AccidentCauseId: FANAVARAN_DEFAULT_ACCIDENT_CAUSE_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (input.accidentReason && result.AccidentCauseId === null) {
|
if (!input.accidentReason) {
|
||||||
this.logger.warn(
|
|
||||||
`${input.logPrefix} accidentReason exists but fanavaran is null or undefined`,
|
|
||||||
);
|
|
||||||
} else if (!input.accidentReason) {
|
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`${input.logPrefix} expert decision / accidentReason is missing`,
|
`${input.logPrefix} expert decision / accidentReason is missing`,
|
||||||
);
|
);
|
||||||
@@ -3544,58 +3524,16 @@ export class ClaimRequestManagementService {
|
|||||||
CompensationReferenceId: 167,
|
CompensationReferenceId: 167,
|
||||||
CulpritLicenceTypeId: 2,
|
CulpritLicenceTypeId: 2,
|
||||||
CulpritTypeId: 337,
|
CulpritTypeId: 337,
|
||||||
AccidentCauseId: 6, // Initialize to null, will be set if found
|
AccidentCauseId: FANAVARAN_DEFAULT_ACCIDENT_CAUSE_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
// AccidentCauseId: from expertSubmitReplyFinal.fields.accidentReason.fanavaran
|
if (
|
||||||
// If fanavaran is 0, use id instead. First check if expertSubmitReplyFinal exists, if not check expertSubmitReply
|
!blameRequest.expertSubmitReplyFinal &&
|
||||||
if (blameRequest.expertSubmitReplyFinal) {
|
!blameRequest.expertSubmitReply
|
||||||
// expertSubmitReplyFinal exists, use it for AccidentCauseId
|
) {
|
||||||
const accidentReason =
|
|
||||||
blameRequest.expertSubmitReplyFinal?.fields?.accidentReason;
|
|
||||||
const fanavaranValue = accidentReason?.fanavaran;
|
|
||||||
const idValue = accidentReason?.id;
|
|
||||||
|
|
||||||
if (fanavaranValue !== undefined && fanavaranValue !== null) {
|
|
||||||
// If fanavaran is 0, use id instead
|
|
||||||
if (fanavaranValue === 0) {
|
|
||||||
result.AccidentCauseId =
|
|
||||||
idValue !== undefined && idValue !== null ? idValue : null;
|
|
||||||
} else {
|
|
||||||
result.AccidentCauseId = fanavaranValue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.logger.warn(
|
|
||||||
`[Fanavaran Submit] expertSubmitReplyFinal exists but fanavaran is null or undefined`,
|
|
||||||
);
|
|
||||||
result.AccidentCauseId = null;
|
|
||||||
}
|
|
||||||
} else if (blameRequest.expertSubmitReply) {
|
|
||||||
// expertSubmitReplyFinal is null, use expertSubmitReply
|
|
||||||
const accidentReason =
|
|
||||||
blameRequest.expertSubmitReply?.fields?.accidentReason;
|
|
||||||
const fanavaranValue = accidentReason?.fanavaran;
|
|
||||||
const idValue = accidentReason?.id;
|
|
||||||
|
|
||||||
if (fanavaranValue !== undefined && fanavaranValue !== null) {
|
|
||||||
// If fanavaran is 0, use id instead
|
|
||||||
if (fanavaranValue === 0) {
|
|
||||||
result.AccidentCauseId =
|
|
||||||
idValue !== undefined && idValue !== null ? idValue : null;
|
|
||||||
} else {
|
|
||||||
result.AccidentCauseId = fanavaranValue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.logger.warn(
|
|
||||||
`[Fanavaran Submit] expertSubmitReply exists but fanavaran is null or undefined`,
|
|
||||||
);
|
|
||||||
result.AccidentCauseId = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`[Fanavaran Submit] Both expertSubmitReplyFinal and expertSubmitReply are null/undefined`,
|
`[Fanavaran Submit] Both expertSubmitReplyFinal and expertSubmitReply are null/undefined`,
|
||||||
);
|
);
|
||||||
result.AccidentCauseId = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccidentDate: Convert createdAt to Persian date
|
// AccidentDate: Convert createdAt to Persian date
|
||||||
@@ -3925,8 +3863,30 @@ export class ClaimRequestManagementService {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const policyCount = Array.isArray(response.data)
|
||||||
|
? response.data.length
|
||||||
|
: 0;
|
||||||
|
const lastPolicy = policyCount > 0 ? response.data[policyCount - 1] : null;
|
||||||
|
|
||||||
|
this.logger.log(
|
||||||
|
`${logPrefix} Policy inquiry response status=${response.status} count=${policyCount}`,
|
||||||
|
);
|
||||||
|
this.logger.log(
|
||||||
|
`${logPrefix} Policy inquiry raw response: ${JSON.stringify(
|
||||||
|
response.data,
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
if (lastPolicy && typeof lastPolicy === "object") {
|
||||||
|
this.logger.log(
|
||||||
|
`${logPrefix} Policy inquiry last policy keys: ${Object.keys(
|
||||||
|
lastPolicy,
|
||||||
|
).join(", ")}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (Array.isArray(response.data) && response.data.length > 0) {
|
if (Array.isArray(response.data) && response.data.length > 0) {
|
||||||
const lastPolicy = response.data[response.data.length - 1];
|
|
||||||
const policyId = lastPolicy?.PolicyId;
|
const policyId = lastPolicy?.PolicyId;
|
||||||
if (policyId !== undefined && policyId !== null) {
|
if (policyId !== undefined && policyId !== null) {
|
||||||
this.logger.log(
|
this.logger.log(
|
||||||
|
|||||||
@@ -156,6 +156,10 @@ export class FanavaranLookupService {
|
|||||||
const appToken = await this.getAppToken(profile.auth);
|
const appToken = await this.getAppToken(profile.auth);
|
||||||
const authenticationToken = await this.login(appToken, profile.auth);
|
const authenticationToken = await this.login(appToken, profile.auth);
|
||||||
|
|
||||||
|
this.logger.log(
|
||||||
|
`[${clientKey}] Calling Fanavaran lookup API: ${url}`,
|
||||||
|
);
|
||||||
|
|
||||||
const response = await firstValueFrom(
|
const response = await firstValueFrom(
|
||||||
this.httpService.get(url, {
|
this.httpService.get(url, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -169,6 +173,34 @@ export class FanavaranLookupService {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const dataCount = Array.isArray(response.data)
|
||||||
|
? response.data.length
|
||||||
|
: typeof response.data === "object" && response.data !== null
|
||||||
|
? Object.keys(response.data).length
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
this.logger.log(
|
||||||
|
`[${clientKey}] Fanavaran lookup response status=${response.status} dataCount=${dataCount}`,
|
||||||
|
);
|
||||||
|
this.logger.log(
|
||||||
|
`[${clientKey}] Fanavaran lookup raw response: ${JSON.stringify(
|
||||||
|
response.data,
|
||||||
|
null,
|
||||||
|
2,
|
||||||
|
)}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Array.isArray(response.data) && response.data.length > 0) {
|
||||||
|
const firstItem = response.data[0];
|
||||||
|
if (firstItem && typeof firstItem === "object") {
|
||||||
|
this.logger.log(
|
||||||
|
`[${clientKey}] Fanavaran lookup first item keys: ${Object.keys(
|
||||||
|
firstItem,
|
||||||
|
).join(", ")}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = isAxiosError(error)
|
const message = isAxiosError(error)
|
||||||
|
|||||||
Reference in New Issue
Block a user