Files
Tomas Kracmar 0a4fb7b55e
Some checks failed
CI / lint-docs (push) Has been cancelled
CI / build-firmware (push) Has been cancelled
CI / test-backend (push) Has been cancelled
CI / test-web (push) Has been cancelled
feat: initial KosmoConnect platform v0.1
Includes:
- Backend services: ingestion (:8001), weather API (:8002),
  gateway (:8003), billing (:8004) with BTCPay integration
- Shared asyncpg pool, TimescaleDB hypertable, Redis, Mosquitto MQTT
- React frontend: Dashboard (MapLibre) and Messaging (chat UI)
- Bridge daemon for Pi + Meshtastic (Serial/TCP T-Deck support)
- Production Docker Compose, Nginx reverse proxy, ops scripts
- DEPLOY.md with step-by-step deployment guide
2026-04-12 17:30:15 +02:00
..

KosmoConnect Gateway Service

The Gateway Service handles all web-to-mesh and mesh-to-web messaging. It is the monetization boundary of the network.

What It Does

  • Subscription Enforcement: Validates that the user has an active subscription and that their plan allows messaging the target node
  • Quota Management: Tracks monthly message usage and rejects requests when limits are exceeded
  • Outbound Queue: Accepts web messages, stores them in PostgreSQL, and publishes them to MQTT for bridge delivery
  • Inbound Consumer: Listens to kosmo/mesh/inbound and stores replies, automatically threading them into conversations
  • Delivery Tracking: Message status progresses pending -> queued -> transmitted -> delivered (future: bridge ACKs will update to transmitted)

Endpoints

Method Path Description
POST /api/v1/messages Send a message to a mesh node
GET /api/v1/messages/conversations List all conversations for the user
GET /api/v1/messages/conversations/{node_id} Get full message history with a node
GET /api/v1/messages/{message_id} Check delivery status of a message

Authentication (v0.1)

For rapid development, the gateway currently uses a simple X-User-ID header to identify the caller. In production this will be replaced with JWT/OAuth2.

Billing

Subscription management is handled by the Billing Service, which integrates with the Church of Kosmo's BTCPay Server at pay.cqre.net. The Gateway does not process payments itself; it only reads subscription state from the shared PostgreSQL database.

Subscription Scopes

Plan Scope Quota (example)
wanderer Any node on the mesh 50/month
guardian Only whitelisted nodes 500/month
sanctuary Any node + API/webhooks Unlimited
free Receive only 0 outbound

Running Locally

Make sure the backend infrastructure (Postgres, MQTT) is running:

cd backend
docker-compose up -d

Seed test users (only needed once):

docker-compose exec -T timescaledb psql -U kosmo -d kosmoconnect < migrations/002_seed_test_users.sql

Start the gateway:

./run-dev.sh gateway

Testing with cURL

# Send a message (test wanderer user)
curl -X POST http://localhost:8003/api/v1/messages \
  -H "Content-Type: application/json" \
  -H "X-User-ID: 11111111-1111-1111-1111-111111111111" \
  -d '{"target_node_id": "!a1b2c3d4", "text": "Hello mesh"}'

# List conversations
curl http://localhost:8003/api/v1/messages/conversations \
  -H "X-User-ID: 11111111-1111-1111-1111-111111111111"

# Check message status
curl http://localhost:8003/api/v1/messages/{message_id} \
  -H "X-User-ID: 11111111-1111-1111-1111-111111111111"

Architecture

Web Client
    |
    | POST /api/v1/messages  (X-User-ID)
    v
Gateway Service (:8003)
    |- Checks subscription + quota in PostgreSQL
    |- Writes message to mesh_messages (status=pending)
    |- Background worker publishes pending rows to MQTT
    |
    v
MQTT Broker  (kosmo/mesh/outbound/{node_id})
    |
    v
Bridge Daemon (Pi)  ->  Meshtastic Mesh  ->  Target Node

Reply path:
Target Node  ->  Mesh  ->  Bridge Daemon  ->  MQTT (kosmo/mesh/inbound)
    |
    v
Gateway Service consumes MQTT and writes reply to mesh_messages
    |
    v
Web Client reads via GET /api/v1/messages/conversations