Skip to content

CLI and generators

The gin-kit CLI creates projects, generates building blocks, manages the database, and inspects the running application. Routes are never registered automatically — every generator prints the exact wiring snippet to paste, so application wiring stays explicit and reviewable.

gin-kit new <path> # create a project (interactive, or --non-interactive)
gin-kit run # run the server with .env loaded
gin-kit dev # hot-reload dev server behind a holding proxy
gin-kit build # build a production binary
gin-kit check # read-only: report gofmt drift, run tests and vet
gin-kit doctor # diagnose toolchain, manifest, and database issues
gin-kit routes # boot the app and print the sorted routing table
gin-kit upgrade # standalone: update vendored internal/platform code
gin-kit explain <topic> # architecture | request-flow | database | auth | commands

new defaults to --project-type runtime; use --project-type standalone for the standalone source-visible project type, --auth for the authentication vertical, --oauth (with --auth) for Google and GitHub social sign-in, --example for the tasks example, and --docker for compose files. Non-interactive creation requires --module, --mode, --database, and --orm.

New projects write manifest v3 with project_type: runtime|standalone. Runtime projects also pin runtime_version; the prior selector and runtime import path are intentionally unsupported.

routes boots the application, so it needs a reachable database (SQLite always works) and valid required secrets.

dev rebuilds the server binary on every change, holds requests behind its proxy while a rebuild is in flight, and renders compile errors as a browser overlay until the next successful build; run remains the simple runner.

gin-kit generate resource <Name> --fields "..." [--table name] [--soft-delete]
gin-kit generate client --lang ts [--from URL|file] [--out web/client/api.ts] [--dry-run]
gin-kit generate domain <Name> [--fields ...]
gin-kit generate dto <Name> [--fields ...]
gin-kit generate repository <Name> [--fields ...]
gin-kit generate handler <Name>
gin-kit generate service <Name>
gin-kit generate middleware <Name>
gin-kit generate policy <Name>
gin-kit generate factory <Name> [--fields ...]
gin-kit generate seeder <Name>
gin-kit generate migration <name>
gin-kit generate job <Name> # runtime project type only
gin-kit generate event <Name> # runtime project type only
gin-kit generate mail <Name> # runtime project type only

generate resource is the flagship: it renders a working vertical slice — domain model, request/response DTOs, GORM/sqlx repository (following the project manifest), service that accepts DTOs and returns domain values, HTTP handler with allowlist-based filtering/sorting/pagination, tests with in-memory fakes, and a goose migration with dialect-mapped column types — then prints the exact wiring snippet to paste into internal/app/app.go.

--soft-delete opts the resource into explicit soft deletion: the domain model gains a DeletedAt *time.Time field (hidden from JSON responses), every repository query filters on a visible deleted_at IS NULL condition — no implicit ORM scoping — and Delete becomes an UPDATE that stamps deleted_at instead of removing the row (404 on already-deleted rows). The migration adds the nullable deleted_at column with an index, and deleted_at joins id, created_at, and updated_at as a reserved field name. Only generate resource accepts the flag — the standalone domain, repository, and dto generators always render the plain variants, so regenerate soft-deleting pieces through the resource generator.

generate dto renders just the DTO file for an existing model. generate policy renders an authorization policy in internal/policy — per-action decision methods with placeholder rules and a table test — and works in both project types; standalone projects get the vendored internal/platform/authz package back-filled when it is missing. generate factory creates a model factory with field-aware fake data; generate seeder a registry-based seeder. generate job, generate event, and generate mail scaffold background jobs, typed events, and mailables — they rely on runtime packages, so they are runtime only.

Comma-separated name:type pairs; a trailing ? makes a field nullable. id, created_at, and updated_at are always generated.

Type Go type Column Filter Validation
string string VARCHAR(255) partial match required,max=255 (omitempty,max=255 if nullable)
text string TEXT partial match required (none if nullable)
int / int64 int / int64 INTEGER / BIGINT comparison
float64 (alias float) float64 dialect-mapped comparison
bool bool BOOLEAN exact boolean
time (aliases datetime, timestamp) time.Time TIMESTAMP comparison

Field names containing password, secret, token, or hash are treated as credentials and excluded from the generated response DTO. --table overrides the derived table name.

Generators preflight output paths, refuse accidental overwrites, gofmt in a staging directory, and publish transactionally — a failed render leaves the project untouched. Use --dry-run to inspect intended files. Errors name the failed phase, a stable code, the affected path, and a recovery hint.

Standalone projects vendor their runtime under internal/platform/, so gin-kit upgrade is how they receive platform fixes from newer CLI releases. It re-renders the current CLI’s platform templates for the project’s manifest, then reports each file as up-to-date, outdated (stale vendored copy, safe to update), modified (local edits, kept), differs (no baseline to verify against), missing, or unmanaged (on-disk files the templates no longer render — never touched).

--diff shows unified diffs, --apply writes the safe updates, and --apply --force also overwrites modified files. The .gin-kit.sum checksum baseline distinguishes your edits from stale vendored code — see Upgrade notes for details. Runtime projects upgrade the versioned module instead: go get github.com/Alfian57/gin-kit@vX.Y.Z.

gin-kit db up # migrate to the latest version
gin-kit db down # roll back one migration
gin-kit db status # migration status table
gin-kit db redo # down then up for the last migration
gin-kit db create <name> # create an empty timestamped migration
gin-kit db seed # run the seeder registry
gin-kit db reset --yes # roll back everything (destructive)
gin-kit db fresh --yes # reset, migrate up, then seed (destructive)

reset and fresh refuse to run without --yes. Server, migrate, and seed binaries all load .env first; the real environment always wins. See Seeding and factories for the seeder registry.

gin-kit explain answers questions offline: architecture (the layer flow), request-flow (who binds, who decides, who persists), database (your selected database/ORM and migration workflow), auth (the token model), and commands (the daily loop).

generate client --lang ts creates a deterministic, dependency-free client from OpenAPI JSON or YAML. It emits schema aliases, path/query/body arguments, the canonical API error shape, and an optional bearer-token provider. Runtime projects obtain the document from go run ./cmd/server --openapi; standalone projects read api/openapi.yaml. Pass --from for another file or URL and --out to choose the destination.