Context Mapping & Additional Generators¶
Two related features:
- Context parameter mappings — map database parameters (like
user_id,created_by,tenant_id) to a context object, so they don't clutter every call site. - Additional generators — generate extra outputs (TypeScript, providers, controllers, …) from the same metadata, in one pass.
Context parameter mappings¶
The problem¶
Many database functions require authentication/context parameters — userid, tenantid, createdby, and so on. Passing them explicitly at every call is noisy and error-prone. Instead, map them to a context object.
Configuration¶
{
"UseUserContext": true,
"UserContextParameterName": "ctx",
"UserContextType": "UserContext",
"ContextParameterMappings": [
{ "ParameterNames": ["userid"], "ContextPath": "User.UserId" },
{ "ParameterNames": ["displaylanguagecode"], "ContextPath": "Locale" },
{ "ParameterNames": ["createdby", "updatedby", "deletedby"], "ContextPath": "Username" },
{ "ParameterNames": ["tenantid"], "ContextPath": "SelectedTenant.TenantId" }
]
}
What it changes¶
Template access¶
Each routine exposes the split between context and regular parameters:
{{range $routine := .Functions}}
{{- if $routine.UsesUserContext}}
{{range $param := $routine.ContextParameters}}
// context: {{$param.PropertyName}} -> {{$param.ContextPath}}
{{end}}
{{range $param := $routine.RegularParameters}}
// regular: {{$param.PropertyName}}
{{end}}
{{- end}}
{{end}}
Language-agnostic¶
The configuration provides data; templates decide the syntax:
Additional generators¶
The problem¶
Previously you needed a separate tool (e.g. a C# model generator) to produce TypeScript models, providers, or other code. db-gen can generate all of it in one pass, reusing its internal metadata.
Configuration¶
{
"AdditionalGenerators": [
{
"Name": "TypeScript",
"Enabled": true,
"Template": "./templates/typescript.gotmpl",
"OutputFolder": "./output/typescript",
"FileExtension": ".ts",
"FileCase": "camelcase",
"GenerationType": "per-routine"
},
{
"Name": "Provider",
"Enabled": true,
"Template": "./templates/provider.gotmpl",
"OutputFolder": "./output",
"FileName": "CommonProvider.cs",
"GenerationType": "single-file"
}
]
}
Generation types¶
| Type | Template data | Output | Use for |
|---|---|---|---|
per-routine |
ModelTemplateData (one Routine) |
one file per routine, named routine + FileExtension |
TypeScript interfaces, individual controllers |
single-file |
DbContextData (all Functions) |
one file named FileName |
CommonProvider, SignalR hub, aggregated index |
If GenerationType is omitted, db-gen infers single-file when FileName is set, otherwise per-routine.
| Option | Required | Description |
|---|---|---|
Name |
yes | Display name for logging |
Enabled |
yes | Enable/disable |
Template |
yes | Path to the .gotmpl file |
OutputFolder |
yes | Where to write |
FileName |
for single-file | Output file name |
FileExtension |
for per-routine | Output extension |
FileCase |
optional | snakecase / camelcase / pascalcase |
GenerationType |
optional | per-routine / single-file (auto-detected) |
CleanOutputFolder |
optional | Delete the output folder before generating |
Example templates¶
public class CommonProvider
{
{{range $routine := .Functions}}
public async Task<List<{{$routine.ModelName}}>> {{$routine.FunctionName}}Async(
{{if $routine.UsesUserContext}}{{$.Config.UserContextType}} {{$.Config.UserContextParameterName}}{{end}}
{{range $param := $routine.RegularParameters}}, {{$param.PropertyType}} {{$param.PropertyName}}{{end}})
{
return await dbContext.{{$routine.FunctionName}}Async(
{{range $param := $routine.Parameters}}
{{if $param.IsContextParameter}}{{$.Config.UserContextParameterName}}.{{$param.ContextPath}}{{else}}{{$param.PropertyName}}{{end}},
{{end}});
}
{{end}}
}
Why it's powerful¶
- Single source of truth — database functions drive every output.
- No re-parsing — uses db-gen's internal structures directly.
- Consistency — all outputs match the database schema.
- Extensibility — add a generator without changing code.
The same mechanism can produce ASP.NET controllers, SignalR hubs, Phoenix channels, GraphQL schemas, OpenAPI specs, test fixtures, or client SDKs in any language.