recover(api-key): вернуть в develop осиротевший UI фазы-2 (#506/#533) #572
Reference in New Issue
Block a user
Delete Branch "recover/506-apikey-ui"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Восстановление: UI управления API-ключами (#506/#533) осиротел от develop
Проблема (найдено при планировании #556). Фаза-2 UI API-ключей (#533) в develop НЕ попала. #533 смержился в ветку
feat/501-mcp-apikey-authв 17:33 — а самаfeat/501ушла в develop раньше (через #526 в 05:02). Итог: 4 UI-коммита #533 остались наfeat/501и НЕ являются предками develop. Проверено ancestry, не по merged-флагу:git merge-base --is-ancestor 4e64c953 gitea/develop→ NO.apps/client/src/features/api-key/**отсутствует (0 файлов).Классический orphan стакнутого PR (тот же класс, что #491→#540): merged-флаг зелёный, но контент не в develop.
Восстановление. Черри-пикнул 3 UI-коммита #533 (
199a9a17/d6411424/be25b31a— соответствуют оригинальным90c02a0a/79675825/5e697434) на свежую ветку от develop. Серверная часть фазы-1 уже в develop (через #526), так что тут ровно клиентский UI-делта (1205 строк): страница управления ключами в настройках, create/show-token модалки, query/service/utils, i18n (ru+en), роут/сайдбар/телеметрия.Конфликт при черри-пике — только
translation.json(en+ru): develop добавил свои ключи в ту же alphabetical-зону. Разрешён аддитивно (оба набора ключей сохранены; api-key-ключи1 year/30 days/90 daysвстают передA new version…). JSON валиден, дублей нет (1 yearcount = 1).Верификация. api-key vitest 68/68 (4 файла) на текущем develop. Маркеров нет.
Это re-land кода, уже прошедшего ревью как #533 — но пусть ревьюер подтвердит корректность восстановления (ставлю review/needs, сам approve не ставлю). Без этого PR у #556 фазы 3A нет UI-поверхности (copy-button), и операторам нечем выпускать ключи перед cutover фазы 3B.
Всплыло при планировании #556 (API-ключи фаза 3).
Fix 1: an already-expired key rendered the forward-looking "Expiring soon" badge/tooltip ("expires within 30 days"), which is false for a past expiry. Add a pure isExpired() helper and, in ApiKeysManager, render a red "Expired" badge ("This key has expired") for past expiries; keep the orange "Expiring soon" badge only for keys expiring in the future within 30 days (the two states are made mutually exclusive at the call site). Extend utils.test.ts with isExpired coverage (past/future/null/exact-now boundary) and add a component assertion that an expired key shows "Expired" and NOT "Expiring soon". Fix 2: the response-contract unwrap (res.data turning the server envelope {data:{token,apiKey},success,status} into {token,apiKey}) was exercised by no test — component tests fully mock the service. Add a service-layer unit test that mocks the api-client (axios instance) and asserts createApiKey unwraps to the inner {token,apiKey} payload and getApiKeys resolves to the row array. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>en-US (source of truth) and ru-RU were missing ~25 strings introduced by the api-key management UI, so Russian users saw the controls in English and en-US was incomplete. Add every new t() key to both locales (24 new in en-US, 26 in ru-RU) with natural Russian translations, placeholders ({{name}}/{{date}}) preserved; existing keys left untouched (insertions only, no reordering). Also fix the createApiKey() lifecycle comment: the gcTime:0 + invalidation lives in queries/api-key-query.ts (there is no use-api-key-query file) and the reset()-after-read of the token lives in components/api-keys-manager.tsx handleCreate (create-api-key-modal.tsx only resets the form). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>