SignalBridge is a cloud-native, human-in-the-loop youth support command centre for Singapore Children's Society youth workers.
It helps workers manage multiple digital conversations, safely bridge after-hours youth messages back to human care, generate youth-approved handoff briefs, prioritise consent-based support signals, and monitor worker load without replacing human youth workers.
SignalBridge is not positioned as a chatbot. The youth-facing chat is one part of a wider command centre that supports continuity of care.
Core demo line:
The youth does not have to repeat their pain twice, and the worker does not have to start from zero.
- Frontend: Next.js App Router and Tailwind CSS
- Backend: FastAPI
- Database: PostgreSQL
- ORM: SQLAlchemy
- Auth: JWT-based role-based access
- AI: OpenAI structured handoffs with deterministic safety fallback
- DevOps: Docker and Docker Compose
apps/
web/ # Next.js frontend
services/
api/ # FastAPI backend
ai-worker/ # AI and safety worker, if separated
docs/
api-contract.md
demo-script.md
infra/
docker-compose.yml
The complete web, API, and PostgreSQL stack runs from Docker Compose. Startup applies Alembic migrations and loads idempotent fictional seed data.
Expected local flow:
docker compose up --buildReset and reseed the fictional database:
docker compose run --rm api python seed.py --resetTo remove the local PostgreSQL volume completely, run docker compose down -v before starting again.
Local backend-only flow:
cd services/api
python -m venv .venv
.venv/Scripts/activate
pip install -r requirements.txt
alembic -c ../../alembic.ini upgrade head
python seed.py
uvicorn app.main:app --reloadPrimary backend endpoints:
GET /health
GET /version
POST /auth/login
GET /youth/conversations
POST /youth/conversations/{id}/messages
POST /youth/conversations/{id}/handoff-consent
POST /ai/handoff/{conversation_id}
GET /worker/cockpit
GET /worker/cases/{id}
PATCH /worker/cases/{id}/status
POST /worker/cases/{id}/notes
GET /worker/handoffs/{id}
GET /worker/youths/{id}
GET /signals/radar
GET /supervisor/load
GET /supervisor/workers
PATCH /supervisor/cases/{id}/assign
GET /audit/logs
GET /analytics/summary
POST /simulator/intake
GET /constants
The alpha is built around one coherent journey: Mira, a youth experiencing cyberbullying, messages SignalBridge after-hours.
Mira's seed message:
People in my class group chat keep editing my photos. I don't want to go school tomorrow. I'm so tired of explaining this.
The system should detect cyberbullying, school avoidance, shame or embarrassment, after-hours timing, and unresolved handoff risk.
| Role | Purpose | |
|---|---|---|
| mira@signalbridge.test | youth | Youth demo account for the Mira after-hours cyberbullying journey |
| worker1@signalbridge.test | worker | Youth worker who reviews Mira's handoff brief |
| worker2@signalbridge.test | worker | Second worker for workload reassignment |
| supervisor@signalbridge.test | supervisor | Supervisor who reviews worker load and audit activity |
All fictional accounts use password password.
Deterministic rules establish risk before any model call. A model can improve handoff wording but cannot lower risk or replace critical escalation guidance. Missing credentials, timeout, refusal, malformed structured output, or prohibited clinical wording automatically uses the deterministic fallback. Configure SIGNALBRIDGE_OPENAI_API_KEY and optionally SIGNALBRIDGE_OPENAI_MODEL.
Youth can also reach SafeNight through Telegram or Discord, and workers can reply back into the same conversation from the cockpit. Both bots are off unless their tokens are configured.
Telegram
-
Set
SIGNALBRIDGE_TELEGRAM_BOT_TOKEN(from @BotFather) andSIGNALBRIDGE_PUBLIC_BASE_URL(the public HTTPS URL of the API). -
The API auto-registers the webhook on startup. To register/inspect manually:
cd services/api python scripts/set_telegram_webhook.py # register python scripts/set_telegram_webhook.py --info # show status
-
Optionally set
SIGNALBRIDGE_TELEGRAM_WEBHOOK_SECRETto reject spoofed webhook calls.
Discord
- Set
SIGNALBRIDGE_DISCORD_BOT_TOKEN. - In the Discord Developer Portal, enable Message Content Intent (Bot → Privileged Gateway Intents). Without it the bot cannot read DMs.
- The bot runs inside the API process and replies to direct messages.
Without these, the channels stay disabled and the rest of the app is unaffected.
npm run lint
npm run build
$env:PYTHONPATH='services/api'; .\.venv\Scripts\python -m pytest services/api/tests -q
docker compose config
docker compose up --build
curl http://localhost:8000/health
curl http://localhost:8000/versionrender.yaml provisions the web service, API, and managed PostgreSQL in Singapore. Apply the Blueprint after merging to dev, set SIGNALBRIDGE_OPENAI_API_KEY if model-assisted summaries are required, and verify /login plus the API /health endpoint. infra/k8s/signalbridge.yaml provides portable deployment, service, secret, and health-probe definitions for a Kubernetes target.
Dell platform deployment requires external project credentials that are not present in this repository. See docs/deployment-fallback-plan.md for the Dell access check, deployment method, and fallback demo order.
| Owner | Area | Branch |
|---|---|---|
| Shelton | Product direction, integration, README, API contract, demo story, merge control | dev / main |
| Mru | Youth experience and SafeNight Companion | feature/youth-chat |
| Mike | Worker Cockpit, case management, Signal Radar UI | feature/worker-cockpit |
| Davier | Backend, AI, safety, database, Docker, DevOps | feature/ai-backend / feature/devops |
- Mira logs in and opens SafeNight Companion.
- Mira sends the after-hours cyberbullying message.
- SafeNight responds safely and asks for handoff consent.
- Mira consents to a handoff note.
- SignalBridge generates a structured handoff brief.
- The youth worker logs in the next morning.
- Mira appears at the top of Signal Radar.
- The worker opens the handoff brief and sees context, risk, key quote, what AI did, what not to repeat, and suggested first response.
- The worker marks the case as Needs Follow-Up and adds a note.
- The supervisor reviews worker load and safety audit logs.
main: stable onlydev: integration branchfeature/youth-chat: Mru youth flowfeature/worker-cockpit: Mike worker and case workflowfeature/ai-backend: Davier API, AI, risk, seed datafeature/devops: Davier Docker, environment, deployment
Merge feature branches into dev first. Test dev before promoting to main.
Day-by-day work is tracked in the GitHub Project board: