MarioCarrion/todo-api-microservice-example
66.7
Adequate · 21 September 2026
2.5k
lines of production code
Go
primary language
4
measurements over time
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.