Skip to main content

eos-scaffold: SP-signature-driven repository scaffolding CLI

backend/tools/Logiswift.Eos.Scaffold (assembly name eos-scaffold) is a dev-only console tool that generates a full Reference CRUD pattern slice — DTO, repository interface + implementation, FluentValidation validator, thin controller — for a new Mas*-style entity by introspecting the real stored procedure signature and table schema, never by hand-transcribing a parameter list. It's not part of any composition root — Api/Workers/Infrastructure never reference it.

Introspection, never a guess

Two real queries feed the generator: sys.parameters/sys.procedures for a manage SP's real parameter list, and INFORMATION_SCHEMA.COLUMNS for the backing table's real column shape. eos-scaffold inspect-sp <name> / inspect-table <name> run either query standalone for reconnaissance.

The connection string is resolved the same sanctioned way as everywhere else in the codebase (ConnectionStringResolver.cs) — --connection-string, then the Api project's own user-secrets store, then appsettings.json. Never read via a shell command.

Schema-drift cross-check against the real scaffolded entity

ScaffoldedEntityInspector.cs does a lightweight regex scan of the actual Persistence/Scaffolded/<Module>/<Entity>.cs file's properties — not just the live table. Any field with no matching scaffolded property is dropped, with a warning naming exactly which columns were dropped, and the scaffolded file's real property name/nullability is taken as ground truth for Map()'s null-coalescing decisions. If the scaffolded file can't be found, the check is skipped with a note to verify by hand.

Conventions applied automatically

  • Active-as-bool: every legacy Mas* table's tinyint Active column becomes bool IsActive on the generated DTO, with the tinyint 0/1 ⇄ bool conversion generated on both read and write sides.
  • [AuditIgnore] heuristic: flags columns whose name contains latitude/longitude/manifestdoc/listdoc/password/secret/ connectionstring/apikey/clientsecret/updatedby/createdby/ modifiedby/changedby — a heuristic, not a certainty; review it like every other generated choice.
  • --strategy StoredProcedure (default) vs --strategy EntityFrameworkCore renders the write path CityRepository-style or ChoiceRepository/CountryRepository-style respectively. [RepositoryWriteStrategyAttribute] is applied to every generated repository automatically.
  • --with-events opts into DomainEvent publishing (off by default); --no-cache and an automatic module-based check (caching only applies when --module Mas) enforce the "lookup tables only, never transactional data" caching rule.
  • Idempotent patchers, not blind appends (DiPatcher.cs/ MenuPermissionPatcher.cs) — insert the new DI-registration line and MenuPermissionNames constant, skipping cleanly on a re-run instead of duplicating a line. No Program.cs patch is needed — AddValidatorsFromAssemblyContaining<ChoiceDto>() already assembly-scans every AbstractValidator<T>.

:::tip This tool produces a starting point, never a finished slice Every run ends with a printed next-steps checklist: confirm the scaffolded entity/DbSet names, read the real SP's full body for its @Result codes and Delete branch's real parameter shape, fill in real sortKey branches once the frontend grid exists, review [AuditIgnore]/required/nullability choices, and add a MAS_MENU seed script for the new constant (the constant is added; no seed script or role grant is ever generated). :::

Still open

  • No Roslyn-based verification — the schema-drift cross-check is a regex scan, not a real parse; an unusual property declaration shape could slip past it silently.
  • No automated test coverage for the generator itself — verified by running it against real SPs/tables and checking the output compiles, not by unit tests.
  • Only Mas*-shaped entities are modeled — a territory-gated entity or an Operations/transactional entity needs its TerritoryFilter/CallerContext/ServiceResult service layer wired up by hand; this tool only ever generates the plain, ungated CRUD pattern.

Reference files

Program.cs, SqlIntrospector.cs, FieldMapper.cs, TypeMapper.cs, ScaffoldedEntityInspector.cs, ScaffoldSpec.cs, ConnectionStringResolver.cs, Generators/DtoGenerator.cs, Generators/RepositoryGenerator.cs, Generators/RepositoryInterfaceGenerator.cs, Generators/ValidatorGenerator.cs, Generators/ControllerGenerator.cs, Generators/DiPatcher.cs, Generators/MenuPermissionPatcher.cs.