projector

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package projector applies canonical store events to the OpenSearch search projection (ADR-013). PostgreSQL remains the source of truth; OpenSearch is an eventual, idempotent, tenant-scoped read model. Deletions propagate from tombstones: a MemoryTombstoned event deletes the projected document, so search results never resurrect a deleted record.

Index

Constants

This section is empty.

Variables

View Source
var AuditMapping = []byte(`{
	"settings": { "number_of_shards": 1, "number_of_replicas": 0 },
	"mappings": {
		"properties": {
			"tenantId":     { "type": "keyword" },
			"seq":          { "type": "long" },
			"eventType":    { "type": "keyword" },
			"resourceType": { "type": "keyword" },
			"resourceId":   { "type": "keyword" },
			"actor":        { "type": "keyword" },
			"details":      { "type": "object", "enabled": false },
			"prevHash":     { "type": "keyword" },
			"chainHash":    { "type": "keyword" },
			"occurredAt":   { "type": "date" }
		}
	}
}`)

AuditMapping is the OpenSearch index mapping for projected audit events (ADR-014 projection). The index is append-only: audit records are never deleted, so there is no tombstone path.

View Source
var MemoryMapping = []byte(`{
	"settings": { "number_of_shards": 1, "number_of_replicas": 0 },
	"mappings": {
		"properties": {
			"tenantId":     { "type": "keyword" },
			"namespace":    { "type": "keyword" },
			"key":          { "type": "keyword" },
			"contentType":  { "type": "keyword" },
			"content":      { "type": "text" },
			"sensitivity":  { "type": "keyword" },
			"resourceVersion": { "type": "long" },
			"createdAt":    { "type": "date" },
			"updatedAt":    { "type": "date" },
			"tombstoneAt":  { "type": "date" }
		}
	}
}`)

MemoryMapping is the OpenSearch index mapping for projected memory records. Vectors stay in the canonical pgvector store; OpenSearch carries the text fields for full-text search across records.

Functions

This section is empty.

Types

type AuditEventPayload

type AuditEventPayload struct {
	TenantID string `json:"tenantId"`
	AuditID  string `json:"auditId"`
	Seq      int64  `json:"seq"`
}

AuditEventPayload is the AuditRecorded outbox payload.

type AuditProjector

type AuditProjector struct {
	// contains filtered or unexported fields
}

AuditProjector applies AuditRecorded events to the OpenSearch audit index (append-only). Application is idempotent by seq: a stale event never overwrites a newer projected record.

func NewAuditProjector

func NewAuditProjector(store AuditStore, search SearchIndex) *AuditProjector

NewAuditProjector wires the audit projector to the canonical ledger and the OpenSearch index.

func (*AuditProjector) Apply

func (p *AuditProjector) Apply(ctx context.Context, event store.OutboxEvent) error

Apply applies one audit event idempotently.

type AuditStore

type AuditStore interface {
	GetAuditEvent(context.Context, string, uuid.UUID) (store.AuditEvent, error)
}

AuditStore is the canonical ledger read surface the projector needs.

type MemoryEvent

type MemoryEvent struct {
	TenantID        string `json:"tenantId"`
	MemoryID        string `json:"memoryId"`
	Namespace       string `json:"namespace"`
	Key             string `json:"key"`
	ResourceVersion int64  `json:"resourceVersion"`
}

MemoryEvent is the projection event payload emitted by the canonical store.

type MemoryProjector

type MemoryProjector struct {
	// contains filtered or unexported fields
}

MemoryProjector applies memory events to the OpenSearch index.

func NewMemoryProjector

func NewMemoryProjector(store MemoryStore, search SearchIndex) *MemoryProjector

NewMemoryProjector wires the projector to the canonical store and the OpenSearch index.

func (*MemoryProjector) Apply

func (p *MemoryProjector) Apply(ctx context.Context, event store.OutboxEvent) error

Apply applies one memory event idempotently:

  • MemoryUpserted fetches the canonical record and indexes it; a stale event (record version <= projected version) is skipped, and a record that no longer exists is dropped.
  • MemoryTombstoned deletes the projected document (deletion propagation); a missing document is idempotent success.

type MemoryStore

type MemoryStore interface {
	GetMemory(context.Context, string, uuid.UUID) (store.MemoryRecord, error)
}

MemoryStore is the read surface the projector needs (the canonical store).

type SearchIndex

type SearchIndex interface {
	Get(context.Context, string) ([]byte, error)
	Index(context.Context, string, any) error
	Delete(context.Context, string) error
}

SearchIndex is the OpenSearch surface the projector writes to; the concrete *opensearch.Client satisfies it.

Jump to

Keyboard shortcuts

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