Owner: Engineering Team | Last Updated: 2026-01-30 | Status: Current
Use this checklist when reviewing pull requests for the WWAI web application. The checklist is organized with WWAI-specific checks first (the most critical items), followed by general best-practice categories that also include project-specific subsections.
Every reviewer should work through the WWAI-Specific Checks section in full. The general sections serve as a supplementary quality gate.
These are the checks that matter most for our codebase. If you only have time for one section, make it this one.
console.log of access_token, refresh_token, or session.access_tokenWALTER_INTERNAL_KEY is never referenced in client-side code — it must remain server-only and must not use the NEXT_PUBLIC_ prefixNEXT_PUBLIC_* environment variable (these are bundled into client-side JavaScript and are publicly visible)Authorization: Bearer ${session.access_token} headerX-Walter-Internal-Key header (sent via utils/api.ts)is_plain_text: false) is sanitized before rendering — this is a direct XSS vector if unsanitized HTML is injected into the DOMcredit field on the response must be checked and the local state updated accordingly(score * 100).toFixed(0)%detail values that drive UI behavior:
'Your subscription is paused' — show reactivation prompt'word_limit' — show plan upgrade prompt'Your content exceeds the limit of your plan' — show plan limit message'You have not enough credits' — show credit purchase promptfetch() — do NOT use axios for these calls. The two HTTP clients must not be mixed for this endpoint.utils/api.tserrorData.detail || errorData.message || errorData.erroruseDispatch<AppDispatch>() — no untyped useDispatch() and no custom typed hooksuseSelector((state: RootState) => ...) — no untyped useSelector() and no custom typed hooks.unwrap() for proper error propagationcreateSlice reducers are fine, but code outside reducers must not mutate store stateen, de, es, fr, it, pt, zh, nlt('keyName') from next-intl — never hardcoded text in JSXuseEffect dependencies and onUpdate callbacks are stablenext build output if in doubtNote: The WWAI web application currently has no formal automated test suite. All verification is manual. This section defines the manual testing matrix that must be executed for any feature-affecting PR.
.docx, .pdf, and .txt filesGeneral security practices that apply alongside the WWAI-specific credential and safety checks above.
Refer to the Credentials and Secrets, Authentication and Bot Protection, and Content and Input Safety subsections in the WWAI-Specific Checks section above for project-specific security requirements.
any types unless absolutely unavoidable (and documented why)catch blocksuseDispatch<AppDispatch>(), useSelector((state: RootState) => ...), .unwrap() on thunks (see Redux subsection above)fetch() for humanizer, axios via utils/api.ts for detector and internal calls (see API Client Usage above)detail, message, errorReact.memo, useMemo, useCallback where appropriate<Image> component with proper sizingRefer to the Performance subsection in the WWAI-Specific Checks section above for TipTap, detector polling, checkout caching, and bundle size checks.
The project has no automated test suite. See the Testing (Manual) subsection in the WWAI-Specific Checks section above for the required manual testing matrix.
next-intl APIsRefer to the Internationalization (i18n) subsection in the WWAI-Specific Checks section above for the full list of 8 required locales and the next-intl usage pattern.
NEXT_PUBLIC_| Mistake | Why It Matters | Correct Approach |
|---|---|---|
console.log(session.access_token) |
Leaks auth tokens to browser console / logs | Remove before merging; use structured logging server-side only |
NEXT_PUBLIC_WALTER_INTERNAL_KEY |
Exposes internal API key to every browser | Use WALTER_INTERNAL_KEY (server-only) |
Displaying detector score as score + '%' |
Score is 0-1 decimal, not 0-100 | (score * 100).toFixed(0) + '%' |
Anti-detection strength value of 3 or 4 |
Scale is 0-2 only | Use 0 (Simple), 1 (Standard), 2 (Enhanced) |
| Using axios for humanizer endpoint | Humanizer uses fetch() by convention |
Use fetch() for humanizer, axios for detector |
| Hardcoded English string in JSX | Breaks i18n for 7 other locales | Use t('keyName') from next-intl |
Adding translation to en.json only |
Other locales show blank/fallback | Add key to all 8 locale files |
Missing .unwrap() on async thunk |
Errors silently swallowed | Always call .unwrap() and handle the rejection |
Checking only errorData.message |
Backend may return detail or error instead |
Check errorData.detail \|\| errorData.message \|\| errorData.error |
Untyped useDispatch() |
Loses type safety for thunk dispatch | Use useDispatch<AppDispatch>() |
| Date | Author | Change |
|---|---|---|
| 2026-01-30 | Admin | Rewrote checklist with WWAI-specific checks: security (tokens, Turnstile, TipTap XSS, env vars), feature logic (credits, scores, strength scale, word/file limits), API patterns (fetch vs axios, error parsing, 403 handling), Redux conventions, i18n for 8 locales, performance (TipTap, polling, pricing cache), and manual testing matrix |
| 2026-01-30 | Admin | Initial creation |
Prev: Guide: Debugging Production Issues | Up: General