feat: accounting integration (D27), SMS relay driver (D26), rebuild user apps
- Add Tahesab/Zarrin accounting sync module with admin panel UI - Add SMS relay driver as default provider, refactor SMS into driver pattern - Update customer services, orders, products, and catalog queries - Rebuild user-app and user-app-v2 dist assets - Add Prisma migration for accounting tables - Update docker-compose and env examples - Update parity docs (DECISIONS, ISSUES, PROGRESS) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a72fa607a5
commit
19d490e790
+19
-9
@@ -39,10 +39,9 @@ Everything else is optional and may be left blank. Two you may want now:
|
||||
# real release (see "Before the real release" below).
|
||||
OTP_MASTER_CODE=1379
|
||||
|
||||
# Leave blank and SMS is logged, not sent. The server still starts.
|
||||
SMS_TREZ_USERNAME=
|
||||
SMS_TREZ_PASSWORD=
|
||||
SMS_TREZ_SENDER_LINE=
|
||||
# SMS goes through the "relay" gateway with nothing to set (D26).
|
||||
# SMS_PROVIDER=none turns sending off; the server still starts either way.
|
||||
SMS_PROVIDER=
|
||||
```
|
||||
|
||||
### Step 2 — build
|
||||
@@ -115,7 +114,9 @@ before it is a production release. The first three are blocking.
|
||||
| **1** | **Set `JWT_CUSTOMER_SECRET` to its own random value**, different from `JWT_SECRET`. | Not a cosmetic default. Unset, the API signs customer and sales-expert **app** tokens with `JWT_SECRET` — *the same key admin tokens use* — and the two token realms stop being cryptographically separate. The only remaining barrier is the `typ` check in `jwt.strategy.ts`, and a sales expert's app token carries their **AdminUser id** in `sub`. Two independent defences collapse into one. A loud boot banner fires while it is missing. **REL-03 (Critical).** |
|
||||
| **2** | **Remove `OTP_MASTER_CODE` from the environment.** | While set, **any active customer signs in with that one fixed code**. Unset or empty disables it completely; the API prints a banner at boot for as long as it is armed. **REL-01 (Critical).** |
|
||||
| **3** | **Set real `JWT_SECRET`.** | Without it the API falls back to a well-known development string, so anyone can forge an admin token. |
|
||||
| **4** | **Configure the SMS credentials** (`SMS_TREZ_USERNAME`, `SMS_TREZ_PASSWORD`, `SMS_TREZ_SENDER_LINE`). | Until then **no customer can receive a real login code** — messages are written to the log instead of sent. The server still boots (D20). **REL-02.** |
|
||||
| **4** | **Confirm SMS is going out.** The default `relay` gateway needs no credentials (D26); check `docker compose logs api` for `SMS provider: relay` and send yourself a login code. | If the gateway refuses the `host` value (inside Docker it is the container's IP), set `SMS_RELAY_HOST`. A failed send is only a log line — the server still boots (D20). **REL-02.** |
|
||||
|
||||
| **5** | **Accounting integration (D27), only if it will be switched on:** set `ACCOUNTING_SECRET_KEY`; count products with no image (they disappear from the app — query in ISSUES ACC-05) and photograph them first; for Zarrin, run the trial on temporary documents first (ACC-01). | The integration itself is off until an admin turns it on in «اتصال حسابداری»; nothing changes before that except the no-image rule, which applies to every product. |
|
||||
|
||||
After changing any of these: `docker compose up -d --build` and confirm the
|
||||
`OTP_MASTER_CODE` banner is **gone** from `docker compose logs api`.
|
||||
@@ -189,14 +190,21 @@ container.
|
||||
| `ADMIN_PANEL_PORT`, `USER_APP_PORT`, `USER_APP_V2_PORT` | 5180–5182 | Dev servers only. |
|
||||
| `RUN_MIGRATIONS` | `true` | Set `false` to skip the boot-time migration run. |
|
||||
| `RUN_SEED` | `true` | Set `false` to skip seeding. |
|
||||
| `ACCOUNTING_SECRET_KEY` | *(derived from `JWT_SECRET`)* | Encrypts the accounting-software token the admin enters (D27). Set its own long random value; changing it later means re-entering the token. |
|
||||
| `ACCOUNTING_WORKER` | `on` | `off` keeps this instance out of the accounting background sync. |
|
||||
| `PROFILE_ADMIN_MOBILES` | *(blank)* | Comma-separated admin mobiles told when a customer completes their profile. The reference hardcoded four numbers; blank means nobody is notified and the upload still succeeds. |
|
||||
|
||||
### SMS — all optional; blank means "log, do not send"
|
||||
### SMS — all optional
|
||||
|
||||
`SMS_PROVIDER` (`trez` default, or `none`), `SMS_TREZ_URL`,
|
||||
`SMS_TREZ_USERNAME`, `SMS_TREZ_PASSWORD`, `SMS_TREZ_SENDER_LINE`.
|
||||
`SMS_PROVIDER`: `relay` (default), `trez`, or `none` (D26).
|
||||
|
||||
With these unset the server **still starts normally** and logs a warning; a
|
||||
- **relay**: `SMS_RELAY_URL`, `SMS_RELAY_SECRET` (both have built-in
|
||||
defaults), `SMS_RELAY_HOST` (blank = the machine's first external IPv4),
|
||||
`SMS_RELAY_PLATFORM` (`kave` default, or `default` to let the gateway pick).
|
||||
- **trez**: `SMS_TREZ_URL`, `SMS_TREZ_USERNAME`, `SMS_TREZ_PASSWORD`,
|
||||
`SMS_TREZ_SENDER_LINE`.
|
||||
|
||||
The server **always starts**; a misconfigured provider is a warning, and a
|
||||
failed or skipped SMS never blocks an operation, including customer creation.
|
||||
|
||||
### ⚠ `OTP_MASTER_CODE` — delivery only
|
||||
@@ -405,4 +413,6 @@ Recorded in `docs/parity/DECISIONS.md`:
|
||||
the lowest-risk option, change nothing protected.
|
||||
- **D20** — SMS can never block a boot or an operation; `OTP_MASTER_CODE` for
|
||||
the delivery.
|
||||
- **D26** — SMS goes through the owner's `relay` gateway by default; Trez is
|
||||
kept as a selectable driver.
|
||||
- **D11 is cancelled** — superseded by D13.
|
||||
|
||||
Reference in New Issue
Block a user