diff --git a/README.md b/README.md index 67e5d86..9cd9d70 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,8 @@ Shared versioned HTTP and authenticated WebSocket contracts for `trixie-server` This repository contains schemas, shared enums, error codes, compatibility fixtures, contract tests, and API documentation only. -The first contract slice is under `contracts/v1/` and `fixtures/v1/`. It covers server readiness and health so the client and server can be developed and tested together before Twitch integration. +The first contract slice is under `contracts/v1/` and `fixtures/v1/`. It covers +server readiness, health, errors, and the transport-neutral realtime event +envelope so the client and server can be developed and tested together before +Twitch integration. diff --git a/contracts/v1/error.json b/contracts/v1/error.json new file mode 100644 index 0000000..9cba1d5 --- /dev/null +++ b/contracts/v1/error.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://trixie.invalid/contracts/v1/error.json", + "title": "Trixie API Error", + "type": "object", + "additionalProperties": false, + "required": ["code", "message", "request_id"], + "properties": { + "code": { "type": "string", "pattern": "^[a-z0-9_]+$" }, + "message": { "type": "string", "minLength": 1 }, + "request_id": { "type": "string", "minLength": 1 } + } +} diff --git a/contracts/v1/realtime-event.json b/contracts/v1/realtime-event.json new file mode 100644 index 0000000..087b235 --- /dev/null +++ b/contracts/v1/realtime-event.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://trixie.invalid/contracts/v1/realtime-event.json", + "title": "Trixie Realtime Event", + "type": "object", + "additionalProperties": false, + "required": ["event_id", "event_type", "occurred_at", "payload"], + "properties": { + "event_id": { "type": "string", "minLength": 1 }, + "event_type": { "type": "string", "pattern": "^[a-z0-9_.-]+$" }, + "occurred_at": { "type": "string", "format": "date-time" }, + "payload": { "type": "object" } + } +} diff --git a/docs/contract-testing.md b/docs/contract-testing.md index a1653da..bb87af3 100644 --- a/docs/contract-testing.md +++ b/docs/contract-testing.md @@ -1,4 +1,12 @@ # Contract Testing -Fixtures cover HTTP responses, authenticated WebSocket events, errors, permissions, version negotiation, reconnects, and server-owned state transitions. Fixtures are deterministic, synthetic, and secret-free. +Fixtures cover HTTP responses, authenticated WebSocket events, errors, permissions, +version negotiation, reconnects, and server-owned state transitions. Fixtures are +deterministic, synthetic, and secret-free. Every new contract must include at +least one valid fixture and a negative case where validation rules are important. + +The current realtime envelope is deliberately transport-neutral: the server may +deliver it over an authenticated WebSocket or a future compatible transport, but +the event identity and payload rules remain the same. `event_id` is the stable +deduplication key for at-least-once delivery. diff --git a/fixtures/v1/error.unauthorized.json b/fixtures/v1/error.unauthorized.json new file mode 100644 index 0000000..9d15817 --- /dev/null +++ b/fixtures/v1/error.unauthorized.json @@ -0,0 +1,5 @@ +{ + "code": "unauthorized", + "message": "Authentication is required.", + "request_id": "req_fixture_unauthorized" +} diff --git a/fixtures/v1/realtime.activity.json b/fixtures/v1/realtime.activity.json new file mode 100644 index 0000000..1664247 --- /dev/null +++ b/fixtures/v1/realtime.activity.json @@ -0,0 +1,9 @@ +{ + "event_id": "evt_fixture_activity_001", + "event_type": "activity.follow", + "occurred_at": "2026-01-01T00:00:00Z", + "payload": { + "username": "fixture_viewer", + "display_name": "Fixture Viewer" + } +}