feat(hint): clause-concept hints layered on F1 (issue #37)
Add a hint.concept.* tier-3 layer surfaced when the cursor sits inside a recognized clause (referential actions, 1:n/m:n cardinality, primary key, unique, check, foreign key), layered beneath the per-form block. New Node::Concept grammar wrapper records clause byte-spans; concept_topic_at_cursor resolves the innermost containing span. Examples are mode-keyed so they stay syntax-correct in both simple and advanced mode. Draft ADR (number at merge).
This commit is contained in:
@@ -237,9 +237,39 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[
|
||||
("hint.ambient_expected", &["expected"]),
|
||||
("hint.getting_started", &[]),
|
||||
("hint.block.heading", &[]),
|
||||
("hint.block.concept_heading", &[]),
|
||||
("hint.block.what", &[]),
|
||||
("hint.block.example", &[]),
|
||||
("hint.block.concept", &[]),
|
||||
// Clause-concept blocks (issue #37 / clause-concept-hints D5).
|
||||
// Both-mode topics carry a mode-keyed `example` (simple + advanced);
|
||||
// single-mode topics carry a plain `example`. The comprehensiveness
|
||||
// test (CONCEPT_TOPICS) enforces this shape per topic.
|
||||
("hint.concept.referential_actions.what", &[]),
|
||||
("hint.concept.referential_actions.example.simple", &[]),
|
||||
("hint.concept.referential_actions.example.advanced", &[]),
|
||||
("hint.concept.referential_actions.concept", &[]),
|
||||
("hint.concept.cardinality_one_to_many.what", &[]),
|
||||
("hint.concept.cardinality_one_to_many.example", &[]),
|
||||
("hint.concept.cardinality_one_to_many.concept", &[]),
|
||||
("hint.concept.cardinality_many_to_many.what", &[]),
|
||||
("hint.concept.cardinality_many_to_many.example", &[]),
|
||||
("hint.concept.cardinality_many_to_many.concept", &[]),
|
||||
("hint.concept.primary_key.what", &[]),
|
||||
("hint.concept.primary_key.example.simple", &[]),
|
||||
("hint.concept.primary_key.example.advanced", &[]),
|
||||
("hint.concept.primary_key.concept", &[]),
|
||||
("hint.concept.unique.what", &[]),
|
||||
("hint.concept.unique.example.simple", &[]),
|
||||
("hint.concept.unique.example.advanced", &[]),
|
||||
("hint.concept.unique.concept", &[]),
|
||||
("hint.concept.check.what", &[]),
|
||||
("hint.concept.check.example.simple", &[]),
|
||||
("hint.concept.check.example.advanced", &[]),
|
||||
("hint.concept.check.concept", &[]),
|
||||
("hint.concept.foreign_key.what", &[]),
|
||||
("hint.concept.foreign_key.example", &[]),
|
||||
("hint.concept.foreign_key.concept", &[]),
|
||||
// Tier-3 teaching blocks (ADR-0053 D3) — Phase-B exemplars.
|
||||
("hint.cmd.insert.what", &[]),
|
||||
("hint.cmd.insert.example", &[]),
|
||||
|
||||
@@ -426,9 +426,58 @@ hint:
|
||||
# `what` / `example` / `concept` parts render under.
|
||||
block:
|
||||
heading: "Hint"
|
||||
# Sub-heading for the clause-concept block layered beneath the
|
||||
# per-form block when the cursor sits inside a recognized clause
|
||||
# (issue #37 / clause-concept-hints D6).
|
||||
concept_heading: "About this clause"
|
||||
what: "What"
|
||||
example: "Example"
|
||||
concept: "Concept"
|
||||
# ── Tier-3 clause-concept blocks (issue #37 / clause-concept-hints) ─
|
||||
# Surfaced by F1 when the cursor sits inside a recognized clause,
|
||||
# layered on top of the per-form `hint.cmd.*` block. Same
|
||||
# `what`/`example`/`concept` shape; topics reachable in BOTH modes
|
||||
# carry a mode-keyed `example` (`simple` + `advanced`) so the example
|
||||
# is syntax-correct for the mode the user is actually in (ADR-0053 D6).
|
||||
# Single-mode topics carry one plain `example`. Copy rules: no engine
|
||||
# name; "simple mode"/"advanced mode", never "DSL".
|
||||
concept:
|
||||
referential_actions:
|
||||
what: "Decide what happens to a child row when the parent it points at is deleted, or its key changes."
|
||||
example:
|
||||
simple: "add 1:n relationship from Customers.id to Orders.customer_id on delete cascade"
|
||||
advanced: "create table Orders (id int primary key, customer_id int references Customers(id) on delete cascade)"
|
||||
concept: "A foreign key forbids orphans by default (restrict — the delete is refused). `cascade` deletes the children along with the parent; `set null` keeps the children but clears their link. The action you pick encodes a real rule about your data."
|
||||
cardinality_one_to_many:
|
||||
what: "Link two tables so one parent row can own many child rows."
|
||||
example: "add 1:n relationship from Customers.id to Orders.customer_id"
|
||||
concept: "\"1:n\" is one parent, many children — one customer, many orders. The child table holds a foreign key column pointing back at the parent; that shared value is what groups a parent's children together."
|
||||
cardinality_many_to_many:
|
||||
what: "Link two tables when rows on each side can relate to many rows on the other."
|
||||
example: "create m:n relationship from Students to Courses"
|
||||
concept: "\"m:n\" — many students take many courses — can't be stored as one foreign key. A junction table sits between them, holding one row per pairing; it is created for you, turning the m:n into two 1:n links."
|
||||
primary_key:
|
||||
what: "Mark the column (or columns) that uniquely identify each row."
|
||||
example:
|
||||
simple: "create table Customers with pk id(serial), Name(text)"
|
||||
advanced: "create table Customers (id int primary key, Name text)"
|
||||
concept: "A primary key is the row's identity: every row must have one, and no two rows may share it. Other tables point at this key to reference the row. List several columns for a compound key when one column isn't unique on its own."
|
||||
unique:
|
||||
what: "Require that no two rows share the same value in this column."
|
||||
example:
|
||||
simple: "create table Customers with pk id(serial), Email(text) unique"
|
||||
advanced: "create table Customers (id int primary key, Email text unique)"
|
||||
concept: "Like a primary key, `unique` forbids duplicates — but a table has one primary key (its identity) and may have many `unique` columns (e.g. email, username). Unlike the primary key, a unique column may usually be left empty."
|
||||
check:
|
||||
what: "Attach a rule each row must satisfy before it can be saved."
|
||||
example:
|
||||
simple: "create table Products with pk id(serial), Price(decimal) check (Price >= 0)"
|
||||
advanced: "create table Products (id int primary key, Price decimal check (Price >= 0))"
|
||||
concept: "A check guards the data at write time: any insert or update that breaks the rule is refused, so invalid rows never reach the table. Use it to enforce real-world constraints — a non-negative price, a rating between 1 and 5."
|
||||
foreign_key:
|
||||
what: "Make this column point at a row in another table."
|
||||
example: "create table Orders (id int primary key, customer_id int references Customers(id))"
|
||||
concept: "A foreign key is a promise that every value here matches a real row in the parent table — no orphaned references. The parent must exist before the child can point at it; an `on delete`/`on update` action decides what happens when that parent later changes."
|
||||
# ── Tier-3 teaching blocks (ADR-0053 D3) ──────────────────────────
|
||||
# Per-form command hints (`hint.cmd.<form>`) and per-class error
|
||||
# hints (`hint.err.<class>`), each a `what` (1–2 sentences) / `example`
|
||||
|
||||
Reference in New Issue
Block a user