Skip to content

fix: stabilization batch 4 — generator wiring, time.Time imports, error formatting, CI YAML#60

Merged
sazardev merged 1 commit into
masterfrom
fix/stabilization-batch-4
Jun 14, 2026
Merged

fix: stabilization batch 4 — generator wiring, time.Time imports, error formatting, CI YAML#60
sazardev merged 1 commit into
masterfrom
fix/stabilization-batch-4

Conversation

@sazardev

Copy link
Copy Markdown
Owner

Stabilization batch 4 — deep audit + cross-cutting fixes

This continues the stabilization effort (batches 1–3). I exhaustively exercised every generator command against real, freshly-generated projectsinit, entity, usecase, repository, handler, feature, di, integrate, interfaces, mocks, messages, middleware, test-integration, ci, config, analyze, doctor, upgrade, template — across all database backends, then compiled (go build/go vet), ran the generated tests, and read the output for correctness. Findings were reproduced before fixing.

✅ Verified result of this PR

A full feature pipeline (init → feature User --fields "...,joined:time.Time" --validation) now builds + vets + passes generated tests on all six databases — sqlite, postgres, mysql, postgres-json, sqlserver, mongodb (matrix: 6/6 pass, previously several failed to compile). Two-feature projects and --cache projects also compile and test clean. Full go test ./... on the goca repo is green.


Fixed in this PR

Critical compile breakers

  1. Repository constructor wiring broke every non-Postgres backend. di, feature, integrate and test-integration all referenced NewPostgres<Entity>Repository, but the repository generator emits NewPostgresJSON…, NewSQLServer…, NewMongo…, etc. → undefined: repository.NewPostgres… for postgres-json/sqlserver/sqlite/mongodb. Introduced a single repoConstructorPrefix(database) helper used everywhere.
  2. feature hardcoded "postgres" when creating a new DI container and never threaded the chosen --database through updateDIContainer/addFeatureToDI/addSetupMethodsToDI.
  3. SQLite was structurally un-wireable. Generated main.go/DI hold a *gorm.DB (gorm.io/driver/sqlite), but the repository used a bespoke database/sql (*sql.DB) impl that could never be injected. Routed SQLite through the shared GORM generator (as MySQL already is). Default DB now works end-to-end.
  4. MongoDB container scaffold used NewContainer(db) but mongo main.go exposes mongoClient (no db). Now derives mongoClient.Database(cfg.Database.Name).
  5. usecase DTOs with time.Time emitted time.Time fields without importing "time"dto.go: undefined: time.
  6. entity unit tests (default --tests) failed to compile / always failed for common fields: missing "time" import, invalid Priority{} composite literal for string-based custom-type stubs, and assert.Equal(time.Now(), field) that can never pass. Now imports time when needed, uses a string-conversion zero literal, and asserts the field is non-zero.

go vet breakers

  1. Repository error formatting: SQLite/SQL Server/DynamoDB/Elasticsearch impls wrote literal %%w (so err was never wrapped) and SQL Server FindByID wrote fmt.Errorf("%s not found") with no argument. Emit %w / substitute the entity name.

Other

  1. goca ci produced an invalid test.yml — the step-level env: block was indented at 6 spaces while sibling step keys use 8, so GitHub Actions rejected the file. Fixed indentation; now valid YAML.
  2. --cache added to an existing DI container emitted c.redisClient/time references the container didn't provide. Now only wires the decorator when a decorator file exists and the container has a redisClient field; otherwise wires the bare repo so the project always compiles.

Tests updated/added accordingly (addSetupMethodsToDI cache pre-conditions, DB-threading callers).


Documented but NOT fixed here (follow-up batch 5)

Reproduced during the audit; left for a focused follow-up to keep this PR reviewable:

  • handler --type grpc / feature --handlers grpc: the //go:build proto server imports a pb package that is never generated; go mod tidy/go vet ignore build tags and fail to resolve it, breaking the whole module. Needs a no-op stub package or to defer the server file until protoc runs.
  • --cache (first feature): decorator file is generated but the generateDI path is called with cache=false, so the decorator/redis client are never wired (orphaned). Needs full redisClient scaffolding in NewContainer + main.go.
  • --middleware-types / --middleware: generates an internal/middleware package that is never imported; routes duplicate inline cors/logging and never apply recovery. In some paths routes.go calls middleware.CORS(...) without importing the package.
  • interfaces --handler/--all: emits undefined: User (references a bare *User); --repository/--usecase interfaces drift from the real generated implementations.
  • Swagger annotations reference non-existent usecase types (usecase.GetUserOutput, usecase.ListUsersOutput); comment-only, so swag init fails but build is fine.
  • Elasticsearch FindAll/FullTextSearch decode the response then return an empty slice (always empty results).
  • init --template: all templates produce byte-identical Go code (only .goca.yaml differs); microservice/monolith/enterprise features not delivered. .goca.yaml database.port is always 5432; template .goca.yaml hardcodes type: postgres regardless of --database.
  • Custom templates (goca template init + edit) are never consumed by generation.
  • Dead flags: usecase --dto-validation, repository --implementation, handler --validation have no observable effect.
  • messages writes errors to messages.go and constants to internal/constants/ (mismatch vs docs); --dry-run creates empty dirs.
  • test-integration --database doesn't affect helpers.go (always imports all drivers).
  • Exit codes: middleware/config validate/config init/template show/doctor print errors but exit 0 (breaks CI gating).
  • Wide doc drift in wiki/ (Gin vs gorilla/mux, default db, JWT version, file layout).

Note: analyze --output json was reported as polluted but could not be reproduced — it already routes human output to stderr and emits valid JSON on stdout.

🤖 Generated with Claude Code

… imports, error formatting, CI YAML

Cross-cutting compile/vet/test fixes found by exhaustively exercising every
generator command against real projects (init → feature/entity/usecase/
repository/handler/di) across all databases and building the output.

Critical compile breakers (now build+vet+test clean for sqlite, postgres,
mysql, postgres-json, sqlserver, mongodb):

- DI/feature/integrate/test wiring referenced NewPostgres<Entity>Repository for
  every backend, but the repository generator emits NewPostgresJSON…/NewSQLServer…
  /NewMongo… etc. Introduce repoConstructorPrefix(database) and use it in di.go
  (container + Wire set), feature.go and test_integration.go so the generated
  container compiles for every DB instead of only Postgres.
- feature created a new DI container with a hardcoded "postgres" database and
  never threaded the real database through updateDIContainer/addFeatureToDI/
  addSetupMethodsToDI. Thread it through.
- SQLite projects run on GORM (gorm.io/driver/sqlite) so main.go/DI hold a
  *gorm.DB, but the repository was generated with a bespoke database/sql
  (*sql.DB) implementation that could never be injected. Route SQLite through
  the shared GORM "Postgres" generator (as MySQL already is). Remove the now
  dead SQLite-with-fields/finder generators.
- MongoDB main.go exposes mongoClient (*mongo.Client), not db, so the injected
  container scaffold (NewContainer(db)) failed to compile. Derive the
  *mongo.Database from mongoClient when wiring the container.
- usecase DTOs with a time.Time field emitted `time.Time` without importing
  "time" (dto.go: undefined: time). Import "time" when DTOs use it.
- entity unit tests omitted the "time" import for time.Time fields, used an
  invalid composite literal (Priority{}) for the string-based custom-type stubs
  the entity generator emits, and asserted Equal(time.Now(), field) which can
  never pass. Add the import when needed, use a string conversion zero literal,
  and assert the time field is non-zero instead.

Other generator fixes:

- repository implementations for SQLite/SQL Server/DynamoDB/Elasticsearch wrote
  literal `%%w` (escaped percent, so errors were never wrapped) and SQL Server
  FindByID wrote `fmt.Errorf("%s not found")` with no argument — both fail
  `go vet`. Emit `%w` and substitute the entity name.
- `goca ci` generated an invalid test.yml: the step-level `env:` block was
  indented at 6 spaces while sibling step keys use 8, so the workflow failed to
  parse. Fix indentation.
- adding a --cache feature to an existing DI container emitted c.redisClient /
  time references the container did not provide; only wire the cache decorator
  when a decorator file exists and the container has a redisClient field,
  otherwise wire the bare repository so the project always compiles.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sazardev sazardev merged commit 7297d88 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