# User

> User profile with role-based access, optional address, and create/update variants.

- Name: `user`
- Categories: auth
- Depends on: `@open-types/address`
- Detail page: https://open-types.dev/types/user

## Install

```bash
# Types only
npx shadcn add @open-types/user

# Types + Zod v4 validators
npx shadcn add @open-types/user-zod

# Types + real-world examples
npx shadcn add @open-types/user-examples
```

## Types

```typescript
import type { Address } from "./address";

export type UserRole = "admin" | "user" | "moderator" | "viewer";

export interface User {
  id: string;
  email: string;
  name: string;
  role?: UserRole;
  avatar?: string;
  address?: Address;
  bio?: string;
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
}

export type UserCreate = Omit<User, "id" | "createdAt" | "updatedAt">;

export type UserUpdate = Partial<UserCreate>;
```

## Zod validator

```typescript
import * as z from "zod";
import type { User, UserCreate, UserUpdate, UserRole } from "../types/user";
import { addressSchema } from "./address";

export const userRoleSchema = z.enum(["admin", "user", "moderator", "viewer"]);

export const userSchema = z.object({
  id: z.uuid({ error: "Invalid user ID" }),
  email: z.email({ error: "Invalid email address" }),
  name: z.string().min(1, { error: "Name is required" }),
  role: userRoleSchema.default("user"),
  avatar: z.url({ error: "Avatar must be a valid URL" }).optional(),
  address: addressSchema.optional(),
  bio: z.string().max(500, { error: "Bio must be at most 500 characters" }).optional(),
  isActive: z.boolean(),
  createdAt: z.iso.datetime({ error: "Invalid datetime" }),
  updatedAt: z.iso.datetime({ error: "Invalid datetime" }),
}) satisfies z.ZodType<User>;

export const userCreateSchema = userSchema.omit({
  id: true,
  createdAt: true,
  updatedAt: true,
});

export const userUpdateSchema = userSchema
  .omit({ id: true, createdAt: true, updatedAt: true })
  .partial();

export type { User, UserCreate, UserUpdate, UserRole } from "../types/user";
```

## Examples

```typescript
// Source: hand-crafted
import type { User, UserCreate, UserUpdate, UserRole } from "../types/user";
import { addressExamples } from "./address.examples";

export const userRoleExamples = {
  admin: "admin",
  user: "user",
  moderator: "moderator",
  viewer: "viewer",
} as const satisfies Record<string, UserRole>;

const jenny = {
  id: "9f8b7c6d-5e4f-4a2b-9c0d-1e8f7a6b5c4d",
  email: "jenny@example.com",
  name: "Jenny Rosen",
  role: "user",
  avatar: "https://cdn.example.com/avatars/jenny.png",
  address: addressExamples.minimal,
  bio: "Engineer at OpenTypes.",
  isActive: true,
  createdAt: "2026-01-01T00:00:00.000Z",
  updatedAt: "2026-05-16T18:30:00.000Z",
} as const satisfies User;

export const userExamples = {
  fullProfile: jenny,
  admin: { ...jenny, id: "11111111-2222-4333-8444-555555555555", role: "admin", email: "admin@example.com" } satisfies User,
  moderator: {
    ...jenny,
    id: "22222222-3333-4444-8555-666666666666",
    role: "moderator",
    email: "mod@example.com",
  } satisfies User,
  viewer: {
    ...jenny,
    id: "33333333-4444-4555-8666-777777777777",
    role: "viewer",
    email: "viewer@example.com",
  } satisfies User,
  minimal: {
    id: "44444444-5555-4666-8777-888888888888",
    email: "min@example.com",
    name: "Min User",
    isActive: true,
    createdAt: "2026-05-16T18:30:00.000Z",
    updatedAt: "2026-05-16T18:30:00.000Z",
  } satisfies User,
  deactivated: {
    ...jenny,
    id: "55555555-6666-4777-8888-999999999999",
    email: "old@example.com",
    isActive: false,
  } satisfies User,
} as const;

export const userCreateExamples = {
  basic: {
    email: "new@example.com",
    name: "New User",
    isActive: true,
  } satisfies UserCreate,
  fullProfile: {
    email: "rich@example.com",
    name: "Rich User",
    role: "user",
    avatar: "https://cdn.example.com/avatars/rich.png",
    bio: "Active community member.",
    isActive: true,
  } satisfies UserCreate,
} as const;

export const userUpdateExamples = {
  bioOnly: { bio: "Updated bio text." } satisfies UserUpdate,
  promote: { role: "admin" } satisfies UserUpdate,
  deactivate: { isActive: false } satisfies UserUpdate,
  empty: {} satisfies UserUpdate,
} as const;
```
