fix(qa): resolve QA-pass issues #122–#134 #135
Reference in New Issue
Block a user
Delete Branch "fix/qa-issues-122-134"
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?
Fixes the issues found in the automated QA pass (#122–#134). Branched off the latest
develop. Every fix was reproduced, then verified fixed live (browser/curl, screenshots captured); the logic-bearing fixes also have new unit tests.Functional bugs
jwtDecode(undefined)on collab auth failure + no reconnect → now reads the token via a ref, guards the decode (incl. missing/non-numericexp), and refetch+reconnects on any failure. (verified: forced 429 → 0 PAGEERROR)/Heading 1) inserted literal text →allowSpaces: true+ the menu closes when nothing matches. (verified live)productteam; +unit tests)atomWithStorage, clamped to viewport (also fixes a latent observer-attach bug). (verified: survives reload)@NoUrls(parity with setup). (verified: now 400; +DTO tests)calc()width/height (icon-columns 4/5) andshare-for-pagequery returningundefined→ fixed. (verified: 0 errors; +test)UX / consistency
Untitledcasing (tree/breadcrumb/tab), stopped force-uppercasing space-name chips, fixed confirm-dialog labels (Cancel / Remove), invite placeholder typo, Export/Move-to-space labels.Tests
New unit tests:
computeSpaceSlug, workspace-nameNoUrlsDTO validation,share-querynull normalization, slashgetSuggestionItemsempty-close. Clienttsc/vitestand servertsc/jestfor the touched areas all pass.🤖 Generated with Claude Code
Ревью PR #135
Прочитал весь дифф (45 файлов, +657/−124) и проверил самые рискованные места против реальных файлов ветки.
Вердикт
PR качественный и аккуратный: правки точечные, с понятными англоязычными комментариями, тесты осмысленные. Критичных проблем не нашёл. Несколько мелких замечаний ниже, ни одно не блокирует мердж.
Что проверил отдельно (всё ок)
throttle.module.tsровно 4 именованных throttler-а (auth,ai-chat,page-template,public-share-ai), безымянного дефолтного нет. Фикс вauth.controller.tsпропускает все 4 →collab-tokenбольше не ловит ложные 429 от IP-лимитера public-share-AI (5/мин). Исправление полное и корректное.page-editor.tsx: свежий токен берётся черезref,jwtDecodeобёрнут в try/catch, отсутствующий/нечисловойexpтрактуется как «истёк» → реконнект сработает даже если первичный фетч токена упал. Хорошая обработка краёв.getSuggestionItemsдействительно импортирован вslash-command.ts;allowSpaces: true+allow, закрывающий меню при отсутствии совпадений; есть тест на контракт.useLayoutEffect+clampGeomна каждом открытии, окно не уедет за экран; правка зависимостиgeom !== nullуResizeObserver— реальный тонкий баг, поймали верно.style={{ width: rem(size) }}соответствует конвенции остальных иконок.AuthLayout/Containerвinvite-sign-up-form.tsxи валидаторno-urls.validatorна месте.Замечания (некритичные)
1. i18n: две новые строки не добавлены в локали — low.
Ключи
"Go to login page"(password-reset.tsx, invite-форма) и"Move to space"(page-header-menu.tsx,space-tree-node-menu.tsx) отсутствуют вen-US/translation.json, хотя PR добавил туда десяток других новых строк. В английском отрисуются через fallback-на-ключ (корректно, кодовая база уже так делает — старый"Goto login page"тоже не был ключом), но в остальных 11 локалях останутся непереведёнными. Для консистентности стоит добавить оба ключа в en-US.2. avatar-uploader: список типов захардкожен — low / возможная регрессия.
В
avatar-uploader.tsxдопускаются толькоimage/png|jpeg|jpg. Раньше клиентской проверки типа не было; если сервер принималwebp/gif, теперь они отклонятся на клиенте."image/jpg"— нестандартный MIME (безвреден). Стоит сверить набор с тем, что реально поддерживает сервер, либо расширить (минимум webp).3. reindex-поллинг: два разных условия «готово» — low.
В
ai-provider-settings.tsxколбэкrefetchIntervalостанавливается приindexedPages >= totalPagesбез проверкиtotalPages > 0, а очищающийuseEffectтребуетtotalPages > 0. Для пустого воркспейса (totalPages=0) поллинг не стартует (ок), ноreindexDeadlineсбросится только по таймауту, а не по «готово». Безвредно, но условия лучше выровнять.4. #133: Share полностью скрыт для read-only — дизайн-заметка, не баг.
Раньше читатель видел модалку Share (с неактивным тоглом), теперь точка входа убрана совсем → читатель больше не может открыть диалог, чтобы скопировать уже существующую публичную ссылку. Соответствует тексту issue, но это поведенческое изменение — отметьте, если «дать читателю копировать существующую ссылку» было нужно.
5. Мелочи — very low.
В
change-password.tsxпотеряно отдельное сообщение «current password is required» (теперь оба поля показывают «Password must be at least 8 characters»). Схемы валидации (account-name / create-group / change-password) пересоздаются на каждый рендер, т.к. переехали внутрь компонента радиt()— функционально ок, можно обернуть вuseMemo.Итог
Мерджить можно. Перед мерджем имеет смысл закрыть только п.1 (добавить 2 ключа в en-US) и проверить п.2 (webp в аватарах) — остальное на усмотрение. Тесты в PR (
computeSpaceSlugproperty-тест,NoUrlsDTO, нормализацияshare-query кnull, закрытие slash-меню) релевантны и покрывают именно логику фиксов.- Add the two new strings to en-US locale ('Go to login page', 'Move to space') so they aren't missing from the base locale (review note 1). - Avatar upload: accept any image/* MIME instead of a hardcoded png/jpeg/jpg list, so webp/gif/etc. are no longer wrongly rejected client-side while genuine non-images still surface the error (review note 2). - Reindex polling: align the deadline-clearing effect with the refetchInterval stop condition (indexed >= total, empty workspace included) so the deadline clears promptly instead of waiting out the cap (review note 3). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>