Go library providing event contract types for the ComplyTime ecosystem.
Events use CloudEvents v1.0 envelopes with
JSON-encoded payloads. Go types in events/events.go are the source of
truth for event contracts; the AsyncAPI 3.0 spec
and JSON Schema files are generated from those types
via go generate. Do not edit the generated files manually.
go get github.com/complytime/complyapipackage main
import (
"fmt"
"log"
"github.com/complytime/complyapi/events"
)
func main() {
data := events.EvidenceIngestedData{
ContentDigest: "sha256:abc123...",
ArtifactType: "application/vnd.gemara.evaluation-log+json",
SubjectID: "my-app-v1",
}
e, err := events.NewEvidenceIngestedEvent("my-service", "my-app-v1", data)
if err != nil {
log.Fatal(err)
}
fmt.Println(e.Type()) // dev.complytime.evidence.ingested
}| Type | Constant | Description |
|---|---|---|
dev.complytime.evidence.ingested |
events.TypeEvidenceIngested |
Evidence accepted for processing |
Example CloudEvents JSON payloads are in
api/events/examples/:
| File | Description |
|---|---|
evidence-ingested.json |
Common payload with required fields and storageRef |
evidence-ingested-minimal.json |
Required data fields only (no optional fields) |
evidence-ingested-with-shard.json |
All fields including optional shardId |
These examples conform to the JSON Schema and AsyncAPI spec. They are hand-maintained reference payloads; the generated schemas remain the source of truth for validation.
- Go (version per
go.mod) - Task (task runner)
- golangci-lint
- Node.js with
npx(required bytask asyncapi-lint; first run downloads the AsyncAPI CLI from npm)
After modifying Go structs in events/events.go, regenerate derived artifacts:
task generateThis runs go generate ./events/... which rebuilds api/events/asyncapi.yaml
and the JSON Schema files in api/events/schemas/.
To validate the generated AsyncAPI spec:
task asyncapi-lintTo run all checks (lint, vet, test, asyncapi validation):
task check-
Define a new
*Datastruct inevents/events.gowith a sentinel blank field carrying theasyncapitag. The tag is a comma-separated list ofkey:valuepairs. Values must not contain commas (the parser splits on commas, and a comma inside a value silently truncates it). Use semicolons for natural pauses. Recognised keys:Key Required Format Description channelyes NATS subject with {param}placeholdersChannel address paramno name=description(repeatable)Channel parameter streamyes Upper-case stream name NATS JetStream stream typeyes Reverse-DNS CloudEvents type CloudEvents typeattributesendyes Free text (no commas) Send operation summary receiveyes Free text (no commas) Receive operation summary descriptionno Free text (no commas) Channel description Example sentinel field:
_ struct{} `asyncapi:"channel:core.widget.created.{ownerId},param:ownerId=The widget owner,stream:WIDGETS,type:dev.complytime.widget.created,send:Published when a widget is created,receive:Consume widget-created events,description:Widget creation pipeline"`
-
Add
asyncapi-field:"description:..."tags on each struct field for schema descriptions. -
Run
task generateto regenerate all derived artifacts. -
Add a constructor function (e.g.,
NewYourEventEvent()) following the existing pattern.
Before changing an existing event's payload, read the
Event Versioning Strategy. It defines which field to bump
for additive versus breaking changes (CloudEvents type and AsyncAPI
info.version), and why the NATS subject stays stable so subscribers never
re-subscribe.