Skip to content
CAI
Software that uses CAICheck a score

MarioCarrion/todo-api-microservice-example

66.7

Adequate · 21 September 2026

2.5k

lines of production code

Go

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a task management microservice that exposes a type-safe REST API for creating, updating, and searching tasks. It persists task data in PostgreSQL and enhances search capabilities through Elasticsearch indexing. The architecture supports asynchronous event publishing to Kafka, RabbitMQ, or Redis to decouple services, while utilizing Memcached for read-through caching and HashiCorp Vault for secure secret management.

Features

Add Elasticsearch indexing service with multi-broker support

Introduces new standalone services for indexing tasks into Elasticsearch, available via Kafka, RabbitMQ, or Redis as the message broker. The \cmd\ directory now includes \elasticsearch-indexer-kafka\, \elasticsearch-indexer-rabbitmq\, and \elasticsearch-indexer-redis\ binaries, each consuming task events (created, updated, deleted) and persisting them to Elasticsearch. Additionally, the REST server (\cmd/rest-server\) is updated to support these message brokers via build tags (\kafka\, \rabbitmq\, or default Redis), allowing the API to publish events to the indexer. Internal helpers in \cmd/internal\ provide client initialization for Elasticsearch, Kafka, RabbitMQ, Redis, PostgreSQL, Memcached, and Vault.

cmd · high confidence

Add Elasticsearch repository for task persistence

Introduces a new internal Elasticsearch repository (\internal/elasticsearch\) that enables storing, searching, and deleting task records. The implementation uses the \go-elasticsearch/v7\ client to index tasks with fields like description, priority, and completion status, and supports filtering by these attributes with pagination. Tests verify the repository's functionality using a Dockerized Elasticsearch 7.17.28 instance, ensuring cluster health before executing operations.

internal/elasticsearch · high confidence

Adopts 'Tools as Dependencies' pattern for internal development tooling

The repository now manages development tools as Go module dependencies within the internal/tools package. This change introduces a standardized set of tools—including golangci-lint, sqlc, oapi-codegen, govulncheck, and others—allowing them to be installed and version-controlled alongside the project code via \make tools\. This ensures consistent tool versions across environments and simplifies the setup process for developers.

internal/tools · high confidence

Introduce memcached repository with Write-Through and Cache-Aside strategies

The \internal/memcached\ package now provides a task repository implementation that caches task data using Memcached. The \Task\ type implements a Write-Through caching strategy for Create and Update operations, ensuring the cache is updated synchronously with the underlying store, and a Cache-Aside strategy for Find operations, populating the cache on misses. Additionally, the \SearchableTask\ type applies Cache-Aside caching to search queries, storing results for 25 seconds to reduce load on the original store. The implementation includes generated test doubles (\FakeTaskStore\, \FakeSearchableTaskStore\) and comprehensive tests verifying cache hit/miss behavior and store interaction.

internal/memcached · high confidence

Introduces OpenAPI 3 code generation and Docker Compose infrastructure for local development

The project now generates a type-safe HTTP client (\client.gen.go\) from an OpenAPI 3 specification using \oapi-codegen\, replacing manual client construction with standardized models and request handlers. Additionally, a comprehensive Docker Compose setup is introduced, allowing developers to run the REST server and its dependencies (PostgreSQL, Elasticsearch, Memcached, Vault) locally, with support for pluggable message brokers (Redis, RabbitMQ, Kafka) via separate compose files.

(repo-wide) · high confidence

Introduces structured error handling and domain models for task management

The internal package now provides a structured error system with typed codes (Unknown, NotFound, InvalidArgument) and wrapping support, alongside core domain types for Tasks including Priority, Dates, and validation logic. It also introduces parameter structs (CreateParams, SearchParams, UpdateParams) for API inputs and utility functions like PointerToValue, establishing the foundational data structures and error semantics for the application.

internal · high confidence

Kafka event publishing for task lifecycle changes

The internal/kafka package now includes a Task publisher that emits structured events to Kafka whenever a task is created, updated, or deleted. This implementation uses the confluent-kafka-go v2 client to send JSON messages containing the task data and a specific event type (e.g., Task.Created) to a configurable topic, enabling downstream services to react to task state changes.

internal/kafka, internal/rabbitmq · high confidence

New Dockerfiles for Elasticsearch indexers and REST server

Added Dockerfiles for the elasticsearch-indexer (with Kafka, RabbitMQ, and Redis variants) and the REST server. These files define multi-stage builds using golang:1.27.1-bookworm and debian:bookworm-20260824-slim, producing static binaries. The REST server Dockerfile includes the OpenAPI spec and exposes port 9234.

dockerfiles · high confidence

PostgreSQL repository implementation using pgx/v5 and sqlc

The internal/postgresql package now provides a concrete repository for Task persistence, replacing previous database interaction patterns. It utilizes the pgx/v5 driver and sqlc-generated code to handle database operations, including creating, finding, updating, and deleting tasks. The implementation includes type-safe conversion logic for internal domain models (such as Priority and Timestamps) to database types and introduces unit tests for these conversions alongside integration tests that spin up a real PostgreSQL container to verify repository behavior.

internal/postgresql · high confidence

REST API layer now uses OpenAPI-generated types and strict server handlers

The internal REST package has been refactored to use code generation from the OpenAPI specification (via oapi-codegen) instead of manual routing and struct definitions. This introduces generated strict-server interfaces and type-safe request/response models (e.g., CreateTaskRequestObject, Task) in server.gen.go, along with new custom types in dates.go and priority.go that handle validation and JSON marshaling/unmarshaling. The task\_handler.go now implements these generated interfaces, converting between the generated REST types and the internal domain models, providing a more robust and type-safe HTTP API layer.

internal/rest · high confidence

Redis-based event publishing for task lifecycle changes

The internal/redis package now includes a Task repository that publishes JSON-encoded events to Redis Pub/Sub channels whenever a task is created, updated, or deleted. This enables other services to subscribe to specific task events (e.g., Task.Created, Task.Updated, Task.Deleted) or all task events via a wildcard pattern, facilitating asynchronous communication within the microservice architecture.

internal/redis · high confidence

Secure configuration via environment variables and Vault provider

The internal/envvar package now supports retrieving sensitive values from an external secret provider (such as Hashicorp Vault) instead of plain environment variables. When a configuration key has a corresponding \\<KEY\>\_SECURE\ environment variable set, the system uses the injected Provider interface to fetch the actual secret value; otherwise, it falls back to the standard environment variable. This change introduces the Provider interface, a Configuration struct that wraps it, and a FakeProvider for testing, allowing applications to securely manage secrets without hardcoding them.

internal/envvar · high confidence

Task service introduces circuit breaker and message broker integration

The task application service now integrates a circuit breaker pattern (using go-circuitbreaker) to protect search operations and publishes task lifecycle events (Created, Deleted, Updated) to a message broker. This change adds new interfaces for repository, search, and message broker dependencies, along with generated test fakes and corresponding unit tests to verify the service behavior.

internal/service · high confidence

Vault-based secret retrieval with local caching

The application now supports retrieving secrets from HashiCorp Vault via a new \internal/envvar/vault\ package. This component initializes a Vault client using a token and address, and provides a \Get\ method that fetches values from the KV engine using a colon-separated path and key format (e.g., \path:key\). It includes local in-memory caching to avoid repeated network calls for the same secret path, and returns specific errors for missing keys, invalid data, or unavailable secrets.

internal/envvar/vault · high confidence

Behavioural changes

Database schema and migration tooling updated

The database layer now uses the 'tern' tool for managing migrations instead of the previous system. Initial migrations define a 'tasks' table with UUID primary keys, description, priority, dates, and a done flag. The schema has been updated to use the native 'gen\_random\_uuid()' function for ID generation, removing the dependency on the 'uuid-ossp' extension.

db · high confidence

PostgreSQL data layer regenerated with sqlc v1.30.0 and pgx/v5

The internal PostgreSQL database access layer has been regenerated using sqlc v1.30.0, updating the generated Go code to use the jackc/pgx/v5 driver. This change affects the type-safe query implementations for tasks (insert, select, update, delete) and model definitions, ensuring compatibility with the newer pgx/v5 library and its associated types like pgtype.Timestamp.

internal/postgresql/db · high confidence

Test coverage

Added generated mock for TaskService in resttesting package

The internal/rest/resttesting package now includes a generated fake implementation of the TaskService interface (task\_service.gen.go), created using counterfeiter. This mock supports stubbing and verifying calls for service methods such as By, ByID, Create, Delete, and Update, enabling more robust unit testing of REST handlers that depend on task service operations.

internal/rest/resttesting · high confidence

Dependencies

Initialize Go module with Go 1.26 and core dependencies

The project initializes its Go module (github.com/MarioCarrion/todo-api-microservice-example) targeting Go 1.26. The main module includes dependencies for PostgreSQL (jackc/pgx/v5, jackc/tern/v2), caching (gomemcache, go-redis/v9), messaging (confluent-kafka-go/v2, amqp091-go), observability (go-elasticsearch/v7, zap), and security (hashicorp/vault/api). Tooling dependencies in internal/tools include golangci-lint/v2, oapi-codegen/v2, sqlc, and counterfeiter.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 78 → 67 (-11.1)
  • Rubric changed (rubric-2026.08.18 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 97 → 89 (-7.6)
  • Architecture 100 → 100 (+0.0)
  • Maturity 95 → 65 (-30.2)
  • Readiness 83 → 72 (-10.6)
  • Security 73 → 86 (+12.8)
  • Domain Modelling 100 → 61 (-38.9)
  • Event-Driven 72 → 72 (+0.0)

Resolved (24)

  • Coverage not included — suite not readable by the collector
  • Critical vulnerability: [GHSA redacted] (internal/tools/go.mod)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (13 lines × 2) (internal/rest/task_handler.go)
  • Duplicated block (13 lines × 3) (cmd/elasticsearch-indexer-kafka/main.go)
  • Duplicated block (15 lines × 3) (cmd/elasticsearch-indexer-kafka/main.go)
  • Duplicated block (16 lines × 3) (cmd/elasticsearch-indexer-kafka/main.go)
  • Duplicated block (19 lines × 2) (cmd/elasticsearch-indexer-rabbitmq/main.go)
  • High vulnerability: [GHSA redacted] (internal/tools/go.mod)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • LLM evaluation failed
  • Medium CVE: GO-2026-4599 (internal/tools/go.mod)
  • Medium CVE: GO-2026-5158 (go.mod)
  • Medium CVE: GO-2026-5942 (go.mod)
  • Medium vulnerability: [GHSA redacted] (internal/tools/go.mod)
  • Medium vulnerability: GO-2026-5841 (go.mod)
  • Medium vulnerability: GO-2026-5932 (go.mod)
  • …and 4 more

New (80)

  • Dependency pinned to a stale untagged commit: github.com/bradfitz/gomemcache
  • Documentation: no installation or build instructions (README.md)
  • Duplicated block (14 lines × 2) (internal/rest/task_handler.go)
  • Duplicated block (14 lines × 3) (cmd/elasticsearch-indexer-kafka/main.go)
  • Duplicated block (15 lines × 4) (cmd/elasticsearch-indexer-kafka/main.go)
  • Duplicated block (16 lines × 4) (cmd/elasticsearch-indexer-kafka/main.go)
  • Duplicated block (47 lines × 2) (cmd/elasticsearch-indexer-rabbitmq/main.go)
  • Duplicated block (5 lines × 2) (internal/memcached/task.go)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • Medium CVE: GO-2026-4599 (internal/tools/go.mod)
  • Medium CVE: GO-2026-6179 (go.mod)
  • Medium IaC: WD-COMPOSE-0002 (compose.kafka.yml)
  • Medium IaC: WD-COMPOSE-0002 (compose.kafka.yml)
  • Medium IaC: WD-COMPOSE-0002 (compose.kafka.yml)
  • Medium IaC: WD-COMPOSE-0002 (compose.rabbitmq.yml)
  • Medium IaC: WD-COMPOSE-0002 (compose.redis.yml)
  • …and 60 more

Changes since last survey

  • 43 commits — 41 feature/other, 2 fixes

By area

  • (root) — 26 commits
  • internal/tools — 10 commits
  • dockerfiles/elasticsearch-indexer-kafka.Dockerfile — 4 commits
  • .github/workflows — 2 commits
  • internal/elasticsearch — 1 commit

Notable commits

  • fix: fix(elasticsearch): Add timeoout to prevent tests failing (#841)
  • fix: fix(lint): migrate exhaustruct config to v5
  • change: build(redis): migrate go-redis v8 to v9
  • change: chore(compose): bump stale pinned image versions
  • change: chore: bump actions/setup-go from 6 to 7
  • change: chore: bump actions/stale from 10.4.0 to 11.0.0
  • change: chore: bump confluentinc/cp-kafka from 7.6.2 to 8.3.1
  • change: chore: bump confluentinc/cp-kafka from 8.3.1 to 8.3.2 (#845)
  • change: chore: bump confluentinc/cp-zookeeper from 7.6.2 to 7.9.1
  • change: chore: bump curlimages/curl from 8.8.0 to 8.22.0 (#838)
  • change: chore: bump debian in /dockerfiles in the go-versions group
  • change: chore: bump debian in /dockerfiles in the go-versions group
  • change: chore: bump elasticsearch from 7.17.28 to 9.5.1
  • change: chore: bump elasticsearch from 9.5.1 to 9.5.3 (#836)
  • change: chore: bump github.com/confluentinc/confluent-kafka-go/v2
  • change: chore: bump github.com/confluentinc/confluent-kafka-go/v2 (#842)
  • change: chore: bump github.com/getkin/kin-openapi in /internal/tools
  • change: chore: bump github.com/go-ozzo/ozzo-validation/v4 from 4.3.0 to 4.4.1
  • change: chore: bump github.com/golangci/golangci-lint/v2 in /internal/tools
  • change: chore: bump github.com/golangci/golangci-lint/v2 in /internal/tools (#835)
  • …and 23 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

MarioCarrion/todo-api-microservice-example was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit fbd54380dd5ba5842bb22eefe53f974a20461fe1 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.