← ClaudeAtlas

effect-form-e2elisted

Use when adding or changing a form, a field's validation rules, or a Playwright test in this repository. Covers why a form is effect-form and lives in the app rather than the design system, declaring field rules once in the contract, telling a validation failure apart from a refusal, and the e2e harness's rules — a user per test, waiting on a condition rather than sleeping.
vantionlabs/saas-starter · ★ 6 · Testing & QA · score 73
Install: claude install-skill vantionlabs/saas-starter
# A write is a form, and a form is effect-form `FormReact.make` over a `FormBuilder`, living in the **app** rather than in `@vantion/ui`. The library binds the submit into the form definition, so a shared presentational component taking `onCreate` as a prop cannot be one. `apps/design` renders plain inputs for the layout, because validation and submit state are the part of a form that has nothing to do with how it looks. That also _removes_ a problem rather than managing it: effect-form does not render its fields during SSR, so there is no window in which somebody can type into a control that is not listening. ## A field's rules are declared once, in the contract `ContactFields` in `ContactRpc.ts` is what the `CreateContact` payload is built from **and** what the form validates with, so the form refuses exactly what the server would. ```ts export const ContactFields = { fullName: Schema.String.check(Schema.isNonEmpty({ message: "Enter a name." })), }; ``` Every check carries a `message`, because that is what a person reads. They were two declarations of one rule once — the procedure checked `isNonEmpty` with no message while the screen kept a readable copy — and the server's was the version nobody could read. For a rule a regex cannot express, `Schema.makeFilter` returns a sentence or `undefined`. `EndpointFields.url` is the worked example, and the rule it enforces is the difference between a webhook form and server-side request forgery. ## A failed submit is two di