Production-minded reference implementation for AI workflow orchestration around business operations: document/CRM/call intake, RAG retrieval, call-audio transcription contracts, transcript analysis, approval queues, outbox handoff, and n8n/Telegram/CRM integration surfaces.
The project keeps the workflow engine thin and moves stateful logic into a backend service. n8n can own webhooks, retries, notifications, and human-in-the-loop routing while the API owns RAG, scoring, audit-friendly state transitions, and integration contracts.
Profile / contact route: DriveDesk AI Operator proof route, portfolio, and inbound brief.
This repository is public proof for AI workflow automation work where the output must be more than a prompt demo.
| What to check | Why it matters |
|---|---|
| Stable reviewer route | Current proof status, CI, local gate, committed evidence, live-runtime boundary, and fallback review path in one page. |
| Runtime demo notes | Availability-dependent VPS demo notes for the browser-visible Sales Ops workflow; use them after the public proof status page confirms the edge is reachable. |
| Live approval proof | Real Telegram approval callback proof: approved item -> queued CRM handoff, while Bitrix24 stays dry-run. |
| Reviewer acceptance report | Live-runtime acceptance pass across API, smoke, GitHub Actions state, Pages route, and public PDF when the VPS edge is reachable. |
| Public proof status | Current CI, local verification gate, committed evidence, runtime boundary, Pages route, and public boundary status. |
| CI workflow | Deterministic tests for workflow state, RAG boundaries, integration contracts, and public verification. |
| Role requirements map | Role-level AI automation requirements mapped to files, endpoints, commands, and production boundaries. |
Best-fit evidence:
- RAG/backend ownership: document and CRM intake contracts, connector/export adapters, chunking, retrieval, pgvector-ready storage, OpenAI/Claude/Gemini LLM boundary, and Whisper/Deepgram transcription boundary;
- human-in-the-loop workflow ownership: approval queue, explicit state transitions, Telegram inline callback handling, and n8n integration shape;
- business automation ownership: call-audio webhook, transcription normalization, transcript scoring, context capture, and review routing;
- engineering discipline: deterministic local embeddings, tests, Docker runtime, docs, and CI.
Fast evaluation path:
- Open
docs/PUBLIC_PROOF_STATUS.md. - Run
bash scripts/verify_public.sh. - Open
docs/LIVE_OWNER_PROOF.md. - Run
python3 scripts/reviewer_acceptance_report.pywhenhttps://saleops.duckdns.org/is reachable. - Open
docs/ROLE_REQUIREMENTS_MAP.md. - Review
infra/n8n/to see the orchestration boundary.
| Surface | Proof |
|---|---|
| Public status | Public proof status with current CI, local gate, committed evidence, runtime reachability boundary, Pages route, and public boundary. |
| Live approval proof | Live approval proof for Telegram callback approval and CRM-safe outbox handoff. |
| Integration boundaries | Public proof status, reviewer acceptance report, and committed sanitized artifacts for Telegram and Bitrix24 boundary checks. |
| Offer demo | Offer demo for document import -> RAG -> call-audio transcription boundary -> transcript scoring -> Telegram approval -> outbox drain -> dry-run Bitrix24 handoff. |
| Reviewer gate | Reviewer checklist, CI workflow, and deterministic tests in tests/. |
| Runtime docs | Live demo notes, Operations notes, and runtime endpoints /runtime, /llm/runtime, /transcription/runtime, /integrations/runtime, /metrics. |
| Architecture | Architecture notes, Evidence map, and Integration skeleton. |
| n8n boundary | n8n approval flow and importable workflows in infra/n8n/. |
flowchart LR
Drive[Documents / CRM / call audio / transcripts] --> N8N[n8n workflows]
Telegram[Telegram approval bot] <--> N8N
N8N --> API[FastAPI workflow API]
API --> STT[Whisper / Deepgram / local fixture]
API --> Vector[(PostgreSQL + pgvector)]
API --> LLM[LLM API adapter]
API --> Queue[Approval queue]
Queue --> N8N
- FastAPI service boundary for AI workflow orchestration.
- Browser-visible Sales Ops Control Tower demo at
/. - Document intake contracts for exported document text from n8n, Google Drive, CRM, or another connector.
- Call-audio webhook and browser upload endpoint that convert audio through a transcription provider boundary into normalized transcript text.
- Transcription runtime endpoint for OpenAI Whisper, Deepgram, and deterministic local fixture without exposing secrets.
- RAG ingestion and retrieval with deterministic local embeddings for repeatable development.
- pgvector-ready schema and Docker Compose runtime.
- Transcript webhook that produces a structured analysis and a human approval item.
- Dry-run Bitrix24 CRM handoff event queued only after human approval; the Bitrix adapter can be credentialed later without changing the approval/RAG flow.
- CRM outbox state with idempotency keys, attempt counters, retry scheduling, last error, and dead-letter handling.
- Optional background worker for Bitrix24 outbox drain, disabled in public dry-run mode.
- Dry-run document intake and Bitrix24 dispatch contracts ready for real credentials.
- Telegram approval can run live for operator-triggered approvals while the public synthetic demo stays dry-run.
- Telegram callback webhook for inline approve/reject decisions.
- Optional Telegram webhook secret verification for production callbacks.
- Approval state machine for Telegram, CRM, or internal review loops.
- n8n workflow examples for document-to-RAG and webhook-to-API-to-approval routing.
- Runtime evidence endpoints for version, deploy environment, counters, and Prometheus-style metrics.
- Tests around chunking, embeddings, retrieval, and approval state transitions.
python3 -m pip install -r requirements.txt
python3 scripts/run_offer_demo.pyThe script runs a complete synthetic sales workflow without external API keys:
Document playbook import -> RAG retrieval -> call audio transcription -> transcript analysis
-> follow-up approval -> Telegram callback -> outbox drain -> dry-run Bitrix24 CRM handoff event
See docs/OFFER_DEMO.md for the reviewer path and expected output shape.
Full public verification gate:
bash scripts/verify_public.shLive deployment smoke:
python3 scripts/capture_reviewer_evidence.py
python3 scripts/reviewer_snapshot.py
python3 scripts/production_readiness_drill.py
python3 scripts/credentialed_sandbox_preflight.py
python3 scripts/credentialed_sandbox_preflight.py --require-target telegram
python3 scripts/credentialed_sandbox_preflight.py --require-target bitrix24
python3 scripts/live_telegram_approval_evidence.py --approval-id <approved-approval-id>
python3 scripts/bitrix24_contract_evidence.py
bash scripts/smoke_live_demo.sh
bash scripts/smoke_live_demo.sh https://leadscore.duckdns.orgcp .env.example .env
docker compose up --buildDemo UI:
http://127.0.0.1:8080/
Public demo:
https://saleops.duckdns.org/
https://leadscore.duckdns.org/
API:
curl http://127.0.0.1:8080/health
curl http://127.0.0.1:8080/runtime
curl http://127.0.0.1:8080/llm/runtime
curl http://127.0.0.1:8080/transcription/runtime
curl http://127.0.0.1:8080/metricsIngest a document:
curl -X POST http://127.0.0.1:8080/documents \
-H 'content-type: application/json' \
-d '{"source":"drive://sales-playbook","text":"Discovery calls should confirm budget, authority, need, timing, and next step.","metadata":{"team":"sales"}}'Ask a RAG-backed question:
curl -X POST http://127.0.0.1:8080/query \
-H 'content-type: application/json' \
-d '{"question":"What should be confirmed during discovery calls?","top_k":3}'Create an approval item:
curl -X POST http://127.0.0.1:8080/approvals \
-H 'content-type: application/json' \
-d '{"kind":"content_review","title":"Approve generated follow-up","draft":"Send a follow-up with budget, timeline, and next step.","context":{"lead_id":"L-1024"}}'| Endpoint | Purpose |
|---|---|
GET / |
Browser-visible Sales Ops Control Tower demo. |
GET /health |
Runtime health and active storage mode. |
GET /runtime |
Runtime version, build SHA, deploy environment, public callback URL, LLM provider state, integrations, worker state, and counters. |
GET /metrics |
Prometheus-style runtime and workflow counters. |
GET /llm/runtime |
Inspect the OpenAI, Claude, Gemini, and local fallback provider boundary without exposing secrets. |
GET /transcription/runtime |
Inspect the local fixture, OpenAI Whisper, and Deepgram transcription boundary without exposing secrets. |
GET /integrations/runtime |
Inspect Google Drive, Telegram, and Bitrix24 adapter configuration/dry-run status. |
POST /demo/run |
Run the synthetic document import through the Google Drive adapter -> call-audio transcription -> transcript -> RAG -> approval -> Telegram/Bitrix dry-run demo. |
POST /documents |
Chunk and ingest text into the vector store. |
POST /integrations/google-drive/import |
Import exported Google Drive document text into the RAG store with Drive metadata. |
POST /query |
Retrieve context and produce an answer draft. |
POST /approvals |
Create a human-in-the-loop approval item. |
GET /approvals |
List approval items, optionally filtered by status. |
GET /approvals/{id} |
Inspect one approval item. |
POST /approvals/{id}/notify/telegram |
Build or send a Telegram approval message. |
POST /webhooks/telegram/approval |
Accept Telegram inline button callbacks and apply approve/reject decisions. |
POST /approvals/{id}/approve |
Approve an item and attach reviewer notes. |
POST /approvals/{id}/reject |
Reject an item and attach reviewer notes. |
GET /integration-events |
Inspect CRM/integration handoff events, optionally filtered by adapter or status. |
POST /integration-events/{id}/dispatch/bitrix24 |
Dry-run or send a queued CRM event through Bitrix24, recording attempts and dead-letter state outside dry-run mode. |
POST /integrations/bitrix24/drain |
Worker-style drain for due queued/retry CRM events. |
POST /webhooks/n8n/call-audio |
Accept call audio metadata, build a transcription contract, normalize transcript text, and continue into transcript analysis. |
POST /webhooks/n8n/call-transcript |
Accept a transcript event, score it, ingest it, and create approval work. |
app/ FastAPI application, workflow domain code, and browser demo payloads
demo/ Synthetic reference playbook and transcript fixtures
infra/n8n/ Importable n8n workflow examples
docs/ Offer demo, reviewer checklist, architecture, n8n, integrations and operations notes
scripts/ Reviewer-facing demo runner and public verification gate
tests/ Unit tests for the core behavior
docker-compose.yml
Dockerfile
python3 -m pip install -r requirements.txt
bash scripts/verify_public.sh- The default local embedding provider is deterministic, so tests and development runs are stable without API keys.
- LLM calls are isolated behind a provider boundary.
LLM_PROVIDER=autocan select OpenAI, Claude/Anthropic, or Gemini when the matching API key is configured; otherwise the API returns an extractive draft from retrieved context. - Speech-to-text is isolated behind a provider boundary. Public mode uses a deterministic local fixture; OpenAI Whisper and Deepgram request contracts are visible through
/transcription/runtimeandPOST /webhooks/n8n/call-audio. - Postgres/pgvector owns durable retrieval data; n8n owns workflow routing and external connectors.
- Approval transitions are explicit and narrow:
pending -> approvedorpending -> rejected. - The webhook contract is structured so Bitrix, telephony, Google Drive, or Telegram can be connected without rewriting RAG logic.
- Google Drive and Bitrix24 are dry-run by default, so public checks prove payload shape without exposing secrets.
- The synthetic public demo keeps Telegram dry-run; operator-triggered approvals can use the real Telegram bot and are captured as sanitized evidence.
- Bitrix24 evidence includes a read-only live sandbox check for
profileandcrm.lead.fields, plus a committed contract artifact for thecrm.lead.updaterequest body. - Real Bitrix24 dispatches are recorded as integration attempts; retryable failures set
next_retry_at, and repeated failures move the event todead_letterwithlast_error. - The Bitrix24 worker is opt-in and starts only when dry-run is disabled, so public demos cannot accidentally consume synthetic events.
/runtimeand/metricsexpose deploy evidence without requiring log access.
