model-form-root

Builds model edit forms by extending BaseUI with schema-seeded reactive $root state.

1|Updated Jun 25, 2026
One-click install
npx skills add https://github.com/IgorAIvanov/altera03 --skill model-form-root-igoraivanov
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: model-form-root
Source: https://github.com/IgorAIvanov/altera03/tree/main/skills/src/model-form-root
Command: npx skills add https://github.com/IgorAIvanov/altera03 --skill model-form-root-igoraivanov

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Hand-writing empty-object literals, transport calls, and per-form loading flags in every screen leads to duplicated logic, drift between SQL defaults and client state, and bugs like duplicate record creation when an entity is missing. This Skill defines the shared $root data contract and BaseUI API so every list, picker, and form behaves consistently. ## Core Features & Use Cases - Schema-seeded reactive state: $root is seeded from the TypeBox schema via Value.Create, so every field exists before first render and no empty-object literals are needed. - Unified envelope handling: run, loadInto, and assign unwrap the SQL { ok, data, messages } envelope, drive running/messages state, and skip top-level null so a missing record never wipes the form. - Declarative validation: fieldRules() declares required and conditional checks in the form, with server-side field errors highlighted automatically. - Use Case: Create a bank catalog edit form by extending BaseUI<BankEditRoot>, passing BankEditRootSchema to super(), loading with loadInto("get", { id }), and rendering fields with bindTo and renderNotice — no manual state or bus.request calls. ## Quick Start Ask the AI to create an edit form for a catalog model named bank with fields code and name, extending BaseUI with a schema-seeded $root and a Save button wired to trySave.

Frequently Asked Questions about model-form-root

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a model edit form with BaseUI?

Extend BaseUI<YourRoot>, set model and primaryKey = "item", pass the root schema via constructor super(YourRootSchema), and load records with loadInto("get", { id }). Render fields with bindTo and renderNotice, and wire Save to trySave.

How do I declare conditional required fields in a form?

Override fieldRules() in the form and return rules that read $root, for example making a field required only when another field has a specific value. Precedence is inline renderField options, then fieldRules(), then the TypeBox schema default.

Why does assign() skip top-level null values?

The SQL envelope always carries all data keys with null for unused ones, so top-level null means no data for that key, not clear it. Skipping null prevents a get of a deleted record from wiping the schema-seeded $root.item and crashing the render.

Why must the schema be passed through the constructor instead of a property?

Subclass field initializers run after super(), so an abstract schema property is still undefined when the base constructor reads it. Passing the schema as a constructor argument, super(BankEditRootSchema), guarantees it is available for Value.Create seeding.

What happens when a record is not found versus creating a new record?

A new record sends no get request and notFound stays false, while a missing record returns item: null, sets notFound true, and blocks saving via canSave. Setting primaryKey = "item" prevents silently creating a duplicate record with a null id.

When should I use loadInto instead of run in a form?

Use loadInto for loading records in forms because it combines run with a not-found check and assign, returning false and setting notFound when the primary key comes back null. Raw run is reserved for commands like save that do not need the not-found semantics.