Maity: Board

web: import and export as JSON for the legal pages and the registration settings (like the landing editor)

tsk-knb9me77f32t done Maity Coder Claude 003 (maity-coder-claude-003)

Oliver (2026-10-31, after importing Landing V3 with the JSON importer from #808): "kann ich so einen Importer auch für die anderen Pages haben bitte! Legal Pages und Registrierung".

Same pattern as the landing editor (web/js/landing.js:421-500, tsk-36d575f5yybz):

  1. Admin > Legal pages: "Import JSON" / "Export JSON" for the body of PATCH /admin/settings/legal (§16.7.1), or one page's languages. The import validates against the hub's answer (the preview call where there is one), shows the hub's refusals per field, replaces the draft only after a confirmation, and saves nothing until the admin saves; then Preview as today.
  2. Admin > Registration: the same for the body of PATCH /admin/settings/registration (§16.4). No preview there; validate by a dry check if the hub offers one, otherwise show the refusals of the real PATCH and save nothing before the confirmation.
  3. Step-up as the editors already need. Texts in the catalog, smoke, e2e (alone, announced).
  4. A hint when the draft was imported but not loaded, so a preview never flickers silently (Oliver hit this with the landing: "Load" was missing).

No contract change expected; if an endpoint is missing for a dry check, tell A first.

Notes

  1. Maity Coder Claude 003 (maity-coder-claude-003) ·

    Designer JSON PR (seq 22777): file att-txtk60yxafwa (maity files get). A (seq 23273): wait until the designer sends the version with nav_label for the four linked sections, and until Oliver decides #909 vs. the designer's patch (req-vqj43e2bgaff); A will say when.

  2. Maity Coder Claude 003 (maity-coder-claude-003) ·

    F (seq 23339, card tsk-hztv5d16x9g1): after #909 merges F renames .scales-layout to .scales-body; my landing.js part: insert .scales-tablist before .scales-body (const body = grid.closest('.scales-body') || grid; body.parentNode.insertBefore(list, body)), stacked on F's follow-up branch (F will name it); test shim needs closest(). Ring activation from #911 unchanged.