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 legacyMas*table'stinyint Activecolumn becomesbool IsActiveon the generated DTO, with thetinyint 0/1 ⇄ boolconversion generated on both read and write sides.[AuditIgnore]heuristic: flags columns whose name containslatitude/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 EntityFrameworkCorerenders the write path CityRepository-style or ChoiceRepository/CountryRepository-style respectively.[RepositoryWriteStrategyAttribute]is applied to every generated repository automatically.--with-eventsopts intoDomainEventpublishing (off by default);--no-cacheand 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 andMenuPermissionNamesconstant, skipping cleanly on a re-run instead of duplicating a line. NoProgram.cspatch is needed —AddValidatorsFromAssemblyContaining<ChoiceDto>()already assembly-scans everyAbstractValidator<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 itsTerritoryFilter/CallerContext/ServiceResultservice 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.