Skip to content

fix: stabilization batch 5 — grpc scaffold, middleware, interfaces, elasticsearch, config port, swagger#61

Merged
sazardev merged 2 commits into
masterfrom
fix/stabilization-batch-5
Jun 14, 2026
Merged

fix: stabilization batch 5 — grpc scaffold, middleware, interfaces, elasticsearch, config port, swagger#61
sazardev merged 2 commits into
masterfrom
fix/stabilization-batch-5

Conversation

@sazardev

Copy link
Copy Markdown
Owner

Stabilization batch 5 — follow-up fixes from the batch-4 audit

Addresses the items documented (but not fixed) in #60. Each fix was reproduced against generated projects and verified with go build/go vet. The full multi-DB matrix (init → feature --validation --middleware-types … → handler --type grpc) now builds + vets clean on all six databases — sqlite, postgres, mysql, postgres-json, sqlserver, mongodb (6/6). go test ./cmd/... is green.

Fixed

  1. gRPC scaffold broke the whole module. The //go:build proto server imported a pb package that was never generated; go mod tidy/go vet evaluate build-tagged files and attempted a remote module lookup, failing for the entire module. Now generate a build-tagged placeholder pb package so the import resolves locally — the default build still excludes it, and -tags proto compiles the scaffold against the stubs (the placeholder is deleted once protoc produces the real *.pb.go). Verified: go mod tidy, default go build/go vet, and go build -tags proto all succeed.
  2. feature --middleware-types left an orphaned package. routes.go was generated before the middleware package existed, so it emitted inline cors/logging duplicates and never imported the package. Reordered so the middleware package is generated first; routes.go now imports it and wires middleware.CORS/middleware.Logging.
  3. interfaces --handler/--all didn't compile (undefined: User). The gRPC request/response interfaces referenced a bare *User; they now return *domain.<Entity> and the package is imported. Verified the interfaces package builds.
  4. Elasticsearch reads always returned empty. FindAll/FullTextSearch ignored (or discarded) the response body and returned an untouched empty slice, and FindByID decoded the raw GET envelope instead of _source. Now parse hits[]._source / _source into the domain types.
  5. .goca.yaml always recorded database.port: 5432. Now records the conventional port for the chosen --database (mysql 3306, mongodb 27017, sqlserver 1433, elasticsearch 9200, sqlite/dynamodb 0).
  6. messages --dry-run created empty directories. Removed the unconditional os.MkdirAll; the file writers create parent dirs only when a file is actually written.
  7. repository --implementation was a no-op (it always regenerated the interface too, identical to the default). It now emits only the implementation, mirroring --interface-only; feature updated to request both layers explicitly so its DI wiring still compiles.
  8. Swagger @Success annotations referenced non-existent types (swag init would fail): Get used usecase.Get<Entity>Output (never generated → now domain.<Entity>) and List used usecase.List<Entity>sOutput (→ the real usecase.List<Entity>Output).

Investigated — not bugs

  • Exit codes (middleware/config validate/config init/template show/doctor): all already return non-zero on error on current master (fixed in an earlier batch / stale audit).
  • analyze --output json: already emits valid JSON on stdout (human output goes to stderr).
  • Dead flags --validation/--dto-validation: not dead — they toggle generation; the audit saw identical output only because the config defaults them on (config-driven default, same as --swagger).

Remaining (genuinely larger — left for dedicated work)

  • init --template (minimal/rest-api/microservice/monolith/enterprise) still produces byte-identical Go code; only .goca.yaml differs. Delivering distinct scaffolds (e.g. microservice gRPC, monolith web) is a feature, not a fix.
  • Custom templates (goca template init + edit) are still not consumed by generation — needs the template engine wired into the generators.
  • interfaces --repository/--usecase produce standalone TDD interfaces that drift from the real generated implementations.
  • test-integration --database doesn't affect helpers.go (always imports all drivers).
  • --cache as the first feature is still orphaned (the new DI container is created with cache disabled) — needs full redisClient scaffolding in NewContainer + main.go. (Batch 4 already made the incremental path compile-safe.)
  • Wide wiki/ doc drift (Gin vs gorilla/mux, default DB, JWT version, file layout).

Note: pre-existing test failures (not from this PR)

internal/testing/tests (TestEntityCommand, TestFeatureCommand, TestConfigCodeGeneration/DatabaseTypeMySQL) fail identically on master — stale hardcoded content expectations (e.g. expecting Client_id) that drifted from the generators across earlier batches. They are unrelated to this PR; worth a dedicated cleanup of the integration suite's expectations.

🤖 Generated with Claude Code

sazardev and others added 2 commits June 14, 2026 14:16
…aces, elasticsearch reads, config port, messages dry-run

Continues the stabilization effort (follow-up to batch 4). Each fix reproduced
against generated projects and verified with go build/go vet across all
databases.

- gRPC handler scaffold broke the whole module: the //go:build proto server
  imported a `pb` package that was never generated, so `go mod tidy`/`go vet`
  (which evaluate build-tagged files) attempted a remote module lookup and
  failed. Generate a build-tagged placeholder `pb` package so the import
  resolves locally; the default build still excludes it, and `-tags proto`
  compiles the scaffold against the stubs (delete the placeholder once protoc
  produces the real *.pb.go).
- feature --middleware-types generated an internal/middleware package that was
  never imported: routes.go was written before the package existed, so it fell
  back to inline cors/logging duplicates and left the package orphaned. Generate
  the middleware package BEFORE the handlers so routes.go detects it and wires
  middleware.CORS/Logging from the package.
- interfaces --handler/--all emitted non-compiling code: the gRPC
  request/response interfaces referenced a bare, undefined *User. Reference
  *domain.<Entity> and import the domain package.
- Elasticsearch repository reads always returned empty: FindAll and
  FullTextSearch decoded (or ignored) the response and returned an untouched
  empty slice, and FindByID decoded the raw GET envelope instead of its
  "_source". Parse hits[]._source / _source into the domain types.
- Generated .goca.yaml always recorded database.port: 5432 regardless of
  --database. Record the conventional port for the chosen database
  (mysql 3306, mongodb 27017, sqlserver 1433, elasticsearch 9200, sqlite 0).
- goca messages --dry-run created empty internal/messages and
  internal/constants directories. Drop the unconditional os.MkdirAll; the file
  writers create parent dirs only when a file is actually written.
- repository --implementation was a no-op (always regenerated the interface
  too, same as the default). It now emits only the implementation, mirroring
  --interface-only; feature wiring updated to request both layers explicitly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The generated swaggo annotations referenced types that do not exist, so
`swag init` would fail:
- Get<Entity> used usecase.Get<Entity>Output, which is never generated — the
  handler returns the domain entity, so reference domain.<Entity>.
- List<Entity>s used usecase.List<Entity>sOutput, but the use case returns
  usecase.List<Entity>Output (singular entity name).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sazardev sazardev merged commit 8aaeb51 into master Jun 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant