Files
ten31-database/backend/matrix_intake/README.md
T
Keysat 7ad0ee7624 Add Matrix intake bot (M1+M2): typed message → approved fundraising-grid write
New backend/matrix_intake/ runs as its own process (matrix-nio isolated from the
stdlib CRM): local-Qwen parse via Spark Control → in-thread human approval
(yes/edit/no) → write through the CRM's own log-communication endpoint, tagged
source=matrix_intake. Adds read-only GET /api/intake/match (returns grid row id,
no-duplicate contract); threads provenance through handle_log_fundraising_communication.
Reviewer-passed: pop-before-commit closes a double-approve race; edit-grammar fix.
Text-only v1; business-card photo (M3) deferred (no Spark vision model).
26/26 tests green; live Matrix smoke pending deploy.
2026-06-17 07:51:27 -05:00

42 lines
1.8 KiB
Markdown

# Matrix intake bot
Turns a typed message in a dedicated Matrix room into a proposed fundraising-grid add/edit,
gated on in-thread human approval before any write. Runs as its own process (on the Spark),
separate from the CRM. Full design + rules: `docs/guides/matrix-intake.md`.
## Run
```bash
# 1. Install the one third-party dep (isolated to this component — NOT the CRM runtime)
python3 -m pip install -r requirements.txt # matrix-nio
# 2. Fill the MATRIX_* and CRM_BOT_* vars in the repo .env (see ../../.env.example),
# and create a dedicated CRM user for CRM_BOT_USERNAME/PASSWORD (admin → invite user).
# 3. Start the listener
python3 bot.py
```
It primes the Matrix sync past history (no backlog replay), then listens. Post a message in
the intake room; it replies in a thread with the parsed proposal. Reply **yes** to commit,
**edit field=value** to change a field, or **no** to discard.
## Layout
- `bot.py` — entrypoint: connect, prime-then-listen, dispatch (lifts matrix-bridge's plumbing).
- `parse.py` — message → structured proposal via local Qwen (`spark.py``backend/ingest/llm.py`).
- `proposals.py` — in-memory pending-proposal store + the yes/edit/no state machine.
- `crm_client.py` — login + `GET /api/intake/match` + write via `POST /api/fundraising/log-communication`.
- `matrix_io.py` — message splitting, thread-root detection, threaded-reply sender.
- `settings.py` — Matrix + CRM-API config (named `settings`, not `config`, to avoid shadowing `ingest/config`).
## Test (offline)
```bash
python3 test_parse.py && python3 test_proposals.py && python3 test_crm_client.py
# endpoint + create→match contract (boots the real server against a temp DB):
cd ../ && python3 test_intake_endpoints.py
```
Live Matrix behavior needs creds + `matrix-nio` and can only be smoke-tested on the Spark.