chore(quality): real lint coverage, vitest + knip gates, dead-file removal - #370
Conversation
…direct deps The lint script was a bare 'next lint', which only covers app/ components/ lib/ (and pages/ src/), so hooks/ and contexts/ were never linted locally or in CI and two real errors hid there. It now names every source directory and fails on warnings; the previously warn-level rules are errors since the tree is at zero. Adds Vitest with 48 specs over the pure lib modules (WIF/hex codecs, AES-GCM, hash160, bloom filter, compression/chunking, slugs, tag/mention extraction) and knip for dead files/exports/deps, both wired into CI. knip enforces files/dependencies/unlisted now; unused exports are reported until the backlog is cleared. Direct imports of @dashevo/wasm-sdk, @storacha/access and @ucanto/principal were only satisfied transitively; they are listed explicitly. Drops the unused @radix-ui/react-slider. Also: tsconfig target es5→es2020, malformed .gitignore line, stale pages/ tailwind glob and unsplash image domain. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Floating promises in hooks/contexts get .catch handlers that log; the enrichment completion tracker uses allSettled. Non-null assertions are replaced with narrowing (private post fields destructured once, variant axes captured, cart load returns its value). exhaustive-deps: real missing deps added (blog comment count callback, blog follower count, fetchReplyChain now memoized), the validation hooks depend on the memoized array instead of a join, and the sidebar effect reads primitives. Explicit any: profile maps are typed as UnifiedProfileDocument (dropping the dead '.data || profile' fallbacks), notification queries go through the typed queryDocuments helper, pagination-utils gets a minimal structural SDK interface instead of any, and the DiceBear style map uses Style<object>. @next/next/no-img-element is turned off in config: with output:export images are unoptimized, next/image adds nothing here, and 13 sites already disabled it inline. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
build:gh-pages never existed (the script is build:subpath). The structure tree listed a profile-migration-service, lib/utils.ts, types/sdk.ts, a /profile route, the deleted hooks, and dash-platform-client, none of which exist. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…m knip config postService.getTimeline hands back createDefaultUser placeholders (hasDpns: false, 'Unknown User'), but PostCard reads hasDpns === undefined as 'still resolving' and false as 'no DPNS name', so every For You card would flash a truncated identity id until enrichment landed. The feed now resets the author to the loading shape, matching what transformRawPost produced. The now-unused forceRefresh option is dropped. knip's own hints: the plugin-covered config entries and the default-ignored dirs were redundant. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🕓 Ready for review — 28 ahead in queue (commit 59554f1) |
Deploying yappr with
|
| Latest commit: |
59554f1
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c4c3c58d.yappr.pages.dev |
| Branch Preview URL: | https://chore-quality-gates.yappr.pages.dev |
Deploying yappr-v2 with
|
| Latest commit: |
59554f1
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://e20a0db0.yappr-v2.pages.dev |
| Branch Preview URL: | https://chore-quality-gates.yappr-v2.pages.dev |
First PR of the anti-slop cleanup series. This one makes the quality gates real and removes what is provably dead, so the later consolidation PRs land on a tree where lint, typecheck, unit tests and dead-code detection all mean something.
The gate that wasn't
npm run lintwas a barenext lint, which only walkspages/ app/ components/ lib/ src/.hooks/(5.9k LOC) andcontexts/were never linted, locally or in CI. Running ESLint over them surfaced two real errors (no-var-requiresin a dead hook) and ~40 warnings. Every rule was alsowarn, so 115 warnings had accumulated with a green CI.lintnow names every source directory and runs with--max-warnings 0.error. The tree is at zero, so this only bites regressions.@next/next/no-img-elementis off: underoutput: 'export'images are unoptimized,next/imageadds nothing, and 13 sites already disabled it inline (those inline disables are removed).no-explicit-anydisables are gone: pagination-utils gets a minimal structural SDK interface, the DiceBear style map usesStyle<object>.New gates
npm run testunitnpm run lint:deaddead-codeVitest starts with 48 specs over the pure
lib/modules: WIF/hex codecs, AES-GCM round-trip and tamper detection, hash160 known vectors, bloom filter (no false negatives, FP rate at design load, serialization), compression/chunking, slugs, tag and mention extraction. These are the modules the primitive-consolidation PRs will touch next.knip enforces unused files, unused dependencies and unlisted dependencies now. Unused exports (69) and types (96) are reported but not yet enforced; that backlog is worked down in the following PRs, after which the job goes strict.
Dependencies
@dashevo/wasm-sdk(11 files),@storacha/accessand@ucanto/principalwere imported directly but only present transitively; they are listed explicitly (wasm-sdk pinned to the same4.2.0-dev.8as evo-sdk, one lockfile entry).@radix-ui/react-sliderhad no importers and is removed.Dead code removed
Ten files with zero importers:
types/sdk.ts,hooks/use-require-encryption-key.ts,hooks/use-platform-detection.ts,components/compose/upload-progress.tsx,components/layout/mobile-header.tsx,components/post/feed-reply-context.tsx,lib/utils/contact-methods.ts,serve.py(superseded byscripts/serve-static.mjs),assets/yappr.png(byte-identical topublic/yappr.png), andlib/dash-platform-client.ts.DashPlatformClientduplicatedpostService.getTimelinebehind anany-typed cache and a third copy of the SDK response normalizer. Its two callers (For You feed, explore search) now callpostService.getTimeline, which returns transformedPostobjects, so the feed no longer re-transforms documents it already has. Theplatform-authclientIdentityport existed only to feed this client and is dropped. Note the per-page 2-minute cache inside the old client is gone;use-feed-datastill caches the first page viacacheManager, so this only affects re-scrolling already-seen pages.The app store carried a
currentUserslot seeded from mock data that nothing read; it and the mock user are gone, leavinglib/mock-data.tsas the default-avatar helper it actually is (CLAUDE.md updated to say so).Lint fixes
Behavior-preserving except where noted:
.catchhandlers that log. The enrichment completion tracker usesallSettled.private-post-content.tsxthe three private fields are destructured once per callback;attemptRecoverygains the guardattemptDecryptionalready had.use-blog-follow's toggle now depends onfollowerCount, which fixes a stale rollback value.fetchReplyChaininuse-post-detailis memoized (its only dep,enrich, is stable). The validation hooks depend on the memoized array instead of.join(',').anycasts: profile maps are typed asUnifiedProfileDocument, dropping 39 dead(profile as any)?.data || profilefallbacks (getProfilesByIdentityIdsalready returns flat documents). Notification queries go through the typedqueryDocumentshelper instead ofsdk.documents.query(... as any).Config leftovers
tsconfig
target: es5→es2020. Malformed last.gitignoreline (.gitignore worktrees) →worktrees/. Stale./pages/**tailwind glob andimages.unsplash.comdomain removed. README no longer names a nonexistentbuild:gh-pagesscript or files that do not exist.Overlap
#369 also touches
lib/feed/load-for-you-feed.tsandhooks/use-feed-data.ts. Whichever lands second will need a small rebase; the conflict is confined to theloadForYouFeedcall site and the removedforceRefreshoption.Validation
npm run lint(0 warnings),npx tsc --noEmit,npm run test(48/48),npx knip --include files,dependencies,unlisted,npm run buildall clean locally.🤖 Generated with Claude Code