effect-form-e2elisted
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