Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-4229Blocked

(motir-core) The Public address pane, part 2 — the custom-domain list: add with DNS instructions, verify, every certificate state, make primary, remove, the tier upsell; en + zh

The second half of the pane — the custom-domain list that renders in the slot part 1 left: add a domain and see the records to create, verify it, watch every certificate state with an action beside it, make one primary, remove one, and meet the tier gate honestly. Built to the design panels 3, 3b, 4, 5, 6, 7 and 9, over the lifecycle's routes, showing what the status job last wrote.

What ships

  • _components/CustomDomainsSection.tsx replaces part 1's stub: the Card with the list of PublicAddressDto rows, Add a domain, and — per row — the hostname, a status Pill, lastCheckedAt, and the row's actions.
  • The state set, total (panel 5): a Record<PublicAddressStatus, { tone, labelKey, hintKey, actions }> — a compile error when the enum grows — mapping unverified (show the records · re-check · remove), verifying (re-check · remove), pending_certificate (waiting copy, re-check · remove), issued (make primary · remove), failed (the failureReason · show the records · re-check · remove), expired and revoked (the reason · re-check · remove); active and alias never appear in this list (they are the subdomain's) and the map says so.
  • Add (panel 4): a Modal — hostname InputPOST …/public-addresses → the DNS-instruction block from the DTO (verification TXT and dns records, each name / value with a copy button; the apex-vs-subdomain shape follows what the DTO returns), Verify nowPOST …/verify, I'll do this later closes with the row left unverified.
  • Verify / re-checkPOST …/verify; Make primary (panel 6) → POST …/primary, enabled only on issued rows with the Tooltip otherwise, and the every other address redirects here consequence line; Remove (panel 7) → DELETE, the archive-confirm grammar.
  • The tier gate (panel 3b): when POST answers the billing surface's entitlement-exceeded shape with entitlement: 'custom_domains', render the shipped upgrade prompt (the 8.1.7 / 8.1.8 component — compose it, do not redraw it) — and, when the org's tier allows zero, render Add a domain disabled with the same prompt before any request.
  • Liveness: while any row is verifying or pending_certificate, re-read the list every 30 s (the client-island tick — CLAUDE.md's page-state-after-mutation routing) so the pane shows the job's writes without a reload; stop when no row is pending.
  • Copy and i18nsettings.publicAddress.domains.* in en.json and zh.json; the parity test.
  • Tests: every status value rendered from a fixture (a table-driven test over the enum, asserting the map is total); the add flow's three exits; make-primary disabled on non-issued; the entitlement prompt from the route's shape; the 30 s tick starts and stops with the pending set; i18n parity.

Boundary

No service or route change, no subdomain UI (part 1), no design change. Nothing outside motir-core.

Acceptance criteria

  • Each of the seven customer-domain statuses renders the pill, hint and action set the design's panel 5 draws, from fixtures, in a table-driven test; the map is a total Record over PublicAddressStatus.
  • Adding a domain shows the exact TXT and pointing records the DTO carries with working copy buttons, and Verify now moves the row's state without a reload; a cap refusal renders the shipped upgrade prompt.
  • Make primary is enabled only for issued rows; after it, that row reads primary and the consequence line is shown; Remove asks for confirmation and removes the row.
  • While a row is pending, the list re-reads on the tick and reflects a state the job wrote; the tick stops once nothing is pending (asserted with fake timers).
  • Every string is in both catalogues; the parity test is green; the per-file coverage floor holds; no file outside motir-core is touched.

Context refs

  • the design — panels 3, 3b, 4, 5, 6, 7, 9; motir-core/design/projects/public-address.mock.html
  • the lifecycle — the DTO and the five routes; the entitlement — the refusal shape; the status job — where the states come from
  • motir-core/app/(authed)/settings/project/members/_components/ProjectMembersSettings.tsx — optimistic writes, toasts, the confirm grammar; the billing upgrade-prompt component (8.1.7 / 8.1.8)
  • motir-core/messages/en.json · messages/zh.json; motir-core/CLAUDE.md — component + token reuse, the client-island tick