## Fixes#20084
### Problem
A saved address is visible in the **table view** but shows **"Empty"**
in the **record detail page** when `addressStreet1` is `null`.
This reproduces with the default seed data out of the box — e.g.
**Google** (city "Mountain View", no street), **Microsoft** (Redmond),
**Meta** (Menlo Park) — which is why several users reported hitting it
immediately.
### Root cause
The frontend zod schema required `addressStreet1` to be a **non-null**
string:
```ts
// isFieldAddressValue.ts
export const addressSchema = z.object({
addressStreet1: z.string(), // ← required non-null
addressStreet2: z.string().nullable(),
...
});
```
…but the backend composite type marks it `isRequired: false`
(`address.composite-type.ts`), and the DB column is nullable. So the API
legitimately returns `addressStreet1: null` when only other subfields
are filled.
The two views diverge on how they render:
- **Record detail** gates the value behind `useIsFieldEmpty()` →
`isFieldValueEmpty()`, which for addresses calls
`isFieldAddressValue()`. With `addressStreet1: null` the `safeParse`
**fails**, so `isFieldValueEmpty` returns `true` and the `"Empty"`
placeholder is shown (`RecordInlineCellDisplayMode`).
- **Table view** (`RecordTableCellDisplayMode`) renders
`AddressFieldDisplay` directly with **no** empty check, so the address
stays visible.
This was a latent mismatch since the address guard was introduced.
### Fix
Make `addressStreet1` nullable to match the backend and the other
subfields:
- `addressSchema` → `addressStreet1: z.string().nullable()`
- `FieldAddressValue.addressStreet1` → `string | null`
- `FieldAddressDraftValue.addressStreet1` → `string | null` (keeps the
input/draft type consistent; the text input already renders `?? ''`)
The change is strictly more permissive — persisting and the settings
default-value form still accept string values; they now also accept
`null`.
### Tests
- `isFieldAddressValue.test.ts` — guard returns `true` for
`addressStreet1: null` with other subfields filled.
- `isFieldValueEmpty.test.ts` — new address coverage: empty address is
empty; **`street1: null` + city filled is NOT empty**; normal address is
not empty. (Added an `addressFieldDefinition` mock.)
Both new assertions were confirmed to **fail before the fix** and pass
after.
### Verification
- `npx jest isFieldValueEmpty isFieldAddressValue
normalize-address-field-value-for-persist` → 17 passed
- `npx nx typecheck twenty-front` → pass
- `npx nx lint:diff-with-main twenty-front` → 0 warnings, 0 errors