# 0.21.0

Terreno packages move in lockstep. Review the consolidated changelog for this release and run:

- `bun run compile` and `bun run lint` at the repo root
- `cd example-frontend && bun run sdk` after any `@terreno/api` route or model surface change

## `@terreno/api` — migrate off `setupServer`

`setupServer` and `initializeRoutes` were removed. Use `TerrenoApp` only:

```typescript
// Before
setupServer({
  userModel: User,
  addRoutes: (router, options) => {
    router.use("/todos", modelRouter(Todo, options));
  },
  addMiddleware: (app) => {
    app.use(sessionMiddleware);
  },
});

// After
new TerrenoApp({
  userModel: User,
  configureApp: (router, { openApi }) => {
    router.use("/todos", modelRouter(Todo, { openApi }));
  },
  beforeJsonSetup: (app) => {
    app.use(sessionMiddleware);
  },
})
  .register(todoRouter)
  .start();
```

- `configureApp` runs after registered plugins/model routers and before `/auth/me`.
- `beforeJsonSetup` runs after CORS and before the JSON parser — same slot as the old `addMiddleware` on `setupServer`.

See `example-backend/src/server.ts` and `api/src/example.ts` for current patterns.

## `@terreno/api` — `requestId` on JSON object responses

`TerrenoApp` injects `requestId` into plain-object JSON response bodies (aligned with the `X-Request-ID` header). This does **not** apply to:

- JSON arrays (list endpoints still return `{ data, page, limit, total, more }` with `requestId` on the wrapper object)
- `GET /openapi.json`
- Primitive JSON bodies

If your client validates response shapes strictly, allow an optional `requestId` string on object payloads.

## `@terreno/admin-backend` — Admin UI v2 config

`GET /admin/config` now includes `schemaVersion: 2` and richer per-model metadata. Legacy v1 fields (`models`, `listFields`, `fields`, …) are unchanged — existing admin clients keep working. New endpoints: `POST {route}/bulk-patch` and `POST /admin/background-tasks`.

## `@terreno/ui` — Card visual changes

`Card` no longer applies shadow by default. The `display` variant adds title, description, optional action button, size, and cover image with responsive row/column layout. Review screens that relied on the old bordered-box-only Card appearance.
