Skip to content

refactor: consolidate mock data into centralized lib/mock/ with factory pattern - #247

Merged
Benjtalkshow merged 2 commits into
boundlessfi:mainfrom
Shadow-MMN:refactor/mock-factory-pattern
May 28, 2026
Merged

refactor: consolidate mock data into centralized lib/mock/ with factory pattern#247
Benjtalkshow merged 2 commits into
boundlessfi:mainfrom
Shadow-MMN:refactor/mock-factory-pattern

Conversation

@Shadow-MMN

@Shadow-MMN Shadow-MMN commented May 28, 2026

Copy link
Copy Markdown
Contributor

Files changed:

  • Deleted: lib/mock-bounty.ts, lib/mock-data.ts, lib/mock-leaderboard.ts, lib/mock-model4.ts, lib/mock-project.ts, lib/mock-wallet.ts
  • Created: lib/mock/ directory with bounties.ts, leaderboard.ts, model4.ts, projects.ts, wallet.ts, discover.ts, index.ts
  • Updated imports in: lib/store.ts, lib/services/withdrawal.ts, app/discover/page.tsx, app/projects/page.tsx, app/projects/[id]/page.tsx, app/wallet/page.tsx, app/api/leaderboard/route.ts, app/api/leaderboard/top/route.ts, app/api/leaderboard/user/[userId]/route.ts, components/search-command.tsx, components/bounty-detail/bounty-detail-client.tsx

Closes #210

Summary by CodeRabbit

  • Chores
    • Reorganized internal mock data structure to improve code maintainability and consistency.
    • Updated formatting standards across the codebase for better uniformity.

Review Change Stack

@vercel

vercel Bot commented May 28, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Threadflow Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented May 28, 2026

Copy link
Copy Markdown

@Shadow-MMN Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Shadow-MMN, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 38 minutes and 43 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7834fd0f-66be-4b1a-9069-443e88b6103c

📥 Commits

Reviewing files that changed from the base of the PR and between 1fe0267 and 0001a9f.

📒 Files selected for processing (5)
  • app/api/leaderboard/route.ts
  • app/api/leaderboard/top/route.ts
  • lib/mock/leaderboard.ts
  • lib/services/withdrawal.ts
  • types/withdrawal.ts
📝 Walkthrough

Walkthrough

This PR consolidates mock data files from the top level into a structured lib/mock/ directory using factory patterns. Five domain-specific modules (bounties, leaderboard, wallet, projects, model4) are created with reusable factory functions alongside precomputed data. A discover module preserves legacy project/bounty datasets, and a central index re-exports everything. All imports across the app are updated to the new paths.

Changes

Mock Data Layer Reorganization

Layer / File(s) Summary
Core mock factory modules
lib/mock/bounties.ts, lib/mock/leaderboard.ts, lib/mock/wallet.ts, lib/mock/projects.ts, lib/mock/model4.ts
Five domain-specific modules introduce factory functions (makeMockBounty, makeMockLeaderboard, makeMockWallet, etc.) for fixture generation and export precomputed constants (mockBounties, mockLeaderboardData, mockWalletInfo, mockProjects, MOCK_MODEL4_MILESTONES). Each module includes read-only accessors to retrieve specific data or enumerate all entries.
Legacy data and central export hub
lib/mock/discover.ts, lib/mock/index.ts
discover.ts houses the legacy projects and bounties data (renamed to oldMockProjects/oldMockBounties for clarity). index.ts re-exports all new mock modules and aliases the legacy data as mockProjects/mockBounties for backward compatibility.
API routes import updates
app/api/leaderboard/route.ts, app/api/leaderboard/top/route.ts, app/api/leaderboard/user/[userId]/route.ts
Leaderboard API handlers update their imports to use @/lib/mock/leaderboard while preserving all existing pagination, filtering, and response logic.
Page and component import wiring
app/discover/page.tsx, app/projects/page.tsx, app/projects/[id]/page.tsx, app/wallet/page.tsx, components/bounty-detail/bounty-detail-client.tsx, components/search-command.tsx
Pages and components update imports to use the new @/lib/mock/... paths. Minor formatting adjustments applied to app/projects/[id]/page.tsx for consistency.
Service and store integration
lib/services/withdrawal.ts, lib/store.ts
Services and stores update to import from new paths and receive code style refactoring (explicit type annotations, multi-line imports, quote normalization) while preserving all validation and caching logic.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • boundlessfi/bounties#189: Updates lib/store.ts to switch mockBounties data source to the new ./mock/bounties module, maintaining TanStack Query local-store hook behavior.
  • boundlessfi/bounties#61: Leaderboard API route handlers were updated to wire to the new lib/mock/leaderboard exports, directly building on the leaderboard API layer.
  • boundlessfi/bounties#10: Updates app/discover/page.tsx to switch mock data imports from @/lib/mock-data to @/lib/mock, directly affecting the Discover page implementation.

Suggested reviewers

  • Benjtalkshow

Poem

🐰 The warren's grown, now tidy and clean,
Mock data scattered finds home in lib/mock's sheen!
Factories bloom where statics once stood,
One central hub, as good wood should,
All imports refactored—hooray, hooray! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.30% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: consolidating scattered mock data files into a centralized lib/mock/ directory using a factory pattern.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #210: all old lib/mock-*.ts files are deleted, new lib/mock/ directory is created with domain-specific files, factory functions are implemented, lib/mock/index.ts re-exports all modules, and all imports across the codebase are updated to use @/lib/mock paths.
Out of Scope Changes check ✅ Passed All changes are directly related to consolidating mock data files into lib/mock/ with factory functions. No unrelated refactoring, functionality changes, or formatting updates beyond what is necessary for the consolidation were introduced.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (1)
lib/mock/discover.ts (1)

507-508: ⚡ Quick win

Build oldMockBounties from oldMockProjects to avoid dataset drift.

Using makeOldProjects() twice creates two independent project arrays. Reuse oldMockProjects so both exports stay in sync by construction.

💡 Suggested fix
 export const oldMockProjects = makeOldProjects();
-export const oldMockBounties = makeOldBounties(makeOldProjects());
+export const oldMockBounties = makeOldBounties(oldMockProjects);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/mock/discover.ts` around lines 507 - 508, The export currently calls
makeOldProjects() twice which creates two different arrays; change the
oldMockBounties export to reuse the already-created oldMockProjects so they stay
in sync by calling makeOldBounties(oldMockProjects) instead of makeOldProjects()
– update the export of oldMockBounties to reference the existing oldMockProjects
variable (symbols: oldMockProjects, oldMockBounties, makeOldProjects,
makeOldBounties).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/api/leaderboard/route.ts`:
- Around line 7-8: Validate and sanitize the parsed pagination inputs before
using them: after obtaining page and limit via parseInt(searchParams.get("page")
|| "1") and parseInt(searchParams.get("limit") || "10"), ensure they are
positive integers (fallback to 1 for page and 10 for limit if NaN, <=0, or
non-integer), optionally clamp limit to a reasonable max (e.g., 100) to prevent
abuse, and then use these sanitized variables in the ranking/pagination math
(references: page, limit, parseInt, searchParams).

In `@app/api/leaderboard/top/route.ts`:
- Line 6: The parsed "count" value (const count =
parseInt(searchParams.get("count") || "5")) can be NaN or non-positive; update
the route handler to sanitize it by validating that count is a finite positive
integer and falling back to a safe default (e.g., 5) if not, and optionally
clamp to a reasonable max to preserve top-N semantics; apply the same validation
wherever "count" is parsed (the other occurrence around the second parseInt at
line 12) so the endpoint always returns a valid top-N parameter.

In `@lib/mock/index.ts`:
- Around line 1-9: The file re-exports mockProjects and mockBounties twice
causing a potential TS2308 conflict: remove or rename the duplicate re-exports
in lib/mock/index.ts so the names from "./projects" and "./bounties" are not
shadowed by the aliases from "./discover"; specifically, either delete the block
exporting oldMockProjects as mockProjects and oldMockBounties as mockBounties,
or change that export to export { oldMockProjects, oldMockBounties } (keeping
their original names) so the unique symbols mockProjects and mockBounties come
only from "./projects" and "./bounties".

In `@lib/mock/leaderboard.ts`:
- Around line 61-75: In getMockLeaderboard validate and normalize pagination
inputs before computing start: ensure page and limit are positive integers
(e.g., coerce to integers and use Math.max(1, ...) for page and Math.max(1, ...)
for limit) so start = (page-1)*limit and slice arguments are always non-negative
and safe; update the logic that computes start, paginated and any downstream
uses to use these normalized values.
- Around line 35-56: The function makeMockLeaderboardData can call Array.from
with a negative length when count < 10; guard count before generating extras by
computing extra = Math.max(0, count - 10) or branching so you only call
Array.from when count > 10. Update the spread that builds extra contributors
(the Array.from call that creates makeMockContributor entries) to use extra
instead of count - 10 (or early-return/slice the hardcoded list when count <=
10) and ensure indices/IDs still start at 11 (use i + 11) so makeMockContributor
and ReputationTier usage remains correct.

In `@lib/services/withdrawal.ts`:
- Around line 25-29: Add a lower-bound validation before creating withdrawals:
besides checking amount > mockWalletWithAssets.balance, validate that amount is
a positive number and that amount > fee (or explicitly that netAmount = amount -
fee > 0); if these fail set result.valid = false, push descriptive errors into
result.errors (e.g., "Invalid amount" or "Amount must exceed fee") and add new
blocker flags (e.g., result.blockers.invalidAmount or
result.blockers.feeTooHigh). Update both the initial balance/amount check (where
result.valid and result.blockers.insufficientBalance are set) and the later
netAmount computation (around netAmount usage at the netAmount check) to prevent
creating withdrawals with netAmount <= 0, referencing amount, fee, netAmount,
result, and mockWalletWithAssets.balance.
- Around line 114-116: The getHistory method returns the internal array by
reference (MOCK_WITHDRAWALS[userId]) which allows callers to mutate service
state; change WithdrawalService.getHistory to return a shallow copy of the array
(e.g., create a new array from MOCK_WITHDRAWALS[userId] or return an empty array
copy when absent) so callers get a safe copy instead of the original, ensuring
modifications to the returned value do not alter MOCK_WITHDRAWALS.

---

Nitpick comments:
In `@lib/mock/discover.ts`:
- Around line 507-508: The export currently calls makeOldProjects() twice which
creates two different arrays; change the oldMockBounties export to reuse the
already-created oldMockProjects so they stay in sync by calling
makeOldBounties(oldMockProjects) instead of makeOldProjects() – update the
export of oldMockBounties to reference the existing oldMockProjects variable
(symbols: oldMockProjects, oldMockBounties, makeOldProjects, makeOldBounties).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3f1773c6-8ffb-4566-bb26-efa2984c9efb

📥 Commits

Reviewing files that changed from the base of the PR and between 3aa81cb and 1fe0267.

📒 Files selected for processing (24)
  • app/api/leaderboard/route.ts
  • app/api/leaderboard/top/route.ts
  • app/api/leaderboard/user/[userId]/route.ts
  • app/discover/page.tsx
  • app/projects/[id]/page.tsx
  • app/projects/page.tsx
  • app/wallet/page.tsx
  • components/bounty-detail/bounty-detail-client.tsx
  • components/search-command.tsx
  • lib/mock-bounty.ts
  • lib/mock-data.ts
  • lib/mock-leaderboard.ts
  • lib/mock-model4.ts
  • lib/mock-project.ts
  • lib/mock-wallet.ts
  • lib/mock/bounties.ts
  • lib/mock/discover.ts
  • lib/mock/index.ts
  • lib/mock/leaderboard.ts
  • lib/mock/model4.ts
  • lib/mock/projects.ts
  • lib/mock/wallet.ts
  • lib/services/withdrawal.ts
  • lib/store.ts
💤 Files with no reviewable changes (6)
  • lib/mock-data.ts
  • lib/mock-wallet.ts
  • lib/mock-model4.ts
  • lib/mock-leaderboard.ts
  • lib/mock-project.ts
  • lib/mock-bounty.ts

Comment thread app/api/leaderboard/route.ts Outdated
Comment thread app/api/leaderboard/top/route.ts Outdated
Comment thread lib/mock/index.ts
Comment on lines +1 to +9
export * from "./bounties";
export * from "./leaderboard";
export * from "./wallet";
export * from "./projects";
export * from "./model4";
export {
oldMockProjects as mockProjects,
oldMockBounties as mockBounties,
} from "./discover";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Inspecting potentially conflicting exports..."
sed -n '1,120p' lib/mock/index.ts

echo
echo "Checking if upstream modules export the same symbols:"
rg -n --type=ts 'export\s+(const|function|type|interface)\s+mock(Project|Bounties|Projects|Bounty|Bounties)|export\s*\{[^}]*mockProjects|export\s*\{[^}]*mockBounties' lib/mock

Repository: boundlessfi/bounties

Length of output: 550


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- lib/mock/discover.ts (lines around oldMockProjects/oldMockBounties) ----"
sed -n '1,220p' lib/mock/discover.ts | sed -n '/oldMockProjects/,/oldMockBounties/p'

echo
echo "---- Full matching lines for oldMockProjects/oldMockBounties ----"
rg -n --type=ts "oldMockProjects|oldMockBounties" lib/mock/discover.ts

echo
echo "---- Ensure discover exports them (export declarations) ----"
rg -n --type=ts "export\s+(const|function|type|interface)\s+oldMock(Project|Bounties|Projects|Bounty|Bounties)" lib/mock/discover.ts || true

Repository: boundlessfi/bounties

Length of output: 521


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Searching for TypeScript duplicate export diagnostics or known handling..."
rg -n --hidden --no-ignore-vcs --type=ts --type=tsx --type=js --type=json --type=md \
  "(TS2308|already exported a member named|Duplicate|conflicting exports)" . || true

echo
echo "Searching for any existing mention of mockProjects/mockBounties duplicate export errors..."
rg -n --hidden --no-ignore-vcs --type=ts --type=tsx --type=js --type=json \
  "mockProjects.*already exported|mockBounties.*already exported|mockProjects.*duplicate|mockBounties.*duplicate" . || true

Repository: boundlessfi/bounties

Length of output: 305


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "---- lib/mock/index.ts (full) ----"
cat -n lib/mock/index.ts

echo
echo "---- Check for scripts/typecheck in package.json ----"
if [ -f package.json ]; then
  cat -n package.json | sed -n '1,200p'
else
  echo "package.json not found"
fi

echo
echo "---- Search for duplicate export-related TS diagnostics ----"
rg -n --hidden --no-ignore-vcs -g'*.ts' -g'*.tsx' -g'*.d.ts' -g'*.md' \
  "(TS2308|already exported a member named|conflict.*exported|Duplicate|re-export.*conflict)" . || true

echo
echo "---- Search for consumers importing mockProjects/mockBounties from lib/mock ----"
rg -n --hidden --no-ignore-vcs -g'*.ts' -g'*.tsx' \
  "from ['\"](.*/)?lib/mock['\"]|from ['\"]@?/.*/mock['\"]|from ['\"](.*/)?mock['\"]" . || true

Repository: boundlessfi/bounties

Length of output: 41151


🌐 Web query:

TypeScript TS2308 already exported a member named re-export conflicts with exported declaration when using export * and export { ... as ... } from different modules

💡 Result:

TS2308 (“Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity”) happens when, in a single module (file), you create two competing exports with the same name—commonly by combining export * from '...' with another re-export that also exports that same identifier. What’s going on - export * from 'other-module' re-exports all exported members from the target module. - If, in the same re-exporting file, you also re-export that same identifier again (either directly, or via export {... as... } from...), TypeScript sees the name collision in the current module’s export surface and raises TS2308, telling you to disambiguate by explicitly re-exporting [1]. Concrete example of the collision - If module “apples” and module “oranges” both export Fruit, and you write: - export * from 'apples' - export * from 'oranges' then TS2308 is thrown because Fruit is now being exported twice from the same index/re-export module [1]. How to fix - Explicitly choose the source of the conflicting name: - export * from 'apples' - export * from 'oranges' - export { Fruit } from 'oranges' (or from 'apples') This “explicit re-export” strategy is exactly what the cited guidance recommends to resolve the ambiguity [1]. - Or, avoid export * for the conflicting surface by explicitly listing the exports you want to re-export (so you can prevent duplicates) [1]. - If you need to bring both versions in, rename one using export { OriginalName as NewName } from... so the exported identifiers no longer collide (the mechanism for using “as” renames is standard re-export guidance) [2]. So, to your query’s specific wording - The root issue is duplicate exported identifier names within the re-exporting module; the trigger pattern is “export *” plus another re-export that produces the same exported name [1]. Even if the second re-export uses export {... as... }, it will still fail if the resulting exported name matches something already exported via export * (i.e., it still produces a duplicate name).

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "---- tsconfig.json (and variants) ----"
ls -la tsconfig*.json 2>/dev/null || true
for f in tsconfig*.json; do
  [ -f "$f" ] && echo "===== $f =====" && sed -n '1,200p' "$f"
done

echo
echo "---- next.config.* ----"
ls -la next.config.* 2>/dev/null || true
for f in next.config.*; do
  [ -f "$f" ] && echo "===== $f =====" && sed -n '1,200p' "$f"
done

Repository: boundlessfi/bounties

Length of output: 1105


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Running TypeScript typecheck (tsc)..."
# Use local npx/tsc from node_modules (no installs in sandbox)
npx --yes tsc -p tsconfig.json --noEmit --pretty false 2>&1 | tee /tmp/tsc.out | head -n 200

echo
echo "Filtered: TS2308 or mockProjects/mockBounties diagnostics"
rg -n "TS2308|already exported a member named|mockProjects|mockBounties" /tmp/tsc.out || true

Repository: boundlessfi/bounties

Length of output: 164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Running TypeScript typecheck (tsc) with redirected output..."
npx --yes tsc -p tsconfig.json --noEmit --pretty false > /tmp/tsc.out 2>&1 || true

echo "---- tsc output (first 120 lines) ----"
head -n 120 /tmp/tsc.out

echo
echo "---- Filter for duplicate export / TS2308 ----"
rg -n "TS2308|already exported a member named|mockProjects|mockBounties" /tmp/tsc.out || true

Repository: boundlessfi/bounties

Length of output: 18481


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "lib/mock/index\.ts|lib/mock/" /tmp/tsc.out || true

Repository: boundlessfi/bounties

Length of output: 46


Avoid duplicate mockProjects/mockBounties re-exports in lib/mock/index.ts.

lib/mock/index.ts already re-exports mockProjects/mockBounties via export * from "./projects" and export * from "./bounties", and then re-exports the same names again via export { oldMockProjects as mockProjects, oldMockBounties as mockBounties } from "./discover". This export-surface duplication is the classic pattern that can trigger TypeScript’s TS2308 (“already exported a member named …”); in the current repo typecheck output it didn’t surface, but the cleanup is still recommended to prevent ambiguity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/mock/index.ts` around lines 1 - 9, The file re-exports mockProjects and
mockBounties twice causing a potential TS2308 conflict: remove or rename the
duplicate re-exports in lib/mock/index.ts so the names from "./projects" and
"./bounties" are not shadowed by the aliases from "./discover"; specifically,
either delete the block exporting oldMockProjects as mockProjects and
oldMockBounties as mockBounties, or change that export to export {
oldMockProjects, oldMockBounties } (keeping their original names) so the unique
symbols mockProjects and mockBounties come only from "./projects" and
"./bounties".

Comment thread lib/mock/leaderboard.ts
Comment thread lib/mock/leaderboard.ts
Comment thread lib/services/withdrawal.ts
Comment thread lib/services/withdrawal.ts

@Benjtalkshow Benjtalkshow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean refactor. Every domain has its own file under lib/mock/, factory pattern is consistently applied with makeX(overrides?) signatures, and the barrel index re-exports everything so consumers can do either from "@/lib/mock" or from "@/lib/mock/projects". All six old lib/mock-*.ts files are deleted, no stragglers.
Typecheck and lint clean. Merging this in. Thanks.

@Benjtalkshow
Benjtalkshow merged commit 0e4b888 into boundlessfi:main May 28, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consolidate the mock data files into lib/mock/ with a factory pattern

2 participants