projector-go

Create Go projectors that keep read-model projections fresh from domain and integration events.

4|Updated Jul 30, 2026
One-click install
npx skills add https://github.com/gabriellst/codm --skill projector-go-gabriellst
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: projector-go
Source: https://github.com/gabriellst/codm/tree/main/.claude/skills/projector/go
Command: npx skills add https://github.com/gabriellst/codm --skill projector-go-gabriellst

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? In event-driven Go backends, read models drift out of sync when projection update logic is scattered or inconsistent. This Skill provides the canonical patterns for writing Projectors — the single event-driven writers of a projection — so every mutation follows the correct find → ApplyX → save flow with proper idempotency and missing-row handling. ## Core Features & Use Cases - Canonical Mutation Flows: Enforces find → projection.ApplyX(event) → save for mutations, InsertIfNew for creation events, and atomic repo ops only when justified by hot-row or bulk scenarios. - Mediator Integration: Guides registration with InternalMediator for domain events and ExternalMediator for integration events inside the fx module's registerHandlers func. - Defensive Semantics: Missing rows log slog.Warn and return nil instead of stalling the mediator; duplicates from InsertIfNew log at Debug, not error. - Use Case: When adding a new event like channel.message_edited to a Go service, use this Skill to generate a MessageEditedProjector struct with the correct repository interface, EventName constant, and fx registration. ## Quick Start Ask the AI to create a Go projector for a specific event, for example: create a projector that handles the message delivered event and updates the message projection.

Frequently Asked Questions about projector-go

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a projector in Go for domain events?

Define a concrete struct with a single projection repository field, implement EventName() returning the event name constant, and implement Handle to unmarshal the event with types.UnmarshalDomainEvent, then run find → ApplyX → save. Register it with the InternalMediator in the module's registerHandlers func.

What is the difference between a projector and an event handler?

A projector is the single event-driven writer of its projection, subscribing to every event that mutates that read model. Handlers orchestrate use cases and may publish integration events; projectors must never call use cases or publish events.

Should a Go projector return an error when the projection row is missing?

No. A missing row is non-fatal because events can arrive out of order during replay. Log slog.Warn with enough context to trace the event and return nil so the mediator is not stalled.

How do I handle duplicate events in a Go projector?

Use the repository's InsertIfNew method for creation events. It is idempotent: a duplicate returns (false, nil), which you log at Debug level rather than treating as an error.

When should a projector use atomic repository operations?

Use atomic repo ops only when the canonical find → ApplyX → save path would cause hot-row contention, N+1 bulk operations, monotonic violations, or conditional conflicts. Document the justification inline in the code.

How do integration event projectors differ from domain event projectors in Go?

Integration event projectors implement the mediator's IntegrationEventHandler interface, unmarshal with types.UnmarshalIntegrationEvent, and register with the ExternalMediator. Domain event projectors use UnmarshalDomainEvent and register with the InternalMediator.