fix: resolve all SonarQube issues + comprehensive test suite - #3
Merged
Conversation
- S6848/S6847: Replace non-interactive divs with buttons for celebrations
(all-done, goal-completed, streak, streak-freeze, welcome-back-toast)
- S6848: Add role="presentation" to backdrop overlays (app-overlay,
notification-bell, app-date-picker)
- S6848: Add role="button" to habit-card article with click handlers
- S6848: Add role="menu" to action menu portal divs (habit-card, page.tsx)
- S6848: Restructure checklist-templates into proper button elements
- S6848: Add role/tabIndex/onKeyDown to ai-settings fact items in select mode
- S6811: Add role="checkbox" to habit-card selection button with aria-checked
- S6852: Add tabIndex={0} to tablist container for focusability
- S6848: Remove onClick from breakdown-suggestion checkbox visual div
(label already handles toggle), add aria-hidden
- S6848: Add role="group" to goal-list draggable containers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract optimistic update helpers (S2004: use-habits.ts nesting > 4 levels) into lib/habit-optimistic-helpers.ts - Extract habit request builders (S3776: create/edit modal complexity 86/24) into lib/habit-request-builders.ts - Extract habit card badge sub-components (S3776: habit-card complexity 89) into TopLevelBadges, ChildBadHabitBadges, ChildDefaultBadges, etc. - Extract proxy response helpers (S3776: route.ts complexity 17) into buildResponseHeaders and toNextResponse Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…594, S1128, S7735, S6754, S2871, S1854, S4138, S1135, S6759) - Replace window.* with globalThis.* for cross-env compatibility (S7764) - Remove unnecessary type assertions in calendar-sync (S4325) - Use .replaceAll() instead of .replace(/regex/g) (S7781) - Use RegExp.exec() instead of String.match() (S6594) - Remove unused imports: useMemo, useStreakInfo, Loader2 (S1128) - Swap negated conditions for clarity (S7735) - Remove useless draggedItemId assignment (S1854) - Add localeCompare to string .sort() (S2871) - Convert for loop to for-of in speech recognition (S4138) - Replace TODO with descriptive comment (S1135) - Add Readonly<> wrapper to component prop types (S6759) - Swap negated ternary branches in form-fields, advanced page (S7735) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The useTotalHabitCount query stored a number under habitKeys.list({ _count: true }),
which collided with habitKeys.lists() prefix used by setQueriesData in mutations.
Moving to a dedicated count() key prevents the "old.map is not a function" error.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Actions: auth, chat, goals, habits, notifications, profile, tags (99% coverage) Hooks: 13 new test files covering gamification, calendar, billing, config, referral, subscription-plans, summary, retrospective, time-format, tag-selection, color-scheme, habit-form, speech-to-text Lib: api-fetch, auth-api, query-client, plural, offline-queue Components: 41 test files covering habits, goals, chat, calendar, gamification, navigation, onboarding, referral, and UI components Shared: types (255 tests), query keys, endpoints, theme, validation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
thomasluizon
added a commit
that referenced
this pull request
Apr 15, 2026
formatChatMessage previously only ran a hand-rolled regex that escaped & < > ". It was then passed straight into dangerouslySetInnerHTML. That is safe today, but: - Single-quote and backtick were not escaped. - A malicious AI reply could emit RTL overrides, zero-width joiners, or homograph URL fragments that the regex never touches. The formatter now: 1. Escapes &, <, >, ", ', and `. 2. Applies the **bold** / *italic* markdown replacements. 3. Runs DOMPurify as defense-in-depth with ALLOWED_TAGS=['strong','em'] and no attributes, so even if future markdown rules introduce a tag (e.g. <a>), it cannot leak executable markup. DOMPurify was already a direct dependency (used in retrospective/page.tsx and app-overlay.tsx), so this adds no new package weight. Adds tests for single-quote/backtick escaping and DOMPurify's strip-unknown- tag behavior. Covers frontend plan Area A #3 (P0 #7). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
thomasluizon
added a commit
that referenced
this pull request
Apr 15, 2026
useHabitDetail (HabitDetail shape) and useHabitFullDetail (HabitFullDetail shape) both cached under habitKeys.detail(id). Whichever hook ran second won the cache entry; the other consumer then read mis-typed data, risking runtime crashes where fields were missing. Adds habitKeys.fullDetail(id) and retargets useHabitFullDetail on web + mobile. Cache invalidations in use-habits and habit-mutation-helpers now invalidate both keys on habit mutation. Covers frontend plan P0 #3 / Area C #8. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
thomasluizon
added a commit
that referenced
this pull request
Apr 15, 2026
…lidators Covers the P1 missing-validation findings in the audit: - validateGoalDeadline(deadline, today): blocks past dates, rejects garbage strings (goals.form.deadlinePast / goals.form.deadlineInvalid i18n keys). - validateReminderTimes(minutes): enforces the backend contract that minutes-before-due offsets are integers in [0, 1440] and unique. - validateDueTimes(dueTime, dueEndTime): blocks the case where a user sets only the end time without a start time. validateReminderSelection and validateHabitForm now delegate into the new validators so inline errors fire on the existing form flows without touching each component. Adds en/pt-BR i18n keys with proper diacritics on the Portuguese strings. Extends validation.test.ts and goal-form.test.ts with exhaustive boundary cases. Covers frontend plan Area D #1, #2, #3. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
thomasluizon
added a commit
that referenced
this pull request
Apr 15, 2026
DraggableFlatList previously had no getItemLayout, so React Native had to measure every row before rendering during initial scroll and drag events. With 40+ habits on mid-tier Android this produces visible jank. Adds an approximate ESTIMATED_HABIT_ITEM_HEIGHT=104 and wires getItemLayout onto the primary DraggableFlatList driver. The value does not need to be perfect: telling RN that rows are of roughly uniform height unlocks scroll-to-offset fast-paths and smoother drag. Covers frontend plan Area C #3 (P0 #9). Note: Splitting habit-list.tsx + habit-card.tsx into smaller files (Area C #1, #2) is deferred as a TODO — it is a large refactor across 2,119 + 1,511 LOC and is better done in a dedicated PR with profiling measurements. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
3 tasks
This was referenced Jun 23, 2026
This was referenced Jul 13, 2026
thomasluizon
added a commit
that referenced
this pull request
Jul 24, 2026
Phase 6 doc sort (REBUILD.md open question #3, D12): - DELETE WORKFLOW.md: the pre-rebuild path-picking guide for the torn-down /drive|/execute|/create-prd|/create-stories harness. Superseded by "The workflow" in CLAUDE.md; a lie-waiting that describes a deleted workflow. Removes its docs-registry row, its live cross-link in planning-and-artifacts.md, and its stale dash-baseline entry. - KEEP FEATURES.md (flagged for review): gate-maintained (pr-review rubric #14), and holds Pro/Free gating the generated arch map cannot. Registry row reworded from "code-derived" to "hand-maintained, gate-kept". - KEEP TESTING.md, the 4 playbooks, the 3 rules files: authoritative-small. - Fix drift in playbooks/README.md: the android-release -> android-generate rename left a dead citation ("cites debugging.md") that is no longer true; replaced with a verified current example. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
SonarQube Fixes
lib/habit-optimistic-helpers.tswindow->globalThis, unnecessary assertions removed,replaceAll,RegExp.exec, unused imports, readonly props, negated conditions,localeComparesortTest Coverage
Bug Fix
habitKeys.count()key added to preventsetQueriesDatacrash whenuseTotalHabitCountstored a number underhabitKeys.list()prefixTest plan
npx turbo run test-- 1,134 tests passing, 0 failuresnpx tsc --noEmit-- 0 type errors🤖 Generated with Claude Code