generated from coulomb/repo-seed
docs: align v2 bootstrap api contract
This commit is contained in:
@@ -3,7 +3,9 @@
|
||||
**Audience:** A developer starting a new domain hub (dev-hub, ops-hub, fin-hub, etc.)
|
||||
that will live in its own repository and use inter-hub as the governance substrate.
|
||||
|
||||
**Current state:** inter-hub v0.2.0-alpha.1 is running at `http://192.168.178.135:8080`.
|
||||
**Current state:** inter-hub v0.2.0-alpha.1 exposes its supported integration
|
||||
surface under `/api/v2`. The examples below use `$IHUB_BASE`; point it at the
|
||||
environment you are bootstrapping against.
|
||||
|
||||
---
|
||||
|
||||
@@ -30,76 +32,142 @@ or type-safe access to inter-hub's data model.
|
||||
|
||||
## Pattern A — API Consumer Hub
|
||||
|
||||
### 1. Create an API consumer in inter-hub
|
||||
### 1. Start with an operator API key
|
||||
|
||||
Go to `http://192.168.178.135:8080/ApiConsumers` → New.
|
||||
|
||||
Fill in:
|
||||
- **Name:** `dev-hub` (or your hub name)
|
||||
- **Contact:** your team email
|
||||
- **Description:** what this hub does
|
||||
|
||||
After creating the consumer, go to **API Keys → New** and generate a key
|
||||
for this consumer. Copy the key — it is shown only once.
|
||||
|
||||
### 2. Register your hub
|
||||
Every write call below requires `Authorization: Bearer <key>`. Use an existing
|
||||
operator/admin API key for the first bootstrap call. New hub-specific keys can
|
||||
then be created through the API and should replace the operator key for normal
|
||||
runtime traffic.
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.135:8080/api/v2/hubs \
|
||||
-H "Authorization: Bearer <your-api-key>" \
|
||||
export IHUB_BASE="http://127.0.0.1:8000"
|
||||
export IHUB_OPERATOR_KEY="<existing-operator-api-key>"
|
||||
```
|
||||
|
||||
### 2. Register the VSM Operations hub
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$IHUB_BASE/api/v2/hubs" \
|
||||
-H "Authorization: Bearer $IHUB_OPERATOR_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "Dev Hub",
|
||||
"slug": "dev-hub",
|
||||
"domain": "dev.example.com",
|
||||
"hubKind": "domain"
|
||||
"name": "Operations Hub",
|
||||
"slug": "ops-hub",
|
||||
"domain": "operations",
|
||||
"hubKind": "domain",
|
||||
"hubFamily": "vsm",
|
||||
"vsmFunction": "operations",
|
||||
"vsmSystem": "1"
|
||||
}'
|
||||
```
|
||||
|
||||
Save the returned `id` — this is your `hubId` for all subsequent calls.
|
||||
|
||||
### 3. Register your type vocabulary
|
||||
|
||||
Before creating widgets with domain-specific types, register them via the
|
||||
inter-hub UI at `/HubCapabilityManifests` → New → select your hub.
|
||||
|
||||
In the manifest editor, declare your types:
|
||||
```json
|
||||
["dev-pipeline-run", "dev-pr-review", "dev-build-status"]
|
||||
```
|
||||
|
||||
Click **Activate**. See `docs/domain-hub-extension-guide.md` for the full
|
||||
naming rules and conflict-resolution workflow.
|
||||
|
||||
### 4. Register widgets
|
||||
### 3. Register and activate the ops-hub manifest
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.135:8080/api/v2/widgets \
|
||||
-H "Authorization: Bearer <your-api-key>" \
|
||||
curl -s -X POST "$IHUB_BASE/api/v2/hub-capability-manifests" \
|
||||
-H "Authorization: Bearer $IHUB_OPERATOR_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "Pipeline Status Panel",
|
||||
"widgetType": "dev-pipeline-run",
|
||||
"hubId": "<your-hub-id>",
|
||||
"viewContext": "pipeline-dashboard"
|
||||
"hubId": "<ops-hub-id>",
|
||||
"manifestVersion": "1.0",
|
||||
"declaredWidgetTypes": ["ops-endpoint-card"],
|
||||
"declaredEventTypes": ["ops-endpoint-verified"],
|
||||
"declaredAnnotationCategories": ["ops-risk"],
|
||||
"declaredPolicyScopes": ["ops-internal"],
|
||||
"capabilityDescription": "Operations inventory and endpoint verification",
|
||||
"contact": "ops@example.com"
|
||||
}'
|
||||
```
|
||||
|
||||
### 5. Record interaction events
|
||||
Then activate the returned manifest:
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.178.135:8080/api/v2/interaction-events \
|
||||
-H "Authorization: Bearer <your-api-key>" \
|
||||
curl -s -X POST "$IHUB_BASE/api/v2/hub-capability-manifests/<manifest-id>/activate" \
|
||||
-H "Authorization: Bearer $IHUB_OPERATOR_KEY"
|
||||
```
|
||||
|
||||
Activation registers the declared vocabulary. Domain-owned widget types,
|
||||
event types, annotation categories, and policy scopes must be declared here
|
||||
before use.
|
||||
|
||||
### 4. Create an ops-hub API consumer and key
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$IHUB_BASE/api/v2/api-consumers" \
|
||||
-H "Authorization: Bearer $IHUB_OPERATOR_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "ops-hub",
|
||||
"description": "Operations hub runtime client",
|
||||
"hubCapabilityManifestId": "<active-manifest-id>",
|
||||
"rateLimitPerMinute": 120,
|
||||
"quotaPerDay": 50000
|
||||
}'
|
||||
```
|
||||
|
||||
Create the static key for the returned consumer:
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$IHUB_BASE/api/v2/api-consumers/<api-consumer-id>/api-keys" \
|
||||
-H "Authorization: Bearer $IHUB_OPERATOR_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"scopes": "ops:write"}'
|
||||
```
|
||||
|
||||
The response contains `fullKey` exactly once. Store it in the hub runtime
|
||||
secret store and use it for all following calls:
|
||||
|
||||
```bash
|
||||
export OPS_HUB_KEY="<fullKey-from-create-api-key-response>"
|
||||
```
|
||||
|
||||
### 5. Register widgets
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$IHUB_BASE/api/v2/widgets" \
|
||||
-H "Authorization: Bearer $OPS_HUB_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "CoulombCore Gitea Registry",
|
||||
"widgetType": "ops-endpoint-card",
|
||||
"hubId": "<ops-hub-id>",
|
||||
"viewContext": "operations-inventory",
|
||||
"policyScope": "ops-internal"
|
||||
}'
|
||||
```
|
||||
|
||||
### 6. Record interaction events
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$IHUB_BASE/api/v2/interaction-events" \
|
||||
-H "Authorization: Bearer $OPS_HUB_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"widgetId": "<widget-id>",
|
||||
"eventType": "clicked",
|
||||
"userId": "<optional-user-id>",
|
||||
"payload": {"button": "retry", "pipeline": "main-ci"}
|
||||
"eventType": "ops-endpoint-verified",
|
||||
"viewContext": "registry-readiness",
|
||||
"metadata": {
|
||||
"service": "gitea",
|
||||
"endpoint": "https://gitea.coulomb.social/v2/",
|
||||
"result": "auth-challenge-ok"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### 6. What you get for free
|
||||
### 7. Verify the bootstrap
|
||||
|
||||
```bash
|
||||
curl -s "$IHUB_BASE/api/v2/interaction-events?widgetId=<widget-id>&eventType=ops-endpoint-verified" \
|
||||
-H "Authorization: Bearer $OPS_HUB_KEY"
|
||||
```
|
||||
|
||||
The event should appear with the submitted `metadata`. If the API returns
|
||||
`event_type_not_in_manifest`, check that the API consumer is bound to the
|
||||
active ops-hub manifest and that the event type was declared before activation.
|
||||
|
||||
### 8. What you get for free
|
||||
|
||||
Once events are flowing, the inter-hub framework automatically provides:
|
||||
- Annotation collection on any widget
|
||||
@@ -109,8 +177,8 @@ Once events are flowing, the inter-hub framework automatically provides:
|
||||
- Outcome signals and regression detection
|
||||
- Widget marketplace discovery
|
||||
|
||||
Your hub only needs to POST events. Everything downstream is managed by
|
||||
inter-hub.
|
||||
Your hub only needs to register its vocabulary, seed meaningful widgets, and
|
||||
POST events. Everything downstream is managed by inter-hub.
|
||||
|
||||
---
|
||||
|
||||
@@ -153,16 +221,16 @@ import IHP.Prelude
|
||||
import Network.HTTP.Simple
|
||||
|
||||
postEvent :: Text -> Text -> Text -> Value -> IO ()
|
||||
postEvent apiKey widgetId eventType payload = do
|
||||
postEvent apiKey widgetId eventType metadata = do
|
||||
let req = setRequestMethod "POST"
|
||||
$ setRequestHeader "Authorization" ["Bearer " <> cs apiKey]
|
||||
$ setRequestHeader "Content-Type" ["application/json"]
|
||||
$ setRequestBodyJSON (object
|
||||
[ "widgetId" .= widgetId
|
||||
, "eventType" .= eventType
|
||||
, "payload" .= payload
|
||||
, "metadata" .= metadata
|
||||
])
|
||||
$ parseRequest_ "http://192.168.178.135:8080/api/v2/interaction-events"
|
||||
$ parseRequest_ "http://127.0.0.1:8000/api/v2/interaction-events"
|
||||
void $ httpLBS req
|
||||
```
|
||||
|
||||
@@ -239,6 +307,7 @@ every domain hub:
|
||||
- `WidgetEnvelope` helpers — consistent widget wrapping across hubs
|
||||
- `InterHubClient` — typed API client with retry and auth built in
|
||||
- `HubCapabilityManifest` bootstrap — auto-activate manifest on startup
|
||||
(planned; use the API recipe above today)
|
||||
- Shared `defaultLayout` with inter-hub navigation integration
|
||||
|
||||
Until `hub-core` exists, copy the client helper above and the 3-step
|
||||
@@ -248,10 +317,11 @@ registration pattern into your new hub. It is ~50 lines of boilerplate.
|
||||
|
||||
## Checklist for a New Hub
|
||||
|
||||
- [ ] Create ApiConsumer + ApiKey in inter-hub UI
|
||||
- [ ] Start with an existing operator API key
|
||||
- [ ] Create ApiConsumer + ApiKey through `/api/v2/api-consumers`
|
||||
- [ ] Record your hub ID and API key in the new hub's `.env`
|
||||
- [ ] Register HubCapabilityManifest with domain type vocabulary
|
||||
- [ ] Activate the manifest (validates no naming conflicts)
|
||||
- [ ] Register HubCapabilityManifest with domain type vocabulary through `/api/v2/hub-capability-manifests`
|
||||
- [ ] Activate the manifest through `/api/v2/hub-capability-manifests/<id>/activate`
|
||||
- [ ] Create at least one Widget per meaningful UI surface
|
||||
- [ ] Instrument interactions with POST to `/api/v2/interaction-events`
|
||||
- [ ] Verify events appear in inter-hub at `/InteractionEvents`
|
||||
@@ -266,8 +336,9 @@ registration pattern into your new hub. It is ~50 lines of boilerplate.
|
||||
|
||||
| Resource | Location |
|
||||
|----------|----------|
|
||||
| API reference (OpenAPI) | `http://192.168.178.135:8080/api/v2/openapi.json` |
|
||||
| Type registry browser | `http://192.168.178.135:8080/TypeRegistries/WidgetTypes` |
|
||||
| API reference (OpenAPI) | `$IHUB_BASE/api/v2/openapi.json` |
|
||||
| Swagger UI | `$IHUB_BASE/api/v2/docs` |
|
||||
| Type registry browser | `$IHUB_BASE/TypeRegistries/WidgetTypes` |
|
||||
| Domain hub extension guide | `docs/domain-hub-extension-guide.md` |
|
||||
| IHP data and queries | `docs/ihp-data-and-queries.md` |
|
||||
| IHP controllers and views | `docs/ihp-controllers-views-forms.md` |
|
||||
|
||||
Reference in New Issue
Block a user