Nimblesite / Nimblesite/typeDiagram
[CRITICAL] Express field metadata (constraints, defaults, descriptions, aliases, config) so generated DTOs need zero hand-maintenance
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 63
- Forks
- 4
- PR merge metrics
- No merged PRs in 30d
Description
Make typeDiagram a complete single source of truth for API DTOs — full requirements
Companion to #38 (scalar types) and #29 (optional-vs-null). This is the complete list of what a contract-first DTO generator must express so consumers never hand-maintain a parallel copy. Every item below is something we currently CANNOT put in the .td and are therefore forced to hand-write in Python (Pydantic) — which then drifts from the contract. Each maps cleanly to Pydantic Field(...), C# DataAnnotations/JSON attributes, and OpenAPI.
1. Field-level constraints (validation metadata) — HIGHEST PRIORITY
Real fields we hand-maintain solely for these:
| our field | needed metadata |
|---|---|
ChatRequest.message |
min_length=1, max_length=100_000 |
SshKeyRequest.public_key |
min_length=1, max_length=10_000 |
BundleFileWriteRequest.content |
max_length=2_000_000 |
ConversationSummary.message_count |
ge=0 |
ToolFileWriteRequest.mode |
ge=0, le=0o777 |
Manifest.build_command |
min_length=1, max_length=1000 |
Proposed syntax (attributes on the field):
type ChatRequest {
message: Option<String> @minLen(1) @maxLen(100000)
}
type ConversationSummary {
message_count: Int @min(0)
}
Constraint vocabulary: @minLen/@maxLen, @min/@max (inclusive), @exclusiveMin/@exclusiveMax, @multipleOf, @pattern("regex").
Lowering: Pydantic Field(min_length=, max_length=, ge=, le=, gt=, lt=, multiple_of=, pattern=); C# [MinLength]/[MaxLength]/[Range]/[RegularExpression]; OpenAPI minLength/maxLength/minimum/maximum/pattern.
2. Explicit default values (not just Option→null)
Fields whose default is a non-null literal — currently un-expressible:
ToolEntry.method = "POST", Manifest.template_dir = "template", ProvisionRequest.workspace_git_push_mode = "manual_only", ToolResultIn.ok = true.
type ToolEntry { method: String @default("POST") }
Lowering: Pydantic field default; C# property initializer; OpenAPI default.
3. String formats
@format(email|uri|uuid|date-time|hostname|ipv4|ipv6|byte) → Pydantic EmailStr/AnyUrl/Field(pattern=...), OpenAPI format.
4. Field descriptions / doc comments
Doc comments must survive into the output (Pydantic Field(description=...), C# XML ///, OpenAPI description). Example we hand-maintain: MessageResponse.tool_calls has a paragraph explaining the content/tool_calls split.
type MessageResponse {
/// Tool calls emitted this turn, separate from `content` so UIs can hide tool activity.
tool_calls: List<ToolCallOut>
}
5. Field aliases (wire name ≠ language name)
We have from_: str = Field(alias="from", serialization_alias="from") because from is a Python keyword. Need @alias("from") → Pydantic alias + populate_by_name, C# [JsonPropertyName].
6. Model-level config
@extra(forbid|ignore|allow), @frozen. We use extra="forbid" on request DTOs to reject typos (ConversationSummary, WorkspaceInstanceSummary) and extra="ignore" elsewhere. Lowering: Pydantic model_config = ConfigDict(extra=, frozen=); C# record immutability / JsonExtensionData.
7. @example(...) and @deprecated
For OpenAPI/docs quality: per-field examples and a deprecation marker.
8. (from #38) native DateTime/Uuid/Decimal scalars + fail-closed on unknown type identifiers.
Why this is critical infrastructure
With items 1–6 NAP can delete its entire hand-written DTO module and generate 100% from the .td. Without them, every constrained/aliased/defaulted/documented field forces a hand copy, the hand copy drifts, and we ship incidents (the conversation-history leak we just fixed was exactly this failure mode). We will adopt a patch build the moment 1, 2, and 4 land — those three remove ~90% of our hand-maintenance.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing .td syntax and the lowering requirements for Pydantic, C# attributes, and OpenAPI described here; review #38 and #29 for related scalar and optional/null behavior. Done means the requested field constraints, defaults, and doc comments can be expressed in the contract and preserved in generated DTO outputs, with the remaining metadata requirements clearly covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, openapi, python, typescript
- Domain
- backend-api-design, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100