qhronos

command module
v0.0.0-...-ce3407c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2025 License: MIT Imports: 27 Imported by: 0

README

Qhronos: Reliable Scheduling & Webhook Delivery

Version CI

Table of Contents

API Documentation

See docs/api.md for full API details and example requests/responses.

Overview

Qhronos (v0.1.0) is a developer-first scheduling and notification platform. It lets you schedule one-time or recurring events and reliably delivers webhooks at the right time. Built for reliability, security, and extensibility, Qhronos is ideal for automating workflows, orchestrating AI agents, and managing time-based triggers in distributed systems.

Event → Schedule → Occurrence Flow:

  • Event: User-defined intent and configuration, stored in the database.
  • Schedule: Actionable plan (stored in Redis) for when the event should be executed. Created by the expander.
  • Occurrence: A record representing a specific scheduled instance of an Event. For recurring events, these are generated by the Expander. Each Occurrence tracks its lifecycle (e.g., pending, scheduled, dispatched, failed) and the outcome of its execution attempt by the Dispatcher.

For system architecture and in-depth design, see design.md.

Features

  • REST API for event scheduling
  • Recurring and one-time events (iCalendar RFC 5545)
  • Reliable, retryable webhook delivery
  • JWT and master token authentication
  • Rate limiting and audit logging
  • Easy deployment (Docker/Kubernetes)

Quick Start

Prerequisites
  • Go 1.20+
  • Docker & Docker Compose
  • PostgreSQL & Redis (or use Docker Compose)
First-Time Setup

For your first run, copy the example config, build the Docker image, and start only the database dependencies and run migrations:

cp config.example.yml config.yml
make docker-build
make docker-up
make migrate-up

Then, to start all services (including the app):

make docker-qup

The API will be available at http://localhost:8080.

Build and Run from Binary
make build
./bin/qhronosd --config config.yaml

You can use CLI flags to override config values, e.g.:

./bin/qhronosd --port 9090 --log-level debug
Configuration Setup

Before running Qhronos, set up your configuration:

  1. Copy the example config file:
    cp config.example.yaml config.yaml
    
  2. Edit config.yaml to match your environment (database, Redis, auth secrets, etc).
  3. You can also override any config value using CLI flags (see above).
Database Setup & Migration

Before running Qhronos for the first time, initialize the PostgreSQL database and apply migrations:

  1. Start PostgreSQL and Redis using Make:
    make docker-up
    
  2. Run database migrations:
    make migrate-up
    
  3. Start all services (including Qhronos):
    make docker-qup
    

This will create all required tables and schema in your database.

Database Migration

Qhronos manages database schema changes using embedded migration files. You can apply all migrations using:

./bin/qhronosd --migrate --config config.yaml
  • This will apply all pending migrations to your database.
  • You can use any CLI flags to override config values (e.g., DB host, port, user).
Notes
  • Migration files are embedded in the binary; no external migration tool is needed.
  • The binary manages a schema_migrations table to track applied migrations.
  • Migration files should be named with incremental prefixes (e.g., 001_initial_schema.sql, 002_add_table.sql, etc.).

API Usage

See API documentation for full details.

Event Creation Example

You can now specify an action for event delivery. The action field supports both webhook and websocket types.

Webhook Example
{
  "name": "My Event",
  "description": "A test event",
  "start_time": "2025-01-01T00:00:00Z",
  "action": {
    "type": "webhook",
    "params": { "url": "https://example.com/webhook" }
  },
  "tags": ["api"]
}
Websocket Example
{
  "name": "Websocket Event",
  "description": "A test event for websocket client",
  "start_time": "2025-01-01T00:00:00Z",
  "action": {
    "type": "websocket",
    "params": { "client_name": "client1" }
  },
  "tags": ["api"]
}
API Call Example
{
  "name": "API Call Event",
  "description": "A test event for apicall action",
  "start_time": "2025-01-01T00:00:00Z",
  "action": {
    "type": "apicall",
    "params": {
      "method": "POST",
      "url": "https://api.example.com/endpoint",
      "headers": { "Authorization": "Bearer token", "Content-Type": "application/json" },
      "body": "{ \"foo\": \"bar\" }"
    }
  },
  "tags": ["api"]
}
Backward Compatibility

The legacy webhook field is still supported for backward compatibility. If you provide webhook, it will be automatically mapped to the appropriate action.

Action System

Qhronos uses an extensible action system for event delivery. Each event can specify an action object with a type and params. Supported types:

  • webhook: Delivers the event to an HTTP endpoint.
  • websocket: Delivers the event to a connected websocket client.
  • apicall: Makes a generic HTTP request with custom method, headers, body, and url.

The system is designed to be extensible for future action types.

Schedule Parameter Tutorial

The schedule parameter in event creation allows you to define recurring or one-time schedules using a flexible JSON structure. Here are the most common use cases:

1. One-Time Event (No Recurrence)

If you omit the schedule field, the event will be scheduled only once at the specified start_time:

{
  "name": "One-Time Event",
  "description": "This event happens only once.",
  "start_time": "2024-05-01T10:00:00Z",
  "webhook": "https://example.com/webhook",
  "metadata": {},
  "tags": ["single"]
  // No "schedule" field!
}
2. Daily Recurring Event
"schedule": {
  "frequency": "daily"
}

This schedules the event to occur every day. (If interval is omitted, it defaults to 1.)

3. Weekly Recurring Event (e.g., every Monday and Friday)
"schedule": {
  "frequency": "weekly",
  "by_day": ["MO", "FR"]
}

This schedules the event to occur every Monday and Friday.

Tip: Omitting the schedule field results in a one-time event. For recurring events, specify the schedule field as shown above.

Configuration

  • Copy config.example.yaml to config.yaml and edit as needed.
  • Or set CLI flags to override config values.
Scheduler Lookahead Settings

The scheduler section in your config controls how far into the future recurring events are expanded and how often the expander runs:

scheduler:
  look_ahead_duration: 24h   # How far into the future to expand recurring events
  expansion_interval: 5m     # How often to run the expander
  • look_ahead_duration: Controls the window (e.g., 24h) for which recurring event occurrences are pre-generated.
  • expansion_interval: How frequently the expander checks and generates new occurrences.

Adjust these values in your config.yaml to tune scheduling behavior for your workload.

WebSocket Real-Time Event Delivery

Qhronos supports real-time event delivery via a WebSocket endpoint at /ws.

Connection Types
  • Client-Hook Listener: Receives events where the event webhook is q:<client-name>.
  • Tag-Based Listener: Receives events that match any of the specified tags.
Usage
  1. Connect to the WebSocket endpoint:
    ws://<host>/ws
    
  2. Send an initial handshake message:
    • For client-hook:
      { "type": "client-hook", "client_name": "acme-corp", "token": "<JWT>" }
      
    • For tag-listener:
      { "type": "tag-listener", "tags": ["billing", "urgent"], "token": "<JWT>" }
      
  3. On success, the server will send event messages as they occur:
    { "type": "event", "event_id": "evt_123", "occurrence_id": "occ_456", "payload": { ... }, "tags": ["foo", "bar"] }
    
  4. (Client-hook only) To acknowledge receipt:
    { "type": "ack", "event_id": "evt_123", "occurrence_id": "occ_456" }
    
    • Tag-listener connections will receive an error if they send an ack message.
Security
  • All connections require authentication via JWT or master token.
  • Only authorized clients receive events for their hooks or allowed tags.

See the design document for more details on message flows and security.

Deployment

  • Supports Docker, Docker Compose, and Kubernetes.
  • See deployment guide for production tips.

Docker Usage

You can build and run Qhronos using Docker:

Build the Docker image
make docker-build
# or
# docker build -t qhronosd:latest .
make docker-qup
Stop all services
make docker-qdown
Override configuration
  • Custom config file:
    docker run -v /path/to/your/config.yaml:/app/config.yaml -p 8080:8080 qhronosd:latest
    
  • CLI flags (recommended):
    docker run qhronosd:latest --port 9090 --log-level debug
    

You can combine these methods as needed.

Authentication

  • Use a master token or generate JWTs via the /tokens endpoint.
  • See docs/auth.md for details.
JWT Tokens

Qhronos supports JWT (JSON Web Token) authentication for secure, scoped API access.

  • Obtaining a JWT Token: Use your master token to request a JWT via the /tokens endpoint:
    curl -X POST http://localhost:8080/tokens \
      -H "Authorization: Bearer <master_token>" \
      -H "Content-Type: application/json" \
      -d '{
        "sub": "your-user-id",
        "access": "admin",
        "scope": ["user:your-username"],
        "expires_at": "2024-12-31T23:59:59Z"
      }'
    
Occurrences

An Occurrence represents a single execution attempt of an event, created only after a scheduled event (from Redis) is executed by the dispatcher. For recurring events, multiple occurrences are generated as each scheduled execution is processed. Each occurrence tracks its status, attempts, and delivery history.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
api

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL