بنقرة واحدة
go-review-service
Audit a GOB Go microservice against all project conventions and patterns
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Audit a GOB Go microservice against all project conventions and patterns
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Internal POSIX runtime helpers for agente-00c/feature-00c orchestrators (state, lock, validation, hashes, secrets filter). NOT user-invocable.
Task status / backlog progress report; identifies tasks ready to start. Triggers: "revisar tarefas", "status das tarefas", "progresso do projeto", "review tasks". Skip for executing (execute-task) or creating tasks (create-tasks).
GLOBAL feature portfolio dashboard — compare progress, suggest archive/abandon/prioritize. Triggers: "status global", "portfolio de features", "dashboard de features", "comparar features". Cross-feature; for single feature deep-dive use review-task.
Convert a natural-language feature description into SDD spec (user stories, FRs, success criteria). Triggers: "specify", "criar spec", "nova feature", "feature spec". Skip for refining an existing spec (clarify).
Requirements quality gate ("unit tests for English") by domain (ux/api/security/performance/a11y). Triggers: "checklist", "validar requisitos", "quality gate". Validates REQUIREMENT quality, not code.
Refine an existing spec via structured Q&A (max 5). Triggers: "clarify", "clarificar spec", "resolver ambiguidades", "refinar spec". Operates on existing spec.md; use specify to create one.
| name | go-review-service |
| description | Audit a GOB Go microservice against all project conventions and patterns |
| allowed-tools | ["Read","Glob","Grep","Bash"] |
Perform a comprehensive read-only audit of a GOB Go microservice, checking 17 conventions. Outputs a structured PASS/FAIL/WARNING report with line references.
"review service", "audit service", "validar servico", "check service", "verificar servico", "checar servico"
$ARGUMENTS should specify:
gob-member-service) — requiredDetermine the service root:
services/{service-name}/
Read these files first (in parallel where possible):
cmd/api/main.go — middleware order, wiring, shutdowninternal/factory/factory.go — repository factoryinternal/repository/repository.go — interfacesinternal/handler/*.go — route registrationgo.mod — module path, dependenciesmigrations/ — list files for schema referenceFor each check, output one of:
Expected order (top to bottom in main.go):
recover.New()requestid.New()apmfiber.Middleware(apmfiber.WithTracer(tracer)) — after requestid, before logging (unconditional/nil-safe; rollout-window dual-accept detailed in Check 3)middleware.LoggingWithLogger(log) or middleware.Logging()cors.New(...) — with AllowOrigins, AllowHeaders, AllowMethods, AllowCredentialsmiddleware.DryRun(...) — if service supports dry-runmiddleware.DryRunFinalizer() — if dry-run presentmiddleware.AuditPublisher(...) — after cors/dryrun, before endpointsSearch: Look for app.Use( calls in main.go. Verify order matches.
rabbitmq.NewFromURL)middleware.AuditExchange constantif rmqURL != "" with warning on failuredefer auditRMQ.Close() presentSearch: AuditPublisher in main.go.
observability.ElasticAPMTracer(cfg, log) called, returns (tracer, err) (non-fatal on error — Resilience Class A: degraded/non-recording, not a boot failure)apmfiber.Middleware(apmfiber.WithTracer(tracer)) present, unconditional — WithTracer(nil) is nil-safe (falls back to apm.DefaultTracer()), no != nil guard neededdefer observability.ShutdownElasticAPM(tracer) presentrequestid and before logging middlewareRollout-window dual-accept (FR-007): while the platform-wide code migration to Elastic APM is in progress across the 20 repositories (commons + 19 services), this check PASSes if the service shows the Elastic signals above OR the legacy signals below in isolation — it FAILs only when neither is present. This is a documented, temporary exception to the zero-New-Relic-references goal (spec.md SC-001), ratified to close once code migration completes (spec.md Clarifications — "aperto final").
observability.NewRelicApp(serviceName, cfg, log) called; nrfiber.Middleware(nrApp) present (historically conditional on nrApp != nil); defer observability.ShutdownNewRelic(nrApp) present.Search: Elastic — ElasticAPMTracer, apmfiber, ShutdownElasticAPM in main.go.
Legacy (rollout window only) — NewRelicApp, nrfiber, ShutdownNewRelic in main.go.
Aperto final (runbook task 6.5): once the operator confirms code migration is complete across all 20 repositories, DELETE the "Legacy signals" bullet and the second half of the Search line above — this check then requires the Elastic signals exclusively and FAILs any service still showing New Relic wiring.
For each handler's RegisterRoutes() method:
/types, /counts, /search) MUST come BEFORE parameterized routes (/:id)/groups) MUST be registered BEFORE /:id catch-allFAIL if: Any /:id or /:param route appears before a static route at the same level.
Search: All RegisterRoutes methods in internal/handler/.
context.Context is the first parameter in every methodFindByID returns (*domain.X, error) — nil/nil when not foundinternal/repository/repository.goSearch: repository.go file, look for interface definitions.
GetContext (single row) and SelectContext (multiple rows)sql.ErrNoRows returns nil, nil (not wrapped as error)member.members)$1, $2, ... positional parameters (not ?)db:"" tags separate from domain structstoDomain() converter methods on row structsSearch: internal/repository/postgres/*.go files.
var ErrXxxNotFound = errors.New("...")Search: internal/service/*.go files, look for var Err and return types.
errors.Is() for sentinel error matchingdto.ErrorResponse with appropriate HTTP status codesmiddleware.GetUserID(c), middleware.GetClaims(c)c.Status(xxx).JSON(dto.ErrorResponse{...}) patternSearch: internal/handler/*.go for errors.Is and ErrorResponse.
Repositories struct holds all repo instancesNewRepositories(db) constructor creates all reposNewDryRunRepositories(db) for dry-run mode (if applicable)RepositoryFactory with isDryRun flag (if dry-run supported)Search: internal/factory/factory.go.
snake_case (e.g., json:"lodge_id")snake_case matching column names (e.g., db:"lodge_id")omitempty on optional/nullable fieldsdb:"-" on computed/relation fieldsjson:"-" on fields that should be visible in APISearch: Domain structs in internal/domain/*.go, check tags.
All three must be present:
GET /health — returns 200 OKGET /ready — pings DB (db.PingContext) and returns health statusGET /version — returns service version infoSearch: /health, /ready, /version in main.go.
EnableTrustedProxyCheck: trueTrustedProxies configured (e.g., private network ranges)ProxyHeader: "X-Real-Ip" or "X-Forwarded-For"fiber.Config{} in main.goSearch: fiber.New( or fiber.Config in main.go.
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)consumer.Stop()) if RabbitMQ consumer existsapp.ShutdownWithContext(ctx) or app.Shutdown()Search: signal.Notify, Shutdown, defer in main.go.
github.com/gob/gob-{service-name}github.com/gob/gob-process-serviceSearch: First line of go.mod.
storage.Storage interface from gob-go-commons/pkg/storage/storage.NewFromConfig(cfg) (auto-selects S3 or local)Upload(ctx, key, reader, size, contentType) — NOT PutPresignedGetURL(ctx, key, expiry) — NOT GetPresignedURL{service}/{category}/{entityID}/{uuid}-{filename}.extstorage.ValidateFileType() and storage.ValidateFileSize()storage.Storage parameterSearch: storage.Storage in handler/service files.
N/A if service doesn't handle file uploads.
AMQPPublisher + NoopPublisher (graceful degradation when RabbitMQ unavailable)SetPublisher() method or accepts publisher in constructortopic and durableSearch: Publisher, AMQPPublisher, NoopPublisher in service and messaging files.
N/A if service doesn't publish events.
Verify logging follows the project standards (see CLAUDE.md "Structured Logging Standards"):
15a. Repository layer has logger injected:
log *logger.Logger field*logger.Logger parameter15b. Repository methods have entry/exit/duration logging:
entity, operationduration_msWithError(err) before returningFindByID not-found path must log Debug (not Error)duration_ms15c. Service layer has logging:
log *logger.Logger fieldentity_idWithError(err)15d. Handler layer has logging:
WithRequestID(requestID), WithError(err)entity, operation fields15e. No anti-patterns:
fmt.Println or log.Println (standard library) — must use logger.Loggerlogger.Default() in production code (inject via constructor)fmt.Println or log.Println found in non-test codeSearch: All .go files in internal/, look for log., logger., fmt.Print, log.Print.
# Service Audit: {service-name}
Date: {current date}
## Summary
PASS: X/17 | FAIL: Y/17 | WARNING: Z/17 | N/A: W/17
## Results
### 1. Middleware Order
**PASS** — Correct order: recover → requestid → apmfiber → logging → cors → dryrun → audit
(main.go:45-82)
### 2. Audit Middleware
**FAIL** — Missing separate RabbitMQ connection. Audit reuses existing connection.
(main.go:95)
### 3. Elastic APM
**PASS** — Elastic signals present: `apmfiber.Middleware(apmfiber.WithTracer(tracer))` unconditional/nil-safe, `ElasticAPMTracer`/`ShutdownElasticAPM` wired
(main.go:104-108, 375)
... (continue for all 17 checks)
## Recommendations
1. [Highest priority fixes]
2. [Medium priority improvements]
3. [Low priority suggestions]