added traits and include features with docs

This commit is contained in:
2026-05-20 19:10:29 -04:00
parent a32cb3a4da
commit 56775c8c1b
8 changed files with 657 additions and 91 deletions

View File

@ -179,7 +179,37 @@ In the Punc architecture, filters are automatically synthesized, strongly-typed
* **Inherited Properties**: Filters automatically inherit all valid database columns from their base type schema, immediately converting them to their respective `.condition` schemas.
* **Relational Proxies**: If a table has a foreign key to another table, the filter automatically generates a proxy property pointing to the related entity's filter (e.g., the `person` filter automatically gains an `organization` property that points to `organization.filter`), allowing infinitely deep nested queries natively.
* **Logical Operators (`$and`, `$or`)**: Every filter automatically includes `$and` and `$or` arrays, which recursively accept the exact same filter schema, allowing complex logical grouping.
* **Ad-Hoc Extensions (`ad_hoc`)**: Fields stored purely in JSONB bubbles that lack formal database columns can still be queried using the `ad_hoc` object, which passes standard, unvalidated string conditions.
* Ad-Hoc Extensions (`ad_hoc`)**: Fields stored purely in JSONB bubbles that lack formal database columns can still be queried using the `ad_hoc` object, which passes standard, unvalidated string conditions.
### Trait-Based Schema Composition (`traits` & `include`)
Traits are reusable, non-generating schema fragments used to share properties and relationships horizontally across multiple schemas. They do not generate separate Go/Dart classes.
* **Traits Namespace**: Defined in a sibling `"traits"` block next to `"schemas"` inside table comments:
```json
"traits": {
"emailable": {
"properties": {
"email_addresses": {
"type": "array",
"items": { "type": "contact", "properties": { "target": { "type": "email_address" } } }
}
}
}
}
```
* **Include Keyword**: Schemas or traits can use the `"include"` array to compose traits or other schemas:
```json
"full.person": {
"type": "person",
"include": ["contactable", "owner"]
}
```
* **Resolution and Merging**: During `Database::new()`, includes are resolved and merged at the raw JSON level:
* **`properties` / `patternProperties`**: Map keys from the host schema override/shadow included traits.
* **`required` / `display`**: Lists are merged and deduped.
* **`dependencies`**: Merged by combining and deduping lists.
* **Scalars / Arrays / Items**: Host definitions completely override included traits.
* The `"include"` keyword is stripped, and `"traits"` maps are omitted from serialization.
---