---
id: w5/m7/t002
title: "Settings tab: route + nav item + Instance Type summary row with Update link"
worker: worker5
status: done
estimate: 40m
depends_on: [w5/m7/t001]
---

## Objective

Give the service detail page a Settings tab whose first (and for now only) section mirrors Render's Instance Type row: current tier name, its CPU/RAM, and an Update link to the picker.

## Context

- Nav: `dashboard/src/features/services/components/service-nav.tsx` (`ITEMS`) — add Settings after Metrics; locales `services.navSettings` in `features/services/locales/{en,zh}.ts`.
- Route: `dashboard/src/routes/services.$serviceId.settings.tsx` rendering into the existing `services.$serviceId` layout `<Outlet/>` (same pattern as the metrics/env tabs).
- Data: the service's current plan comes from the `server(id) { plan }` field (shipped in m8; codegen may need the field added to an existing `.graphql` doc + `yarn codegen` — see `dashboard/CLAUDE.md` GraphQL section, needs `CODEGEN_SESSION_TOKEN`); its CPU/RAM come from matching `plan` against t001's `instanceTypes`.
- Render's row (captured): label "Instance Type" · tier name · separator · "0.5 CPU" / "512 MB" · "Update" link. bex renders the same minus nothing (no price on Render's row either). An App with no plan (bare-CR, untiered) shows an honest "No instance type set" state with the Update link still active.
- Follow the existing card/section idioms (`dashboard/CLAUDE.md` visual layout pattern; the env tab is the closest sibling).

## Steps

1. Nav item + route + Settings page shell with the Instance Type section.
2. Wire `plan` + `instanceTypes` queries; format quantities for display ("500m" → "0.5 CPU", "512Mi" → "512 MB").
3. Empty/plan-less state; i18n en+zh for every string.

## Files

- `dashboard/src/features/services/components/service-nav.tsx`, `locales/{en,zh}.ts`
- `dashboard/src/routes/services.$serviceId.settings.tsx` (new)
- `dashboard/src/features/services/components/` (new settings/instance-type components)
- `dashboard/src/features/services/api/*.graphql` (+ regenerated definitions)

## Acceptance criteria

- [ ] Settings tab appears in the nav; `/services/{id}/settings` shows "Instance Type · Standard · 1 CPU / 2 GB · Update" for a `standard` App.
- [ ] Untiered App shows the no-instance-type state, not a fake tier.
- [ ] Lint + tests + build green.

## Out of scope

- The picker itself (t003); other Settings sections (name/region/build).
