revert(design-systems): drop the rulebook import — a migration, not a feature
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 19s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 43s
CI & Build / Build & push image (push) Successful in 44s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 19s
CI & Build / TypeScript typecheck (push) Successful in 32s
CI & Build / Python tests (push) Successful in 43s
CI & Build / Build & push image (push) Successful in 44s
Operator's call, and it corrects a scope error rather than a bug: "this is a path for a user to go from a rulebook to a design system. we don't need to build this path in the app itself ... you should be the one that does the import ... going forward no one else should have to do such a migration." Right. Nobody starting from a design system will ever go rulebook -> system, so the whole path was permanent product code serving a single act on one install. Rule #22: remove it, don't flag it off. Gone from the service, the REST route, the MCP tool, the UI panel, the API client and its tests. There is a second consequence I had missed, and it is the better argument. The parser was WORSE at this than doing it by hand. `propose_tokens` leaves radius steps and type sizes valueless because "Small 4px" is not a hex and nothing here parses it — a limitation I documented carefully and shipped anyway. But that limitation only exists because the importer had to run unattended. Done as work rather than as a feature, those values are just read and written, and the result is a complete design system instead of one with a dozen blanks and a count explaining them. Scaffolding built around my own absence from the loop, when I am the loop. KEPT: `extract_expectations` and `design_expectations` in services/design_rulebook_import.py. The live drift panel still reads them until it is repointed at a resolved design system (#2295), and removing them now would take the /design page's only content with it. They go with that change, not this one.
This commit is contained in:
@@ -342,77 +342,6 @@ async def set_project_design_system(
|
||||
return True
|
||||
|
||||
|
||||
# --- import from a rulebook -------------------------------------------------
|
||||
|
||||
async def import_from_rulebook(
|
||||
user_id: int,
|
||||
design_system_id: int,
|
||||
rulebook_id: int,
|
||||
apply: bool = False,
|
||||
) -> dict | None:
|
||||
"""Propose (and optionally create) tokens for a system from a rulebook.
|
||||
|
||||
Returns None when the caller may not write the system or read the rulebook.
|
||||
Otherwise a report with three lists, and the split between them is the whole
|
||||
point of running it with `apply=False` first:
|
||||
|
||||
proposed — everything the rulebook describes, each entry carrying the
|
||||
rule and sentence it came from
|
||||
created — what was actually written (empty unless `apply`)
|
||||
skipped — proposals whose name the system already defines
|
||||
|
||||
**Existing tokens are never overwritten.** An import is a proposal built by
|
||||
reading prose; a value already in the record was put there deliberately, and
|
||||
a re-run must not undo an operator's correction. That also makes the whole
|
||||
operation safe to repeat — it fills gaps and reports the rest.
|
||||
|
||||
Tokens with no value are still created when `apply` is set. The rulebook
|
||||
names them, so their absence from the system is itself a finding, and a
|
||||
named token with a blank value says "this exists and needs deciding" where
|
||||
silence says nothing at all.
|
||||
"""
|
||||
if not await access.can_write_design_system(user_id, design_system_id):
|
||||
return None
|
||||
|
||||
from scribe.services import rulebooks as rulebooks_svc
|
||||
from scribe.services.design_rulebook_import import propose_tokens
|
||||
|
||||
rules = await rulebooks_svc.list_rules(user_id, rulebook_id=rulebook_id)
|
||||
if not rules:
|
||||
return {"rulebook_id": rulebook_id, "proposed": [], "created": [], "skipped": []}
|
||||
|
||||
proposals = propose_tokens(rules)
|
||||
existing = {t.name for t in await list_tokens(user_id, design_system_id)}
|
||||
|
||||
created: list[dict] = []
|
||||
skipped: list[str] = []
|
||||
for index, proposal in enumerate(proposals):
|
||||
if proposal.name in existing:
|
||||
skipped.append(proposal.name)
|
||||
continue
|
||||
if not apply:
|
||||
continue
|
||||
token = await create_token(
|
||||
user_id,
|
||||
design_system_id=design_system_id,
|
||||
name=proposal.name,
|
||||
value_by_mode=proposal.value_by_mode,
|
||||
group_name=proposal.group_name,
|
||||
purpose=proposal.purpose,
|
||||
supersedes=proposal.supersedes,
|
||||
order_index=index,
|
||||
)
|
||||
if token is not None:
|
||||
created.append(token.to_dict())
|
||||
|
||||
return {
|
||||
"rulebook_id": rulebook_id,
|
||||
"proposed": [p.as_dict() for p in proposals],
|
||||
"created": created,
|
||||
"skipped": skipped,
|
||||
}
|
||||
|
||||
|
||||
# --- the master sheet -------------------------------------------------------
|
||||
|
||||
async def stylesheet_for_system(
|
||||
|
||||
Reference in New Issue
Block a user