package main import ( "context" "encoding/json" "time" "github.com/tinode/chat/server/store/types" ) type kafkaAuditPayload struct { ActorType string `json:"actor_type"` ActorID string `json:"actor_id"` Action string `json:"action"` Resource string `json:"resource"` ResourceID string `json:"resource_id"` Result string `json:"result"` Reason string `json:"reason,omitempty"` Data map[string]any `json:"data,omitempty"` OccurredAt time.Time `json:"occurred_at"` } var publishKafkaAuditEventEnvelope = publishKafkaEnvelope func enqueueKafkaAuditEvent(ctx context.Context, tenantID types.TenantID, actorType string, actor types.Uid, action, resource, resourceID, result, reason string, data map[string]any) error { if !kafkaEnabled() { return nil } actorID := "" if !actor.IsZero() { actorID = actor.UserId() } payload := kafkaAuditPayload{ ActorType: actorType, ActorID: actorID, Action: action, Resource: resource, ResourceID: resourceID, Result: result, Reason: reason, Data: data, OccurredAt: time.Now().UTC().Round(time.Millisecond), } encoded, err := json.Marshal(payload) if err != nil { return err } envelope := kafkaEnvelope{ EventID: stableIMEventID("audit_event", tenantID, "audit."+action, resource+":"+resourceID, encoded), TenantID: tenantID, SourceService: "im-server", TargetService: "hotgo-admin", EventType: "audit." + action, BizType: "audit", BizID: resource + ":" + resourceID, OccurredAt: payload.OccurredAt, Payload: encoded, } if !actor.IsZero() { envelope.Actor = &kafkaActor{Type: actorType, ID: actorID} } return publishKafkaAuditEventEnvelope(ctx, "audit_event", envelope.BizID, envelope) }