Orion is a unified notification gateway: it accepts notify requests from business systems, orchestrates routing, and delivers messages to multiple external channels (Feishu/Lark, WeCom, WeChat, email, SMS, MQ, etc.).
This repo demonstrates an ai-coding & vibe-coding workflow — documentation-first, agent-friendly, fully auditable via agents_chat.
- Message Definitions: define message schema (JSON with ${var} templating).
- Endpoints: HTTP/MQ/channel endpoints with adapter_key and config (e.g., http.feishu_bot, channel.wechat_official_account).
- Dispatch Mapping: map a message to many endpoints (BID-first relations).
- Notify API: POST /api/v1/notify with message_name or message_definition_bid + data.
- Feishu E2E: endpoint edit page offers “send test” to a Feishu bot webhook.
- WeChat Official Account channel: unified templating + gateway, including retry/metrics.
- Auth profiles: CRUD ready; attach to endpoints (future auth providers wiring).
- Frontend console: manage systems, endpoints, messages, and mappings.
- Languages: Simplified Chinese (
zh-CN) and English (en-US). - UI texts: stored in
frontend/messages/{locale}.json; a lightweight provider exposest(key)across pages. - Language detection: a middleware sets the
LANGcookie (derived fromAccept-Languageon first visit). The navbar includes a language switcher that updatesLANGand reloads. - Backend negotiation: FastAPI middleware negotiates locale (
?lang→Cookie LANG→Accept-Language→ defaultzh-CN) and injectsContent-Languagein responses. - Help center: loads Markdown from
frontend/help/<locale>/with fallback tofrontend/help/when a localized document is missing. - Where to extend:
- Add
frontend/messages/<new-locale>.jsonand updateSUPPORTED_LOCALES. - Add
frontend/help/<new-locale>/*.mdfor localized docs. - Backend: add translations via Babel/
pybabelunderbackend/locale/<lang>/LC_MESSAGES.
- Add
- Roadmap: migrate to
next-intlwith[locale]/routes and SEOhreflang/alternates.
- Backend: Python 3.11, FastAPI, SQLAlchemy, Alembic, PyJWT/Passlib (optional), httpx
- Frontend: Next.js 14 (app dir) + Tailwind
- DB: SQLite (dev) / MySQL (supported); Redis/MQ optional later
backend/: FastAPI app, APIs, services, repositories, models, testsfrontend/: Next.js console (systems, endpoints, messages, dispatches)agents_chat/: AI collaboration logs (see below)
- Conda recommended:
conda activate py311 - Install: from repo root
pip install -e backend(orcd backend && pip install -e .) - Run server:
uvicorn backend.app.main:app --reload - DB (MySQL example): set in
.envORION_DATABASE_URL=mysql+pymysql://root:Pa88word@127.0.0.1:13306/orion?charset=utf8mb4- Migrate:
scripts/migrate.sh upgrade head
- CORS: configure
ORION_CORS_ORIGINS=*or JSON array; defaults allow localhost:3000/3001 - API Docs: Swagger
/docs, ReDoc/redoc
-
Auth: either header
X-API-Keyor HTTP Basic withapi:<key>- Set
ORION_PUBLIC_API_KEYin.envor compose env - Basic example:
Authorization: Basic+ base64(api:<key>)
- Set
-
Endpoint:
POST /api/v1/notify -
Body options:
- By name:
{ "message_name": "simple-text", "data": { "text": "hi" } } - By bid:
{ "message_definition_bid": "...", "data": { ... } }
- By name:
-
Response:
{ "results": [ { "dispatch_bid", "endpoint_bid", "status_code", "body" } ] } -
Generate a key (preview):
POST /api/v1/notify/keys/previewreturns a random key suggestion; set it toORION_PUBLIC_API_KEYon the backend.
- Create endpoint: transport=http, adapter_key=http.feishu_bot, endpoint_url=<feishu_webhook>
- Create message definition: schema
{ "msg_type": "text", "content": { "text": "${text}" } } - Add dispatch (message -> endpoint)
- Call
/api/v1/notifywith{ "message_name": "...", "data": { "text": "hello" } } - Or use endpoint edit page “Send test” UI
- Mailgun
- Create endpoint: transport=http, adapter_key=http.mailgun
- Config:
url=https://api.mailgun.net/v3/<domain>/messages,api_key=<key>, optionalfrom/to - Send test in endpoint page; subject auto="Orion Test", body uses input text
- SendGrid
- Create endpoint: transport=http, adapter_key=http.sendgrid
- Config:
url=https://api.sendgrid.com/v3/mail/send,api_key=<key>, optionalfrom/to - Send test constructs SendGrid JSON with from/to/subject/content
- SMTP
- Create endpoint: transport=smtp, adapter_key=smtp.generic
- Config:
host, optionalport,use_tls/use_ssl, optionalusername/password, defaultfrom/to - Send test sends a simple email with subject "Orion Test" and text from input; mapping also supports
subject,text,html,from,to
- Endpoint:
transport=channel, adapter_key=channel.wechat_official_account- Config:
app_id,app_secret,language(e.g.zh_CN)
- Message Definition:
- Store a template-style payload for WeChat:
{ "template_id": "TM00000001", "to_user": "${openid}", "data": { "first": { "value": "Booking result" }, "time": { "value": "${time}" } }, "link": { "type": "url", "url": "${link_url}" } }
- Store a template-style payload for WeChat:
- Dispatch & Notify:
- Bind the message to the WeChat endpoint.
- Call
/api/v1/notify/withdataprovidingopenid/time/link_url/...; Orion renders the template, merges endpoint config, and sends via thewechat_official_accountgateway.
cd frontend && npm i(or pnpm/yarn)- Run:
npm run devand open http://localhost:3000 - Note: the browser uses same-origin
/apicalls; for local dev without Docker/Nginx, set up a dev proxy from/api→http://127.0.0.1:8000(e.g., Next.js rewrites) or prefer Docker Compose below which already proxies via Nginx. - Navigate to Systems, Endpoints, Messages; create mappings in Messages or Endpoints pages
- Switch language using the selector in the navbar; the current language persists in
LANGcookie. - To localize a page, replace hardcoded strings with
t('...')and add keys tofrontend/messages/{locale}.json. - Help docs: place localized pages in
frontend/help/en-US/*(or another locale folder). Titles use# HeadingMarkdown.
- Prereqs: Docker Desktop with Compose.
- Start (first time build recommended):
- Build images:
docker compose build - Run in background:
docker compose up -d - Check status:
docker compose ps - Tail logs:
docker compose logs -f --tail=200 backend(orfrontend/mysql/nginx)
- Build images:
- Console (Nginx entry): http://localhost:8080
- API (proxied by Nginx): http://localhost:8080/api/
- Health:
/healthzor/api/v1/ping
mysql: MySQL 8 withorion/orionpass, DBorion, rootorionroot; data persists via volumemysql_data.backend: FastAPI service. Runsalembic upgrade headthen serves via Uvicorn.- Key envs:
ORION_DATABASE_URL=mysql+pymysql://orion:orionpass@mysql:3306/orion?charset=utf8mb4,ORION_PUBLIC_API_KEY, etc.
- Key envs:
frontend: Next.js console. Browser requests hit same-origin/api, which Nginx proxies to backend.nginx: reverse proxies/to frontend and/api/to backend.
- MySQL may take a moment on first start. If backend migrates too early, run
docker compose restart backend. - Compose warns about
versionfield deprecation: it’s safe to ignore; we’ll clean this later. - To override the frontend API base URL, edit
docker-compose.ymland setNEXT_PUBLIC_API_BASE_URLin bothfrontend.build.argsandfrontend.environment.
- Install:
pip install pre-commitand ensure Node.js is available (for commitlint). - Install hooks:
pre-commit installandpre-commit install --hook-type commit-msg. - Validate locally:
pre-commit run -a. - Commits should not use
--no-verify; CI enforces Conventional Commits and agents_chat coupling.
- Install:
pip install -e backend[test] - Run in
backend/:pytest
- All agent instruction files are symlinked to
AGENTS.md. - Collaboration logs under
agents_chat/(Y/M/D/timestamp-topic.md). Commits that modify code must include an agents_chat entry in the same commit (CI-enforced). Useskip agents-chatin commit body to bypass when necessary. - Architecture doc:
docs/architecture/overview.md.
MIT — see the LICENSE file for details.