The bot service in docker-compose.yml builds from ./bot, but the agent code lived in 'ai procurement/' and ./bot was only a Windows junction on reza.g's machine (and was gitignored) — exactly as the team reported: 'bot/ was never committed — prod-v7's bot is un-buildable from the repo.' - junction removed; 'ai procurement/' renamed to 'bot/' via git mv (all 41 files keep their history as pure renames) - 'bot/' dropped from .gitignore (voice/ stays ignored — runtime voice notes; bot/.env stays ignored by bot/.gitignore) - compose needs no change: context: ./bot and ./bot/app now resolve to committed files - bot/INTEGRATION-REPORT.md added: full story (problem, root cause, git state, security note on the committed BALE_BOT_TOKEN / AI_API_KEY compose defaults, and usage instructions for the team) Verified: 41 renames staged with zero secret/cache files; voice/ and bot/.env still ignored.
45 lines
2.1 KiB
Markdown
45 lines
2.1 KiB
Markdown
# ERP integration pack
|
|
|
|
The agent is a **standalone container** — it talks to the ERP exclusively over
|
|
HTTP and keeps its own state in its own `bot_*` tables. Integrating it into the
|
|
[ERP stack](https://git.bennu-api-bahrestan.ir/ali_mohaghegh/ERP) needs exactly
|
|
two things:
|
|
|
|
## 1. Compose service
|
|
|
|
Add [`erp-compose-service.yml`](erp-compose-service.yml) to the ERP's
|
|
`docker-compose.yml` (and the Coolify variant). The bot long-polls Bale, so it
|
|
needs **no ports, no webhook, no TLS** — it joins the compose `default` network
|
|
and reaches `http://api:8000/api/v1` in-network.
|
|
|
|
Credentials/env are passed at compose level from a `.env` next to the compose
|
|
file: `BALE_BOT_TOKEN`, `AI_BASE_URL`, `AI_API_KEY`, `AI_LLM_MODEL`
|
|
(see [`../.env.example`](../.env.example) for the full list).
|
|
|
|
> If your stack is started with multiple `-f` files (e.g. a prod_v2 checkout +
|
|
> port-remap override), keep using the same chain — the `bot` service merges in
|
|
> like any other service and the override's host-port remaps don't affect it.
|
|
|
|
## 2. Per-user attribution in the API
|
|
|
|
Apply [`x-actor-id.patch`](x-actor-id.patch) — a ~6-line, fully
|
|
backward-compatible change to `backend/app/utils/security.py`:
|
|
|
|
- before: `get_actor` returns the raw `Authorization: Bearer …` string and
|
|
`quote_events.actor` stores the bot's token;
|
|
- after: an `X-Actor-Id: <users.id>` header (sent by the bot for every mutating
|
|
call, carrying the **linked ERP user's id**) takes precedence, so the audit
|
|
trail records the human who asked, not the bot.
|
|
|
|
Requests without the header behave exactly as before.
|
|
|
|
## What the agent does NOT touch
|
|
|
|
- No ERP code is imported by the bot (HTTP-only, own postgres tables
|
|
`bot_links` / `bot_drafts` / `bot_messages` / `bot_meta`, created idempotently
|
|
at startup with `CREATE TABLE IF NOT EXISTS`).
|
|
- No Alembic migration needed — the bot owns its schema.
|
|
- The ERP's data model stays untouched; committed drafts flow through the
|
|
ordinary public endpoints (`POST /quotes`, `PATCH /quotes/{id}/accept`,
|
|
`PATCH /quotes/{id}/arrive-items`, `POST /suppliers`, `POST /materials`).
|