Skip to content

[auth 7] Build generic forms and generated profile/account UI #195

Description

@artiphishle

Roadmap: #188

Respect the [auth] roadmap first and the AGENTS.md file of every repository touched.

Previous roadmap step

[auth 6] (#194) establishes canonical identity, editable profile, account operations and auth/profile binding contracts. This issue builds the reusable form capability and uses profile/account UI as its first production consumer.

Repository impact

Likely:

  • ankhorage/contracts
  • ankhorage/runtime
  • ankhorage/zora
  • ankhorage/surface only if reusable layout/input foundations are missing
  • ankhorage/studio

Pause at package release boundaries. Contracts own serializable form definitions, Runtime owns state/action execution, ZORA renders controls/patterns, and Studio generates/authors them. Do not put form state machines into ZORA components or profile business logic into Studio-only controls.

Goal

Build one generic, provider-neutral form architecture and generate a complete profile/account experience from canonical Auth configuration.

The form system must be reusable for future generated app forms, Properties/admin authoring and API-backed workflows. The profile page is not a one-off hardcoded Supabase form.

Architecture

@ankhorage/contracts
  -> FormSpec / FieldSpec / validation / submit-action contracts

@ankhorage/runtime
  -> form state
  -> initial binding resolution
  -> validation lifecycle
  -> event/action execution

@ankhorage/zora
  -> accessible cross-platform controls and form renderer/pattern

@ankhorage/studio
  -> generation/configuration
  -> profile/account route and chrome integration

Generic form requirements

Field model

Support a deliberate initial set with extensibility:

  • text;
  • email;
  • password;
  • number;
  • textarea;
  • select;
  • checkbox/switch;
  • date where cross-platform semantics are production-ready;
  • image/avatar selector through the canonical media capability when available.

Do not include a field merely because an HTML input type exists. Each field requires Web/iOS/Android semantics, accessibility and validation.

Form state

One canonical runtime model must cover:

  • initial values;
  • current values;
  • dirty/touched state;
  • field/form errors;
  • loading/submitting/success/failure;
  • reset/cancel;
  • disabled/read-only/visibility bindings;
  • server/adapter error mapping;
  • deterministic duplicate-submit prevention.

Validation

Support serializable validation where appropriate:

  • required;
  • min/max length;
  • numeric min/max;
  • pattern/format;
  • field equality/dependency, e.g. password confirmation;
  • custom operation/action-backed validation only through explicit runtime contracts.

Client validation improves UX but must not pretend to replace backend validation.

Bindings and actions

  • initial values resolve through canonical binding sources, including auth and profile;
  • submit emits the canonical form.submit event payload;
  • event/action bindings invoke neutral profile/account actions from [auth 6];
  • no direct Supabase calls in form components;
  • sensitive password values are not persisted in generic app state or diagnostics;
  • action results map back to fields/form state consistently.

Generated profile/account UI

Configuration-driven fields

Generate visible/editable fields from canonical Auth/Profile configuration.

Examples:

Read-only identity:
  email

Editable profile:
  displayName
  firstName
  lastName
  avatarUrl

Dedicated account forms/actions:
  change email
  change password
  sign out
  delete account

A password entry in profile configuration must never display an existing value. It produces only an appropriate write-only account action/form.

Profile route and access

Generate a canonical authenticated profile/account route with:

  • route guard;
  • loading/error/unsupported states;
  • profile form;
  • account/security actions according to adapter capabilities;
  • sign-out;
  • explicit destructive confirmation for account deletion.

The exact route is configurable/canonical and must not collide with app-owned routes.

Account entry placement

Allow configuration for an account entry such as:

  • avatar/button in app header/top bar;
  • navigator entry;
  • both where intentionally configured;
  • hidden UI while route remains programmatically available only when explicitly allowed.

Use the normalized avatar/display-name/email fallback chain. Do not couple account chrome to Google metadata.

UI generation/authoring relationship

Generated profile/account UI should be represented through canonical screens/nodes/forms/bindings where practical, not an opaque uneditable hardcoded React island.

Coordinate with [adm] ownership:

  • [adm 2] authoring metadata must remain canonical for component/form authorability;
  • [adm 6] binding authoring should consume the same form events/binding contracts rather than creating another form-binding model;
  • do not block the functional generated profile page on the complete future authoring UI where canonical specs can already be generated safely.

Likely files

Contracts, non-exhaustive:

src/types.ts
src/bindings.ts
src/forms.ts (new if appropriate)
src/*form*.test.ts

Runtime:

src/forms/*
src/bindings/*
src/actions/*

ZORA:

src/components/*Input*/
src/patterns/Form*/
src/metadata/*
src/registry.ts

Studio:

src/host/layout/templates/auth/*
src/host/layout/*
src/ui/admin/pages/AuthAdminPage.tsx
src/manifestState.ts

Exact files must be confirmed from current repository structures.

Phases

Phase 1 — serializable form contracts

Define fields, validation, initial bindings, events and action/result contracts with strict tests.

Phase 2 — Runtime form engine

Implement state, validation, binding resolution, submission lifecycle and secure sensitive-value handling.

Phase 3 — ZORA renderer/patterns

Add accessible cross-platform rendering and metadata without embedding backend/profile behavior.

Phase 4 — generated profile/account experience

Generate configured route, account entry, profile form and capability-driven account actions.

Phase 5 — authoring/runtime hardening

Ensure canonical specs are compatible with existing/future Studio Properties/Bindings workflows and remove any duplicate legacy auth forms.

Tests

Cover at minimum:

  • field/validation contract parsing and serialization;
  • initial auth/profile binding resolution;
  • dirty/touched/error/submitting transitions;
  • sync and adapter/server error mapping;
  • duplicate submit protection;
  • password values never persist/log;
  • ZORA renderer field mapping/accessibility metadata;
  • configured profile fields appear with correct read-only/editable semantics;
  • update profile invokes neutral capability;
  • change email/password use dedicated account actions;
  • unsupported actions remain hidden/diagnostic rather than failing at runtime;
  • avatar/account-entry fallback behavior;
  • route guard and sign-out/delete confirmation behavior;
  • fake non-Supabase adapter works with the same generated UI.

Acceptance criteria

  1. One canonical generic form contract/runtime exists.
  2. ZORA renders forms without owning backend/profile logic.
  3. Initial values and submissions use canonical bindings/actions.
  4. Passwords remain write-only and are never restored from session/profile state.
  5. Profile/account UI is generated from Auth configuration.
  6. Identity fields, editable profile fields and security actions are presented correctly.
  7. Account entry placement/avatar behavior is configurable and provider-neutral.
  8. Unsupported adapter capabilities are handled honestly.
  9. The form/profile architecture is reusable by future app/admin authoring rather than a one-off screen.
  10. Behavior-focused tests, package releases/changesets and full validation pass.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions