๐Ÿ—“๏ธ 07062026 1150
๐Ÿ“Ž

REVIEW BACKIES

Applied companion to the Go notes. A review of the backies service (a single Go backend serving language-learning apps) through the idioms in learning_plan. Unlike the other notes this is not one atomic concept โ€” it maps real code to the concepts and flags where the code could improve. Paths are relative to the repo root.

What it does wellโ€‹

ConceptWhere in backiesNotes
dependency_injectioncmd/api/main.go, internal/materia/routes.goClean composition root. main wires config โ†’ db โ†’ services โ†’ routes; RegisterRoutes cascades deps down. No framework.
interfacesinternal/materia/services/*.goInterfaces (QuoteReader, SourceWriter) defined in the consumer, not the repo package. Accept-interface / return-struct throughout.
project_structureinternal/<domain>/, internal/shared/Grouped by domain (materia, grafana, lark) with shared infra split out. shared/httpx is correctly named to dodge the net/http clash.
struct_embeddingmetrics/middleware.go, alerting/middleware.goresponseWriter / alertResponseWriter embed http.ResponseWriter and override WriteHeader to capture status โ€” textbook wrapper.
channels ยท selectalerting/alerter.goLarkAlerter = buffered chan (100) + single consume() goroutine; non-blocking select { default: drop } on send; Close() closes the channel and waits on done to drain.
sync_primitiveshealth/registry.go, alerting/rate_limiter.goRWMutex with a snapshot-then-release pattern in the health registry; sync.Map for the per-key rate limiter.
panic_recoveralerting/safe_go.goSafeGo recovers goroutine panics so a background task can't crash the process.
graceful_shutdownserver/server.go Start()signal.Notify on SIGINT/SIGTERM, select on errors-vs-signal, Shutdown(ctx) with a 30s deadline, then DB close. Server sets no WriteTimeout โ€” request duration is governed solely by the router timeout, so long LLM responses aren't cut mid-write.
custom_error_types ยท error_handlingshared/errors/errors.goAppError implements Error/Unwrap; RespondError uses errors.As to map to a status. 500s send a generic message and log the wrapped cause โ€” no internal leakage.
context ยท deferrepos/services/handlers; main.goctx is the first param across I/O; Init functions return a cleanup func() used as defer closeAlerting() / defer cancel(). Per-route timeouts (httpx.DefaultTimeout 3s, httpx.LLMTimeout 180s) applied as sibling groups, since a context deadline can only be shortened, never lengthened.

Could improveโ€‹

PriorityIssueLocationSuggestion
HighNo tests anywhere โ€” every package reports [no test files].whole repoStart with table-driven tests on services using interface fakes (testing). The interface-based DI already makes this easy.
LowPackage-level mutable singletons (defaultAlerter, defaultQuoteMetrics + SetDefault).alerting/alerter.go, metrics/quote_metrics.goConvenient and consistent with the codebase, but global mutable state is ordering-sensitive and harder to isolate in tests. Acceptable; just know the trade-off.
LowSilent alert drops when the buffer is full (select default).alerting/alerter.goBy design, but increment a metric on drop so it's observable rather than invisible.
Lowinterface{} instead of any in response helpers.httpx/response.goCosmetic modernize (go vet/modernize flags it).
WARNING

The earlier WriteTimeout-vs-router-Timeout mismatch (which truncated long responses at 15s) has been fixed โ€” the server now sets no WriteTimeout. The biggest remaining gap is the total absence of tests on a codebase that's otherwise production-shaped.

Referencesโ€‹