Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v4.0.7 #1883

Merged
merged 56 commits into from
Feb 3, 2025
Merged

Release v4.0.7 #1883

merged 56 commits into from
Feb 3, 2025

Conversation

jaybuidl
Copy link
Member

@jaybuidl jaybuidl commented Feb 3, 2025

Summary by CodeRabbit

  • New Features

    • Launched revamped navigation with dedicated Profile and Jurors pages, including a clickable Jurors Leaderboard button.
    • Introduced a dynamic appeal banner that displays real-time countdown information during appeal periods.
    • Added a new Stats component to display statistical information about jurors, along with filtering options.
    • Implemented a new Search component for enhanced search functionality on the Jurors page.
    • Introduced a new DisplayJurors component for paginated juror listings based on coherence scores.
  • UI Enhancements

    • Improved styling and layout across juror cards and profile views for clearer, more responsive displays.
    • Enhanced search and filtering capabilities on the Jurors page for a smoother browsing experience.
    • Updated header titles and component structures for better user experience and consistency.
    • Adjusted margin and padding for improved visual spacing in various components.
    • Simplified JSX structures in components for cleaner code and improved readability.
    • Enhanced visual feedback and layout adjustments in the TopSearch component.
  • Data Handling Improvements

    • Transitioned from a score-based system to a coherence percentage system for user level calculations.
    • Updated methods to handle juror data more effectively, ensuring type consistency and clarity.
    • Enhanced the coherence percentage calculations and adjusted related components accordingly.

Harman-singh-waraich and others added 30 commits January 16, 2025 21:04
Copy link
Contributor

coderabbitai bot commented Feb 3, 2025

Walkthrough

Updates include adding a new CODEOWNERS file to define team ownership, upgrading GitHub Actions workflows with new action versions and permissions, and revising dependency configurations (Yarn, Node, Docker). Deprecated bot-pinner files have been removed. In the kleros-sdk and subgraph projects, new constants, schema fields, and functions were added to streamline dispute answer handling and juror tracking. The web project underwent extensive UI and routing changes—including renaming Dashboard to Profile, updating routes to Jurors/Profile, introducing new components and hooks, and refining type usage (e.g., bigint, string) in voting and juror interfaces.

Changes

File(s) Change Summaries
.github/CODEOWNERS, .github/workflows/* Added CODEOWNERS file; upgraded action versions; added permissions; removed dependabot-automerge workflow.
.yarnrc.yml, package.json, services/bots/base/Dockerfile, bot-pinner/package.json Updated Yarn and Node versions; upgraded package manager versions; updated Docker base image digest; removed bot-pinner workspace.
bot-pinner/* Removed deprecated bot-pinner files including Dockerfiles, .gitignore, compose files, requirements, README, and peer/tooling scripts.
kleros-sdk/src/dataMappings/utils/* Introduced new refusal-to-arbitrate constant; made answer ID required; integrated refusal answer into template population.
subgraph/core/*, subgraph/package.json Extended GraphQL schema with new fields (e.g., userAddress, Answer type); added functions and methods for improved juror tracking and data updates.
web/* Renamed Dashboard to Profile; updated routes to Jurors/Profile; added new UI components and hooks; adjusted layouts, styling, and types (bigint, string) in voting and juror info components.
web/src/utils/* Added getCoherencePercent utility; updated getVoteChoice for Answer objects with bigint conversion; revised user level calculation to use coherence percentages.

Sequence Diagram(s)

sequenceDiagram
    participant C as Component
    participant B as GraphQLBatcher
    participant D as dtrBatchExec
    participant E as coreBatchExec
    participant S as GraphQL Server

    C->>B: Submit GraphQL query with flag
    alt DisputeTemplate query
      B->>D: Route query to DTR executor
      D->>S: Send batched query
      S-->>D: Return results
      D-->>B: Return batched response
    else Other query
      B->>E: Route query to Core executor
      E->>S: Send batched query
      S-->>E: Return results
      E-->>B: Return batched response
    end
    B-->>C: Return aggregated results
Loading
sequenceDiagram
    participant U as User
    participant SC as Search Component
    participant H as useJurorsByCoherenceScore Hook
    participant G as GraphQL Batch Executor
    participant D as DisplayJurors Component

    U->>SC: Enter search query
    SC->>H: Update query parameters
    H->>G: Fetch juror data based on coherence score
    G-->>H: Return juror data
    H-->>D: Provide processed juror list
    D->>U: Render paginated juror leaderboard
Loading

Suggested labels

Type: Maintenance :construction:, Type: Toolchain ⚒️, dependencies

Suggested reviewers

  • alcercu

Poem

I'm a little rabbit hopping through code at night,
Skipping over workflows, making everything light.
I nibble on updates and crunch through the lines,
With every change, our repo more brightly shines.
Hop along with me, let’s code with delight! 🐇


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

netlify bot commented Feb 3, 2025

Deploy Preview for kleros-v2-testnet ready!

Name Link
🔨 Latest commit 3e1118d
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-testnet/deploys/67a131765750020008149f43
😎 Deploy Preview https://deploy-preview-1883--kleros-v2-testnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Feb 3, 2025

Deploy Preview for kleros-v2-university ready!

Name Link
🔨 Latest commit 3e1118d
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-university/deploys/67a131765459df000835d4e7
😎 Deploy Preview https://deploy-preview-1883--kleros-v2-university.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Feb 3, 2025

Deploy Preview for kleros-v2-neo-devtools ready!

Name Link
🔨 Latest commit 3e1118d
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-neo-devtools/deploys/67a13176fcd99e0008e4f09f
😎 Deploy Preview https://deploy-preview-1883--kleros-v2-neo-devtools.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Feb 3, 2025

Deploy Preview for kleros-v2-testnet-devtools ready!

Name Link
🔨 Latest commit 3e1118d
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-testnet-devtools/deploys/67a13176c21a980008126d7d
😎 Deploy Preview https://deploy-preview-1883--kleros-v2-testnet-devtools.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

netlify bot commented Feb 3, 2025

Deploy Preview for kleros-v2-neo ready!

Name Link
🔨 Latest commit 3e1118d
🔍 Latest deploy log https://app.netlify.com/sites/kleros-v2-neo/deploys/67a13176b6e6650008e3c213
😎 Deploy Preview https://deploy-preview-1883--kleros-v2-neo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (28)
web/src/pages/Cases/CaseDetails/Timeline.tsx (2)

88-88: Fix typo in comment.

The comment contains a typo: "loosing" should be "losing".

-    // only show if loosing option was funded and winner needs funding, else no action is needed from user
+    // only show if losing option was funded and winner needs funding, else no action is needed from user

81-99: Consider enhancing error handling and documentation.

The AppealBanner component could benefit from:

  1. Error boundaries to handle potential hook failures
  2. More explicit documentation about the business logic behind the text conditions
  3. Type safety for the countdown values

Consider wrapping the component with error boundaries and adding JSDoc comments:

/**
 * Displays a banner during the appeal period with countdown information.
 * The banner shows different messages based on:
 * 1. Loser funding phase: Shows time left for losing options to be funded
 * 2. Winner funding phase: Shows time left for winning option to be funded,
 *    but only if losing options were previously funded
 */
const AppealBanner: React.FC = () => {
  try {
    const { loserSideCountdown, winnerSideCountdown } = useCountdownContext();
    const { fundedChoices } = useFundingContext();
    // ... rest of the component
  } catch (error) {
    console.error('Failed to render AppealBanner:', error);
    return null;
  }
};
web/src/layout/Header/navbar/Menu/Settings/General/WalletAndProfile.tsx (1)

48-61: Consider making the profile URL more maintainable.

The hardcoded profile URL "/profile/1/desc/all" could be problematic:

  • The "1" appears to be a hardcoded user ID
  • URL structure is hardcoded and might change

Consider:

  1. Using route constants
  2. Making the URL dynamic based on the user's ID
  3. Using a URL builder utility
-      <ReStyledArrowLink to={"/profile/1/desc/all"} onClick={toggleIsSettingsOpen}>
+      <ReStyledArrowLink to={buildProfileUrl(userId)} onClick={toggleIsSettingsOpen}>
web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)

94-98: Consider more explicit prop passing.

While prop spreading works, explicit prop passing would be more maintainable and self-documenting.

Consider:

-        <General {...{ toggleIsSettingsOpen }} />
+        <General toggleIsSettingsOpen={toggleIsSettingsOpen} />
-        <NotificationSettings {...{ toggleIsSettingsOpen }} />
+        <NotificationSettings toggleIsSettingsOpen={toggleIsSettingsOpen} />
web/src/utils/getVoteChoice.ts (1)

4-6: Consider validating the vote parameter for proper hexadecimal format.
By directly converting vote and answer.id to BigInt, runtime errors can occur if either string is malformed. Consider adding a small validation step or error handling to safeguard against invalid hex strings.

 export const getVoteChoice = (vote: string, answers: Answer[]) => {
+  if (!/^0x[0-9a-fA-F]+$/.test(vote)) {
+    return `Invalid vote ID: ${vote}`;
+  }
   const selectedAnswer = answers?.find((answer) => BigInt(answer.id) === BigInt(vote));
   ...
web/src/utils/userLevelCalculation.ts (1)

17-20: Handle unexpected formats in coherencePercentage.
Currently, parseFloat(percentage.replace("%", "")) can fail or yield NaN if the string is not in the expected format (e.g., "85" or "85.5% Extra"). You might consider adding stricter checks or fallback values for edge cases.

 const percentageToNumber = (percentage: string) => {
+  const sanitized = percentage.trim().replace("%", "");
+  const parsed = parseFloat(sanitized);
+  return Number.isNaN(parsed) ? 0 : parsed;
 };
subgraph/core/src/entities/ClassicRound.ts (1)

43-47: Updating vote counts directly on Answer entities is a robust design.
By ensuring each Answer entity tracks its own counts:

  • It simplifies the logic in ClassicRound.
  • It centralizes data, reducing array-based indexing errors.

Additionally, watch for:

  • Persistent updates if round.winningChoice or tie logic is changed in the future.
  • Handling large delta changes properly to avoid integer overflow (though unlikely with BigInt).

Also applies to: 49-51, 64-64

web/src/context/GraphqlBatcher.tsx (1)

25-39: Consider using await for consistency in the async function.

Currently, the fetch function returns a promise from request(...).then(...). Since this function is already marked async, using await instead of .then() would streamline the code and error handling:

-const result = request(url, document, variables).then((res) => ({
-  data: res,
-})) as Promise<ExecutionResult>;
-return result;
+const result = await request(url, document, variables);
+return { data: result };
web/src/hooks/useClassicAppealContext.tsx (2)

29-30: Allow optional clearing of selected option.

Currently, setSelectedOption only accepts Option. Consider allowing undefined for scenarios where clearing the selection is necessary. For instance:

- setSelectedOption: (arg0: Option) => void;
+ setSelectedOption: (option?: Option) => void;

Also applies to: 64-64


135-151: Validate BigInt equality usage.

When comparing two BigInt values, using === is more idiomatic than ==. Both sides are already converted to BigInt, so strict equality is valid:

- BigInt(classicAnswer.answerId) == BigInt(answer.id)
+ BigInt(classicAnswer.answerId) === BigInt(answer.id)
web/src/components/JurorsLeaderboardButton.tsx (1)

10-10: Consider extracting the URL path as a constant.

The hardcoded URL path /jurors/1/desc/all should be extracted as a constant to improve maintainability and reusability.

+const JURORS_LEADERBOARD_PATH = "/jurors/1/desc/all";
+
 const JurorsLeaderboardButton: React.FC = () => {
   return (
-    <InternalLink to={"/jurors/1/desc/all"}>
+    <InternalLink to={JURORS_LEADERBOARD_PATH}>
kleros-sdk/src/dataMappings/utils/populateTemplate.ts (1)

14-18: Consider using nullish coalescing for the fallback.

The filtering logic is well-implemented, using BigInt for safe number comparison. However, consider using nullish coalescing (??) instead of logical OR (||) for the fallback array, as it's more precise for handling undefined and null cases.

-    ...((dispute as DisputeDetails).answers.filter((answer) => answer.id && BigInt(answer.id) !== BigInt(0)) || []),
+    ...((dispute as DisputeDetails).answers.filter((answer) => answer.id && BigInt(answer.id) !== BigInt(0)) ?? []),
web/src/pages/Jurors/Stats.tsx (1)

36-39: Consider making the Stats component more flexible.

The Stats component is currently hardcoded to display only "Total Jurors". Consider making it more flexible to display different types of statistics.

 export interface IStats {
   totalJurors?: number;
+  label?: string;
+  extraLabel?: string;
 }

-const Stats: React.FC<IStats> = ({ totalJurors }) => {
+const Stats: React.FC<IStats> = ({ totalJurors, label = "Total", extraLabel = "Jurors" }) => {
   const value = !isUndefined(totalJurors) ? totalJurors : undefined;
-  return <Field label="Total" value={value} extraLabel="Jurors" />;
+  return <Field label={label} value={value} extraLabel={extraLabel} />;
 };
web/src/hooks/queries/useJurorsByCoherenceScore.ts (1)

30-49: Consider adjusting the staleTime configuration.

The staleTime: Infinity setting prevents data refetching entirely. Consider using a finite staleTime to ensure data freshness, especially for leaderboard data that may change frequently.

-    staleTime: Infinity,
+    staleTime: 5 * 60 * 1000, // 5 minutes
web/src/pages/Jurors/StatsAndFilters.tsx (2)

30-33: Consider memoizing the callback function.

The handleOrderChange callback could be memoized using useCallback to prevent unnecessary re-renders of the DropdownSelect component.

-  const handleOrderChange = (value: string | number) => {
+  const handleOrderChange = React.useCallback((value: string | number) => {
     const encodedFilter = encodeURIFilter({ ...filterObject });
     navigate(`${location}/1/${value}/${encodedFilter}?${searchParams.toString()}`);
-  };
+  }, [filterObject, location, navigate, searchParams]);

41-44: Enhance type safety with constants for order values.

Consider defining constants for the order values to improve maintainability and type safety.

+const ORDER = {
+  DESC: "desc",
+  ASC: "asc",
+} as const;
+
+type Order = typeof ORDER[keyof typeof ORDER];

 items={[
-  { value: "desc", text: "1st to last" },
-  { value: "asc", text: "Last to 1st" },
+  { value: ORDER.DESC, text: "1st to last" },
+  { value: ORDER.ASC, text: "Last to 1st" },
 ]}
web/src/pages/Jurors/Search.tsx (1)

32-45: Consider memoizing the debounced callback.

While the debounce implementation is correct, the callback function could be memoized to prevent unnecessary recreations.

+ const debouncedCallback = useCallback(
    () => {
      if (initialRenderRef.current && isEmpty(search)) {
        initialRenderRef.current = false;
        return;
      }
      initialRenderRef.current = false;
      const newFilters = isEmpty(search) ? { ...filterObject } : { ...filterObject, id: search };
      const encodedFilter = encodeURIFilter(newFilters);
      navigate(`${location}/1/${order}/${encodedFilter}?${searchParams.toString()}`);
    },
+   [search, filterObject, order, location, searchParams, navigate]
+ );

  useDebounce(
-   () => {
-     if (initialRenderRef.current && isEmpty(search)) {
-       initialRenderRef.current = false;
-       return;
-     }
-     initialRenderRef.current = false;
-     const newFilters = isEmpty(search) ? { ...filterObject } : { ...filterObject, id: search };
-     const encodedFilter = encodeURIFilter(newFilters);
-     navigate(`${location}/1/${order}/${encodedFilter}?${searchParams.toString()}`);
-   },
+   debouncedCallback,
    500,
    [search]
  );
web/src/pages/Cases/CaseDetails/Appeal/Classic/index.tsx (1)

50-50: Consider using a more type-safe approach for amount.

The type assertion as \${number}`` could be replaced with proper runtime validation.

- <Fund amount={amount as `${number}`} setAmount={setAmount} setIsOpen={setIsPopupOpen} />
+ <Fund 
+   amount={/^\d+$/.test(amount) ? amount : "0"} 
+   setAmount={setAmount} 
+   setIsOpen={setIsPopupOpen} 
+ />
web/src/components/ExtraStatsDisplay.tsx (1)

31-37: Consider adding responsive styles for mobile.

The ContentContainer might benefit from additional mobile-specific styles to ensure optimal display on smaller screens.

const ContentContainer = styled.div`
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  text-align: center;
+ @media (max-width: 768px) {
+   width: 100%;
+   justify-content: center;
+ }
`;
web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageTwo.tsx (1)

57-58: Consider using nullish coalescing for paidFee.

The current fallback to 0 could mask potential bugs if paidFee is undefined unexpectedly.

-  funding={BigInt(choice.paidFee ?? 0)}
+  funding={choice.paidFee ? BigInt(choice.paidFee) : 0n}
kleros-sdk/src/dataMappings/utils/disputeDetailsSchema.ts (1)

36-36: Consider adding min/max length validation for id.

The regex ensures hex format but doesn't limit the length of the id.

-  id: z.string().regex(/^0x[0-9a-fA-F]+$/),
+  id: z.string().regex(/^0x[0-9a-fA-F]+$/).min(3).max(66),
web/src/pages/Home/TopJurors/JurorCard/MobileCard.tsx (2)

80-86: Consider using BigInt type for vote counts.

The change from number to string suggests these values represent large numbers. Consider using bigint type instead of string for better type safety and numerical operations.

interface IMobileCard {
  rank: number;
  address: string;
-  totalCoherentVotes: string;
-  totalResolvedVotes: string;
-  totalResolvedDisputes: string;
+  totalCoherentVotes: bigint;
+  totalResolvedVotes: bigint;
+  totalResolvedDisputes: bigint;
}

102-102: Avoid props spreading for better maintainability.

Using the spread operator for props can make it harder to track prop dependencies. Consider explicitly passing each prop for better maintainability.

-<JurorLevel {...{ totalCoherentVotes, totalResolvedVotes, totalResolvedDisputes }} />
+<JurorLevel
+  totalCoherentVotes={totalCoherentVotes}
+  totalResolvedVotes={totalResolvedVotes}
+  totalResolvedDisputes={totalResolvedDisputes}
+/>
web/src/pages/Jurors/DisplayJurors.tsx (1)

84-96: Consider adding error state handling.

While loading states are handled well, there's no explicit error state handling for failed data fetches.

+  const { data: queryJurors, error } = useJurorsByCoherenceScore(...);
+  if (error) {
+    return <StyledLabel>Failed to load jurors. Please try again.</StyledLabel>;
+  }
web/src/pages/Cases/CaseDetails/MaintenanceButtons/DrawButton.tsx (2)

34-34: Consider moving isUniversity to component scope.

The isUniversity constant is defined outside the component, which could cause issues with hot reloading or testing.

-const isUniversity = isKlerosUniversity();
 const DrawButton: React.FC<IDrawButton> = ({ id, numberOfVotes, setIsOpen, period }) => {
+  const isUniversity = isKlerosUniversity();

Also applies to: 69-70


108-110: Add input validation feedback.

Consider adding visual feedback for invalid juror addresses in university mode.

-        <Field placeholder="Juror Address" onChange={(e) => setDrawJuror(e.target.value)} value={drawJuror} />
+        <Field
+          placeholder="Juror Address"
+          onChange={(e) => setDrawJuror(e.target.value)}
+          value={drawJuror}
+          error={drawJuror && !isAddress(drawJuror) ? "Invalid address" : undefined}
+        />
web/src/components/Popup/MiniGuides/JurorLevels.tsx (1)

38-38: Maintain consistency in percentage symbol usage.

The percentage symbol usage is inconsistent across level descriptions:

  • Level 1: "0-70%"
  • Level 2: "70%"
  • Level 3: "80%"

Consider using the same format throughout.

-      "Level 1: Jurors with ≥ 1 case arbitrated with 0-70% of coherent votes.",
+      "Level 1: Jurors with ≥ 1 case arbitrated with 0-70% coherent votes.",
-    paragraphs: ["Level 2: Jurors with ≥ 3 cases arbitrated with more than 70% coherent votes."],
+    paragraphs: ["Level 2: Jurors with ≥ 3 cases arbitrated with >70% coherent votes."],
-    paragraphs: ["Level 3: Jurors with ≥ 7 cases arbitrated with more than 80% of coherent votes."],
+    paragraphs: ["Level 3: Jurors with ≥ 7 cases arbitrated with >80% coherent votes."],

Also applies to: 43-43, 47-47

.github/workflows/codeql.yml (1)

44-44: Remove Trailing Whitespace
The static analysis tool detected trailing spaces on this line. Please remove the extra spaces to maintain proper YAML formatting standards.

Suggested diff:

-        egress-policy: audit  
+        egress-policy: audit
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 44-44: trailing spaces

(trailing-spaces)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be6d5f9 and 2730163.

⛔ Files ignored due to path filters (5)
  • .yarn/releases/yarn-4.6.0.cjs is excluded by !**/.yarn/**
  • bot-pinner/avatar-default.png is excluded by !**/*.png
  • bot-pinner/docs/image.png is excluded by !**/*.png
  • web/src/assets/svgs/icons/ranking.svg is excluded by !**/*.svg
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (100)
  • .github/CODEOWNERS (1 hunks)
  • .github/workflows/codeql.yml (1 hunks)
  • .github/workflows/contracts-testing.yml (1 hunks)
  • .github/workflows/dependabot-automerge.yml (0 hunks)
  • .github/workflows/dependency-review.yml (2 hunks)
  • .github/workflows/deploy-bots.yml (1 hunks)
  • .github/workflows/deploy-subgraph.yml (2 hunks)
  • .github/workflows/scorecards.yml (3 hunks)
  • .github/workflows/sentry-release.yml (2 hunks)
  • .github/workflows/sonarcloud.yml (1 hunks)
  • .yarnrc.yml (1 hunks)
  • README.md (1 hunks)
  • bot-pinner/.gitignore (0 hunks)
  • bot-pinner/Dockerfile (0 hunks)
  • bot-pinner/Dockerfile-dappnode (0 hunks)
  • bot-pinner/README.md (0 hunks)
  • bot-pinner/dappnode_package.json (0 hunks)
  • bot-pinner/docker-compose-dappnode.yml (0 hunks)
  • bot-pinner/docker-compose.yml (0 hunks)
  • bot-pinner/package.json (0 hunks)
  • bot-pinner/requirements.txt (0 hunks)
  • bot-pinner/src/add_hashes.py (0 hunks)
  • bot-pinner/src/peers.txt (0 hunks)
  • bot-pinner/src/tooling.py (0 hunks)
  • kleros-app/package.json (1 hunks)
  • kleros-sdk/package.json (1 hunks)
  • kleros-sdk/src/dataMappings/utils/disputeDetailsSchema.ts (1 hunks)
  • kleros-sdk/src/dataMappings/utils/populateTemplate.ts (2 hunks)
  • kleros-sdk/src/utils/getDispute.ts (0 hunks)
  • package.json (1 hunks)
  • services/bots/base/Dockerfile (1 hunks)
  • subgraph/core/schema.graphql (3 hunks)
  • subgraph/core/src/DisputeKitClassic.ts (2 hunks)
  • subgraph/core/src/KlerosCore.ts (3 hunks)
  • subgraph/core/src/datapoint.ts (3 hunks)
  • subgraph/core/src/entities/ClassicContribution.ts (1 hunks)
  • subgraph/core/src/entities/ClassicRound.ts (4 hunks)
  • subgraph/core/src/entities/User.ts (1 hunks)
  • subgraph/package.json (6 hunks)
  • web-devtools/package.json (1 hunks)
  • web/README.md (1 hunks)
  • web/package.json (2 hunks)
  • web/src/app.tsx (2 hunks)
  • web/src/components/BlueIconTextButtonContainer.tsx (1 hunks)
  • web/src/components/EvidenceCard.tsx (2 hunks)
  • web/src/components/ExtraStatsDisplay.tsx (3 hunks)
  • web/src/components/HowItWorks.tsx (2 hunks)
  • web/src/components/JurorsLeaderboardButton.tsx (1 hunks)
  • web/src/components/Popup/MiniGuides/JurorLevels.tsx (2 hunks)
  • web/src/components/Verdict/DisputeTimeline.tsx (2 hunks)
  • web/src/context/GraphqlBatcher.tsx (2 hunks)
  • web/src/hooks/queries/useClassicAppealQuery.ts (1 hunks)
  • web/src/hooks/queries/useJurorsByCoherenceScore.ts (1 hunks)
  • web/src/hooks/queries/useTopUsersByCoherenceScore.ts (0 hunks)
  • web/src/hooks/queries/useTotalLeaderboardJurors.ts (1 hunks)
  • web/src/hooks/useClassicAppealContext.tsx (4 hunks)
  • web/src/layout/Header/navbar/Explore.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/General/WalletAndProfile.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/General/index.tsx (2 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1 hunks)
  • web/src/layout/Header/navbar/Menu/Settings/index.tsx (1 hunks)
  • web/src/pages/Cases/CaseDetails/Appeal/AppealHistory.tsx (2 hunks)
  • web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx (3 hunks)
  • web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageOne.tsx (2 hunks)
  • web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageTwo.tsx (2 hunks)
  • web/src/pages/Cases/CaseDetails/Appeal/Classic/StageExplainer.tsx (3 hunks)
  • web/src/pages/Cases/CaseDetails/Appeal/Classic/index.tsx (3 hunks)
  • web/src/pages/Cases/CaseDetails/Appeal/index.tsx (1 hunks)
  • web/src/pages/Cases/CaseDetails/MaintenanceButtons/DrawButton.tsx (2 hunks)
  • web/src/pages/Cases/CaseDetails/Timeline.tsx (2 hunks)
  • web/src/pages/Cases/CaseDetails/Voting/Classic/Commit.tsx (2 hunks)
  • web/src/pages/Cases/CaseDetails/Voting/Classic/OptionsContainer.tsx (4 hunks)
  • web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx (5 hunks)
  • web/src/pages/Cases/CaseDetails/Voting/VotesDetails/AccordionTitle.tsx (3 hunks)
  • web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx (1 hunks)
  • web/src/pages/Cases/CaseDetails/index.tsx (2 hunks)
  • web/src/pages/Courts/CourtDetails/TopSearch.tsx (2 hunks)
  • web/src/pages/Home/Community/index.tsx (1 hunks)
  • web/src/pages/Home/CourtOverview/Stats.tsx (1 hunks)
  • web/src/pages/Home/TopJurors/Header/DesktopHeader.tsx (2 hunks)
  • web/src/pages/Home/TopJurors/Header/MobileHeader.tsx (2 hunks)
  • web/src/pages/Home/TopJurors/JurorCard/Coherence.tsx (2 hunks)
  • web/src/pages/Home/TopJurors/JurorCard/DesktopCard.tsx (3 hunks)
  • web/src/pages/Home/TopJurors/JurorCard/JurorLevel.tsx (2 hunks)
  • web/src/pages/Home/TopJurors/JurorCard/JurorTitle.tsx (3 hunks)
  • web/src/pages/Home/TopJurors/JurorCard/MobileCard.tsx (2 hunks)
  • web/src/pages/Home/TopJurors/JurorCard/index.tsx (1 hunks)
  • web/src/pages/Home/TopJurors/index.tsx (6 hunks)
  • web/src/pages/Jurors/DisplayJurors.tsx (1 hunks)
  • web/src/pages/Jurors/Search.tsx (1 hunks)
  • web/src/pages/Jurors/Stats.tsx (1 hunks)
  • web/src/pages/Jurors/StatsAndFilters.tsx (1 hunks)
  • web/src/pages/Jurors/index.tsx (1 hunks)
  • web/src/pages/Profile/JurorInfo/Header.tsx (2 hunks)
  • web/src/pages/Profile/JurorInfo/JurorRewards.tsx (1 hunks)
  • web/src/pages/Profile/JurorInfo/index.tsx (2 hunks)
  • web/src/pages/Profile/index.tsx (3 hunks)
  • web/src/utils/getCoherencePercent.tsx (1 hunks)
  • web/src/utils/getVoteChoice.ts (1 hunks)
  • web/src/utils/userLevelCalculation.ts (1 hunks)
💤 Files with no reviewable changes (15)
  • bot-pinner/Dockerfile-dappnode
  • bot-pinner/Dockerfile
  • bot-pinner/src/peers.txt
  • bot-pinner/dappnode_package.json
  • bot-pinner/package.json
  • bot-pinner/requirements.txt
  • bot-pinner/README.md
  • .github/workflows/dependabot-automerge.yml
  • bot-pinner/docker-compose-dappnode.yml
  • bot-pinner/.gitignore
  • web/src/hooks/queries/useTopUsersByCoherenceScore.ts
  • bot-pinner/src/add_hashes.py
  • bot-pinner/docker-compose.yml
  • bot-pinner/src/tooling.py
  • kleros-sdk/src/utils/getDispute.ts
✅ Files skipped from review due to trivial changes (11)
  • web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
  • web/README.md
  • .yarnrc.yml
  • web/src/pages/Courts/CourtDetails/TopSearch.tsx
  • services/bots/base/Dockerfile
  • web/src/pages/Profile/JurorInfo/JurorRewards.tsx
  • web/src/pages/Profile/index.tsx
  • .github/workflows/dependency-review.yml
  • .github/workflows/sonarcloud.yml
  • .github/workflows/deploy-subgraph.yml
  • .github/CODEOWNERS
🧰 Additional context used
📓 Learnings (3)
web/src/pages/Home/TopJurors/JurorCard/Coherence.tsx (1)
Learnt from: Harman-singh-waraich
PR: kleros/kleros-v2#1739
File: web/src/pages/Home/TopJurors/JurorCard/Coherency.tsx:22-26
Timestamp: 2024-11-12T04:49:43.234Z
Learning: In the `Coherency` component (`web/src/pages/Home/TopJurors/JurorCard/Coherency.tsx`), `totalResolvedVotes` is always greater than or equal to `totalCoherentVotes`. When both are zero, `0/0` results in `NaN`, which is acceptable in this context.
web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx (1)
Learnt from: Harman-singh-waraich
PR: kleros/kleros-v2#1839
File: web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx:141-149
Timestamp: 2025-01-17T11:11:32.535Z
Learning: In the Kleros v2 codebase, using -1 as an initial value for choice tracking is preferred over undefined on the client-side to explicitly indicate that no option has been selected. This value is only used internally and never reaches the contract.
web/src/pages/Home/TopJurors/JurorCard/index.tsx (1)
Learnt from: Harman-singh-waraich
PR: kleros/kleros-v2#1739
File: web/src/pages/Home/TopJurors/JurorCard/Coherency.tsx:22-26
Timestamp: 2024-11-12T04:49:43.234Z
Learning: In the `Coherency` component (`web/src/pages/Home/TopJurors/JurorCard/Coherency.tsx`), `totalResolvedVotes` is always greater than or equal to `totalCoherentVotes`. When both are zero, `0/0` results in `NaN`, which is acceptable in this context.
🪛 YAMLlint (1.35.1)
.github/workflows/codeql.yml

[error] 44-44: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Redirect rules - kleros-v2-neo
  • GitHub Check: Header rules - kleros-v2-neo
  • GitHub Check: Pages changed - kleros-v2-neo
  • GitHub Check: Redirect rules - kleros-v2-testnet-devtools
  • GitHub Check: Header rules - kleros-v2-testnet-devtools
  • GitHub Check: Pages changed - kleros-v2-testnet-devtools
  • GitHub Check: Redirect rules - kleros-v2-testnet
  • GitHub Check: Header rules - kleros-v2-testnet
  • GitHub Check: Pages changed - kleros-v2-testnet
🔇 Additional comments (114)
web/src/pages/Cases/CaseDetails/Timeline.tsx (3)

6-7: LGTM!

The new imports are well-organized and properly utilized throughout the code.

Also applies to: 9-9, 16-19


51-64: LGTM!

The styled component is well-structured with proper use of theme variables and responsive design principles.


72-72: LGTM!

The conditional rendering of AppealBanner is clean and properly tied to the appeal period.

Also applies to: 76-76

web/src/layout/Header/navbar/Menu/Settings/General/WalletAndProfile.tsx (2)

1-10: LGTM!

The imports are well-organized and include all necessary dependencies.


12-46: LGTM!

The styled components are well-structured and follow best practices:

  • Consistent use of theme variables
  • Proper flexbox layout
  • Responsive hover effects
  • Clear component hierarchy
web/src/layout/Header/navbar/Menu/Settings/General/index.tsx (3)

1-11: LGTM!

The imports are clean and include all necessary dependencies.


36-53: LGTM!

The styling changes improve component spacing and alignment:

  • Reduced button margin for better vertical rhythm
  • Updated container padding for consistent spacing
  • Added gap for better component separation

60-82: LGTM!

The component changes improve structure and maintainability:

  • Proper prop typing with ISettings
  • Clean integration of WalletAndProfile
  • Simplified component hierarchy
web/src/pages/Cases/CaseDetails/Voting/VotesDetails/AccordionTitle.tsx (4)

11-11: LGTM!

The import of JurorTitle aligns with the refactoring to use a consistent component for displaying juror information.


94-96: LGTM!

The refactoring improves code maintainability by:

  • Using a dedicated component for juror information display
  • Encapsulating address formatting logic

89-89: Verify the profile route structure.

The URL structure has been updated from Dashboard to Profile. Let's verify this change is consistent with the routing configuration.

✅ Verification successful

Profile route structure verified.

  • The route definition in web/src/app.tsx specifies path="profile/:page/:order/:filter", which correctly maps /profile/1/desc/all to { page: 1, order: "desc", filter: "all" }.
  • All instances referencing the profile route, including the profileLink constructed in AccordionTitle.tsx, consistently use the updated structure with an optional query parameter (?address=${juror}) added for additional context.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the profile route structure.

# Find route definitions
echo "Route definitions:"
rg -A 2 'path.*profile'

# Find other profile links
echo -e "\nProfile links:"
rg -A 2 'to=.*profile'

Length of output: 1809


74-74: Verify the getVoteChoice function signature.

The change suggests that getVoteChoice now expects a string parameter instead of a number. Let's verify this change is consistent across the codebase.

✅ Verification successful

I'll run a follow-up script to get the full definition of getVoteChoice using rg, so we can confirm the parameter types. Please see the script below.


Verified getVoteChoice signature and usage across the codebase.
The function is defined in web/src/utils/getVoteChoice.ts with a signature that explicitly expects a string (vote: string, answers: Answer[]). All invocations, including the update in the VoteStatus component, consistently provide a string argument.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the getVoteChoice function signature and usage.

# Find the function definition
echo "Function definition:"
ast-grep --pattern 'export const getVoteChoice = ($_) => { $$$ }'

# Find all function calls
echo -e "\nFunction calls:"
rg -A 2 'getVoteChoice\(' 

Length of output: 1451


Script:

#!/bin/bash
echo "Searching for getVoteChoice definition using rg:"
rg -n "export const getVoteChoice =" --type ts

Length of output: 256

web/src/utils/getVoteChoice.ts (2)

1-1: Import statement looks fine.
No issues identified with importing Answer from "@kleros/kleros-sdk".


8-9: Return logic is clear and consistent.
If a matching answer isn't found, returning Answer 0x${vote} provides a descriptive fallback.

web/src/utils/userLevelCalculation.ts (3)

5-6: Introduction of Coherence Percentage fields looks correct.
Replacing minScore and maxScore with minCoherencePercentage and maxCoherencePercentage makes the interface more intuitive for percentage-based checks.


10-14: Verify coherence intervals for overlap or logical conflicts.
Multiple criteria entries share the same maxCoherencePercentage of 100, which might cause the first match to overshadow later entries. Verify that the priority ordering of the criteria is by design.


24-25: Boundary checks for coherence values appear consistent.
Using >= minCoherencePercentage and <= maxCoherencePercentage is appropriate for inclusive matching.

subgraph/core/src/entities/ClassicRound.ts (3)

3-4: Updated imports to include Answer and ZERO.
The addition of Answer for new entity logic and ZERO for default BigInt values is a clear approach.


27-38: ensureAnswer function centralizes answer existence handling well.
This function neatly avoids duplication by loading or creating an Answer entity. It’s good practice to return the entity immediately if found.


80-83: Fee contributions are handled elegantly by ensureAnswer.
The approach of incrementing paidFee within the associated Answer entity keeps logic consistent and localized. This promotes maintainability by centralizing fee data in each Answer.

web/src/context/GraphqlBatcher.tsx (4)

41-47: No immediate concerns.

The coreExecutor and dtrExecutor functions correctly defer to the fetch function, providing the respective GraphQL endpoints. This segregation of concerns is clear and maintainable.


49-50: LGTM on batch executors.

Creating separate batching executors for the two GraphQL endpoints is a clean approach, enabling easy scaling and customization for each endpoint's batching behavior.


54-63: Concurrent request strategy check.

Using Promise.all to process queries concurrently is generally efficient. However, ensure your GraphQL endpoints can handle simultaneous requests without throttling or performance issues. If needed, consider adjusting concurrency limits in future updates.


69-70: Approved data mapping.

The processed data correctly maps each response back to its query ID, maintaining clarity in the results.

web/src/hooks/useClassicAppealContext.tsx (3)

15-17: Good extension of the base interface.

Defining Option as an extension of Answer with the optional paidFee and funded fields is a flexible way to handle additional data. Also, updating OptionsContext to store an array of Option objects instead of strings is consistent with this approach.

Also applies to: 26-26


66-66: Efficient memo usage.

Using useMemo around getOptions prevents unnecessary recalculations when disputeDetails or data hasn’t changed, improving performance for complex queries.


109-109: Memo dependencies are consistent.

All necessary variables are included in the memo’s dependency array, reducing the risk of stale data.

web/src/utils/getCoherencePercent.tsx (1)

1-4: Handles zero denominator and returns percentage correctly.

The function properly guards against division by zero and uses integer down-rounding. If negative values are out of scope, this approach should suffice.

web/src/components/BlueIconTextButtonContainer.tsx (1)

4-24: LGTM!

The styled component is well-structured, follows best practices, and maintains consistent theming with proper hover transitions.

web/src/pages/Home/TopJurors/JurorCard/index.tsx (1)

9-11: Verify data handling for vote and dispute counts.

The type changes from number to string for vote and dispute counts suggest a change in data handling. Please ensure that:

  1. The string values are properly formatted and validated.
  2. Any calculations using these values (e.g., coherence percentage) handle string-to-number conversion correctly.
  3. The invariant that totalResolvedVotes >= totalCoherentVotes is maintained.
✅ Verification successful

Data handling for vote and dispute counts is properly managed.

  • The GraphQL backend defines the values as BigInt, and the frontend receives them as strings.
  • In components like JurorCard/Coherence.tsx and JurorCard/JurorLevel.tsx, the string values are consistently converted to numbers (using Number() or parseInt) before performing any calculations (e.g., via getCoherencePercent).
  • Although there isn’t an explicit invariant check in the UI for ensuring totalResolvedVotes >= totalCoherentVotes, the backend logic and the conversion in the frontend ensure that calculations (like the coherence percentage) handle the values appropriately.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify data handling for vote and dispute counts.

# Test: Search for string-to-number conversions of these values
rg -A 5 'totalCoherentVotes|totalResolvedVotes|totalResolvedDisputes'

# Test: Search for coherence percentage calculations
ast-grep --pattern $'getCoherencePercent($_, $_)'

Length of output: 24103

web/src/components/HowItWorks.tsx (1)

16-19: LGTM!

The replacement of the styled component with BlueIconTextButtonContainer maintains functionality while improving styling consistency across components.

kleros-sdk/src/dataMappings/utils/populateTemplate.ts (1)

3-3: LGTM!

The import of RefuseToArbitrateAnswer is correctly added to support the new filtering logic.

web/src/pages/Home/TopJurors/JurorCard/Coherence.tsx (2)

18-19: LGTM!

The type changes from number to string correctly align with the data format from the backend.


27-29: LGTM!

The coherence calculation is now handled by the dedicated getCoherencePercent utility function, which is a good practice for code reusability. The Number() conversion is safe as the types are guaranteed to be strings.

web/src/hooks/queries/useTotalLeaderboardJurors.ts (1)

20-31: Verify the hardcoded ID and consider making it configurable.

The query is well-structured, but the hardcoded id: 0 in the variables might be too rigid. Consider making it configurable through a parameter if there's a possibility of querying different counters in the future.

-export const useTotalLeaderboardJurors = () => {
+export const useTotalLeaderboardJurors = (counterId = 0) => {
   const { graphqlBatcher } = useGraphqlBatcher();

   return useQuery<TotalLeaderboardJurorsQuery>({
     queryKey: [`TotalLeaderboardJurors`],
     staleTime: Infinity,
     queryFn: async () =>
       await graphqlBatcher.fetch({
         id: crypto.randomUUID(),
         document: totalLeaderboardJurorsQuery,
         variables: {
-          id: 0,
+          id: counterId,
         },
       }),
   });
 };
✅ Verification successful

Action: Parameterize the Hardcoded ID in useTotalLeaderboardJurors Hook

The query currently passes a hardcoded ID (id: 0) in the variables. Confirming the code snippet from web/src/hooks/queries/useTotalLeaderboardJurors.ts, the behavior is as described. To improve flexibility and allow querying with different counter IDs if needed, parameterizing the ID (using a default value of 0) as suggested would be beneficial.

  • Location: web/src/hooks/queries/useTotalLeaderboardJurors.ts
  • Observation: The hook uses id: 0 in the GraphQL query.
  • Recommendation: Update the hook to accept an optional parameter (e.g., counterId = 0) and replace the hardcoded value with this parameter.
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found

web/src/pages/Jurors/Stats.tsx (1)

22-30: LGTM!

The Field component is well-structured with proper type definitions and graceful loading state handling using the Skeleton component.

web/src/hooks/queries/useJurorsByCoherenceScore.ts (1)

6-28: LGTM! Well-structured GraphQL query.

The query is well-defined with proper pagination, sorting, and filtering parameters. The where clause ensures only users with resolved votes are included.

web/src/pages/Home/TopJurors/JurorCard/JurorTitle.tsx (2)

26-37: LGTM! Well-structured styled component.

The ReStyledArrowLink component properly extends StyledArrowLink with appropriate hover effects and theme usage.


43-49: LGTM! Robust profile link logic.

The profile link logic correctly handles both connected and non-connected wallet states with proper address comparison.

web/src/pages/Home/TopJurors/Header/MobileHeader.tsx (1)

40-45: LGTM! Clean URL parameter handling.

The implementation properly handles URL parameters with appropriate fallback to "all" and conditional rendering of the header label.

web/src/pages/Cases/CaseDetails/Appeal/index.tsx (1)

48-56: LGTM! Good architectural improvement.

Moving the ClassicAppealProvider up to CaseDetails/index.tsx reduces nesting and makes the context available to more components, following React's composition pattern.

web/src/pages/Home/Community/index.tsx (1)

14-14: LGTM! Improved vertical spacing.

The margin adjustment enhances the visual hierarchy and spacing of the community section.

subgraph/core/src/entities/ClassicContribution.ts (1)

11-11: Consider handling potential errors from ensureUser.

The return value from ensureUser is not being checked. Consider handling potential errors to ensure data integrity.

Let's verify the error handling in the ensureUser function:

web/src/pages/Jurors/Search.tsx (1)

22-31: LGTM! Clean state initialization and URL parameter handling.

The component properly initializes search state from URL parameters and sets up necessary hooks for navigation.

web/src/pages/Cases/CaseDetails/Appeal/AppealHistory.tsx (1)

41-50: Consider handling undefined paidFee more explicitly.

The optional chaining on option.paidFee could lead to unexpected behavior if paidFee is undefined.

Consider adding explicit fallback:

- funding={BigInt(option.paidFee ?? 0)}
+ funding={option.paidFee ? BigInt(option.paidFee) : BigInt(0)}
✅ Verification successful

Assessing Handling of option.paidFee in OptionCard Funding

The current expression

funding={BigInt(option.paidFee ?? 0)}

already explicitly handles the case where option.paidFee is undefined (or null) by defaulting to 0. Although the suggested alternative

- funding={BigInt(option.paidFee ?? 0)}
+ funding={option.paidFee ? BigInt(option.paidFee) : BigInt(0)}

appears to make the fallback more explicit, it relies on a truthy check. This could inadvertently treat valid values like 0 (which is falsy) differently, even though the end result in this case remains the same (i.e. BigInt(0)). In short, the current implementation is both succinct and correct. If the goal is to increase clarity, you might consider an approach such as:

funding={typeof option.paidFee !== 'undefined'
  ? BigInt(option.paidFee)
  : BigInt(0)}

to explicitly check for undefined without conflating 0 with an absent value.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found

web/src/components/ExtraStatsDisplay.tsx (1)

8-13: LGTM! Improved flex layout handling.

The updated Container component properly handles wrapping and centering of child elements.

web/src/hooks/queries/useClassicAppealQuery.ts (1)

28-33: LGTM! Well-structured data model for answers.

The new answers field provides a more comprehensive data structure with clear properties for each answer, improving the handling of voting and fee data.

web/src/pages/Home/TopJurors/JurorCard/DesktopCard.tsx (2)

14-34: LGTM! Improved component flexibility with conditional rendering.

The Container's grid template is now dynamically adjusted based on the presence of rank, making the component more reusable.


40-46: Type changes align with data handling practices.

The interface updates (optional rank, string types for votes) improve type safety and data consistency.

web/src/pages/Home/TopJurors/index.tsx (2)

6-6: LGTM! Improved data fetching with new hook.

The switch to useJurorsByCoherenceScore with specific parameters provides better control over juror data retrieval.

Also applies to: 50-50


43-47: Enhanced UI with well-positioned button container.

The ButtonContainer provides consistent spacing and centering for the leaderboard button.

web/src/pages/Jurors/index.tsx (2)

19-31: LGTM! Well-structured responsive container.

The Container component uses proper responsive sizing and maintains consistent spacing across different screen sizes.


57-61: LGTM! Proper conditional rendering of profile link.

The profile link is correctly shown only when the user is connected, improving UX.

web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageOne.tsx (3)

32-32: LGTM! Improved context usage

The removal of paidFees from useFundingContext destructuring aligns with the new object-based approach for handling options.


42-45: LGTM! Enhanced type safety and readability

The refactoring from index-based to object-based mapping improves type safety and code clarity. Using option properties directly makes the code more maintainable.


48-55: LGTM! Improved option handling

Good improvements in the OptionCard props:

  • Using option.id as key instead of array index
  • Direct property access for title and funding
  • Clear funded state check
subgraph/core/src/entities/User.ts (1)

30-30: LGTM! Standardized address handling

Good practice to store Ethereum addresses in lowercase format for consistent comparison operations.

web/src/pages/Profile/JurorInfo/index.tsx (1)

7-7: LGTM! Improved coherence calculation

Good refactoring to:

  • Extract coherence calculation into a separate utility function
  • Use more descriptive variable names (coherencePercentage)
  • Maintain clean separation of concerns

Also applies to: 50-51

web/src/layout/Header/navbar/Explore.tsx (1)

57-57: LGTM! Updated navigation structure

The addition of the Jurors link and removal of Dashboard aligns with the broader navigation restructuring in the application.

web/src/pages/Home/TopJurors/Header/DesktopHeader.tsx (3)

20-41: LGTM! Responsive grid layout implementation.

The conditional grid template columns based on renderIcon prop provides a clean way to handle layout variations.


43-47: LGTM! Theme-consistent icon styling.

Good use of theme colors for the icon, maintaining visual consistency.


60-62: Consider adding error handling for malformed URL parameters.

The decodeURIFilter function might throw if the filter parameter is malformed.

Add a try-catch block to handle potential errors:

-  const { id: searchValue } = decodeURIFilter(filter ?? "all");
+  let searchValue;
+  try {
+    ({ id: searchValue } = decodeURIFilter(filter ?? "all"));
+  } catch (error) {
+    console.error("Error decoding filter:", error);
+    searchValue = null;
+  }
web/src/pages/Cases/CaseDetails/Appeal/Classic/Options/StageTwo.tsx (2)

38-38: LGTM! Performance optimization with useMemo.

Good use of useMemo to prevent unnecessary recalculations of the choice object.


40-43: Consider adding null check for setSelectedOption.

The useEffect should verify that setSelectedOption is defined before calling it.

-    if (!isUndefined(choice)) setSelectedOption(choice);
+    if (!isUndefined(choice) && setSelectedOption) setSelectedOption(choice);
kleros-sdk/src/dataMappings/utils/disputeDetailsSchema.ts (1)

42-47: LGTM! Standardized refuse-to-arbitrate answer.

Good addition of a standardized constant for handling arbitration refusal cases.

web/src/pages/Cases/CaseDetails/index.tsx (1)

62-89: LGTM! Context provider addition looks good.

The ClassicAppealProvider is correctly nested within VotingContextProvider, maintaining proper context hierarchy.

subgraph/core/src/datapoint.ts (1)

18-18: LGTM! Consistent implementation of leaderboard jurors tracking.

The changes follow the established pattern:

  1. Variable added to VARIABLES array
  2. Initial value set to ZERO in checkFirstDayActivity
  3. Update function follows the same pattern as other metric updates

Also applies to: 47-47, 92-94

web/src/pages/Cases/CaseDetails/Voting/Classic/Commit.tsx (2)

46-48: LGTM! Type safety improvements for blockchain values.

The change from number to bigint for the choice parameter and its string conversion for localStorage are appropriate for handling blockchain values.

Also applies to: 59-59


71-84: Review dependency array in useCallback.

The dependency array includes wagmiConfig which might cause unnecessary re-renders. Consider memoizing the config or using specific values from it.

web/src/pages/Cases/CaseDetails/Voting/Classic/OptionsContainer.tsx (3)

15-15: LGTM! Type safety improvements with bigint.

The migration from number to bigint for voting options improves type safety and prevents potential integer overflow issues when dealing with large numbers.

Also applies to: 45-45, 53-53, 57-57, 81-82, 95-96


70-70: Add null coalescing for question display.

Good use of the null coalescing operator to provide a fallback empty string, preventing potential rendering issues.


75-86: Verify type safety with the Answer interface.

The use of the Answer type from the SDK improves type safety. However, ensure that all properties of the Answer interface are properly handled.

✅ Verification successful

Type safety with the Answer interface verified.
The repository shows that the Answer interface is imported in multiple files (including in OptionsContainer, Reveal, and getVoteChoice) and used consistently. In OptionsContainer.tsx, only the title and id properties are accessed—which aligns with the component’s needs. There were no indications that additional properties are omitted or misused.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check Answer interface usage across the codebase
ast-grep --pattern 'import { Answer } from "@kleros/kleros-sdk"'

Length of output: 366

web/src/pages/Jurors/DisplayJurors.tsx (1)

45-57: Good use of memoization for juror ranking.

The useMemo hook effectively optimizes the juror ranking calculation, especially when handling ascending order and search scenarios.

web/src/pages/Profile/JurorInfo/Header.tsx (1)

18-18: LGTM! Clean UI improvements.

The addition of the JurorsLeaderboardButton and title update improve navigation and clarity.

Also applies to: 91-91, 99-99

web/src/pages/Home/CourtOverview/Stats.tsx (1)

40-41: LGTM! Good practice making the utility function reusable.

Making getLastOrZero exportable allows for better code reuse across the codebase.

web/src/components/Popup/MiniGuides/JurorLevels.tsx (1)

8-9: LGTM! Import paths updated correctly.

Import paths have been updated to reflect the new Profile-centric structure.

web/src/app.tsx (1)

17-19: LGTM! Routes updated correctly for the new Profile-centric structure.

The changes correctly implement the transition from Dashboard to Profile/Jurors components with appropriate routes.

Also applies to: 68-82

web/src/pages/Cases/CaseDetails/Appeal/Classic/Fund.tsx (3)

36-36: LGTM! UI layout improvement.

Increased spacing improves the visual layout of the ETH label.


76-76: LGTM! Safer option handling.

Using selectedOption?.id is safer than using the entire object, preventing potential type coercion issues.


114-124: LGTM! Improved button state handling.

Adding isLoading to the dependencies ensures the button state is correctly managed during loading states, preventing potential race conditions.

web/src/pages/Cases/CaseDetails/Voting/Classic/Reveal.tsx (3)

23-23: LGTM! Enhanced type safety with SDK type.

The addition of the Answer type from @kleros-sdk improves type safety and maintainability.


141-150: LGTM! Improved choice tracking with BigInt.

The use of BigInt(-1) as initial value for choice tracking aligns with the established pattern from PR #1839, ensuring consistent type handling.


77-77: Verify wallet and public client availability.

The addition of the publicClient check in the condition enhances error handling.

Run the following script to verify similar patterns in other contract interactions:

✅ Verification successful

Client validation pattern confirmed across contract interactions.
After analyzing the output, we found that contract interaction components (e.g., in "Classic/Reveal.tsx", "ClaimPnkButton.tsx", "Commit.tsx", etc.) consistently check for the availability of publicClient—and in the case of "Reveal.tsx", both walletClient and publicClient. This confirms that the added publicClient check is in line with the overall pattern to enhance error handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent client validation patterns
# Test: Search for contract write operations. Expect: Consistent client validation.
rg -A 5 'writeContract|simulateContract' 

Length of output: 12934

web/src/pages/Cases/CaseDetails/Voting/VotesDetails/index.tsx (1)

117-117: LGTM! Improved type handling in getVoteChoice.

Removed unnecessary parseInt, allowing getVoteChoice to handle the type conversion internally.

web/src/components/EvidenceCard.tsx (1)

226-226: LGTM! Updated route to profile.

Route updated from dashboard to profile, aligning with the new navigation structure.

subgraph/core/src/DisputeKitClassic.ts (2)

105-106: LGTM! Improved answer management.

The use of ensureAnswer and answer.paidFee provides better encapsulation and tracking of fees.

Also applies to: 108-108


112-114: LGTM! Explicit funded state management.

Clear management of the answer's funded state with proper persistence.

web/src/components/Verdict/DisputeTimeline.tsx (1)

106-106: LGTM! Improved vote choice handling

The changes enhance the dispute timeline by:

  • Passing answers to getVoteChoice for better context
  • Correctly handling ruling overrides by comparing with currentRuling

Also applies to: 125-125, 128-128

subgraph/core/src/KlerosCore.ts (2)

148-164: Enhanced juror tracking with leaderboard updates

The code now tracks the first resolved vote for each juror and updates the leaderboard accordingly. The coherence score calculation is properly handled when votes are missing.


174-174: Simplified coherence score calculation

The coherence score is now always recalculated after updating total resolved votes, making the logic more consistent.

.github/workflows/deploy-bots.yml (1)

3-4: Security improvements in workflow configuration

Good security practices:

  • Added explicit permissions for contents
  • Updated harden-runner to latest version v2.10.3

Also applies to: 11-11

kleros-app/package.json (1)

16-18: Update Node Version in Volta Configuration:
The Node version has been updated to "20.18.2", which aligns with the changes made in other package configurations across the repository. This consistency helps ensure a standardized development environment.

web-devtools/package.json (1)

10-12: Standardize Node Version in Volta Section:
The Node version under the volta key is updated to "20.18.2", matching the new standard applied in other packages. If required, confirm whether the Yarn version in this file should also be updated for uniformity with the root configuration.

.github/workflows/contracts-testing.yml (2)

19-21: New Permissions Configuration:
The introduction of the permissions: contents: read section ensures that the workflow adheres to the principle of least privilege, improving overall security.


26-27: Update Harden Runner Action Version:
The Harden Runner action is updated to commit 446798f8213ac2e75931c1b0769676d927801858 (v2.10.3). This update helps ensure that the workflow benefits from the latest security hardening improvements.

🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 26-26: wrong indentation: expected 6 but found 4

(indentation)

.github/workflows/sentry-release.yml (3)

9-11: New Permissions Block:
Adding permissions: contents: read restricts the workflow’s access to only the necessary resources, reinforcing security best practices.


19-20: Harden Runner Action Version Update:
The Harden Runner action has been updated to v2.10.3, aligning security enhancements with those in other workflows.

🧰 Tools
🪛 YAMLlint (1.35.1)

[warning] 19-19: wrong indentation: expected 6 but found 4

(indentation)


74-76: Sentry Release Action Version Update:
The Sentry release action is now set to v1.9.0. This update should provide improved compatibility and functionality with the latest Sentry features.

package.json (1)

30-33: Update Package Manager & Volta Settings:
The root package.json now specifies "packageManager": "[email protected]" and updates the volta configuration to use "node": "20.18.2" and "yarn": "4.6.0". These revisions help standardize the toolchain across the repository and ensure a consistent development environment.

.github/workflows/scorecards.yml (3)

35-36: Harden Runner Action Version Updated:
The Harden Runner action has been upgraded to commit 446798f8213ac2e75931c1b0769676d927801858 (v2.10.3). This aligns with our overall workflow security enhancements. Ensure that the updated version has been tested in your environment.


54-55: Checkout Action Version Updated:
The checkout action version is now set to 11bd71901bbe5b1630ceea73d27597364c9af683 (v4.2.2). This upgrade should improve performance and security.


81-82: Upload Artifact Action Version Updated:
The artifact upload action has been updated to version 65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 (v4.6.0). Please confirm that any downstream integrations or artifact processing logic are compatible with this change.

web/package.json (2)

26-27: New “clean” Script Added:
A new script has been added:
"clean": "rimraf node_modules/ dist/"
This provides a quick way to clear the build outputs and ensure a fresh environment before building or starting the application.


74-75: New Dependency "rimraf" Added to devDependencies:
The "rimraf": "^6.0.1" dependency was introduced to support the new clean script. This utility is well-suited for cross-platform deletion of directories. Verify that its version is compatible with the rest of the toolchain.

subgraph/package.json (3)

3-4: Project Version and DRT Version Updated:
The project version has been updated to "0.11.0" and a new field "drtVersion": "0.11.0" has been introduced. This ensures consistency between the subgraph version and the DRT deployments.


28-29: Deploy Commands for Core-Neo Updated:
The deploy commands for Core-Neo (lines 28–29) have been updated to reflect the revised versioning scheme. Ensure that these commands deploy to the correct targets and use the updated version environment tags.


51-53: DRT Deployment Commands Enhancement:
The deploy commands for the dispute-template-registry now dynamically pull the version using $(jq -r .drtVersion $npm_package_json), which helps keep the versioning in sync. Please verify that the jq command returns the correct value in all deployment environments.

README.md (1)

43-44: New Documentation Entry for kleros-app Added:
A new table entry for kleros-app has been introduced to document the library of React hooks and utilities shared by the Kleros frontend apps. Ensure that the linked documentation provides developers with adequate guidance on how to use this module.

subgraph/core/schema.graphql (4)

71-74: New Field in User Type:
A userAddress: String! field has been added to the User entity. This addition enriches the user data model. Ensure that the data ingestion and mutation processes correctly populate this field to prevent unexpected null values.


271-278: New Entity Type "Answer" Introduced:
A new type Answer has been defined with fields for answerId, count, paidFee, funded, and a relation to ClassicRound via localRound. This enhances the round-answer tracking mechanism. It’s important to validate that your data sources correctly supply these values.


284-285: New answers Field in ClassicRound:
The ClassicRound entity now includes an answers: [Answer!]! @derivedFrom(field: "localRound") field. This change links rounds with their corresponding answers. Confirm that the underlying data relationships are correctly maintained in the subgraph.


242-243: New Field in Counter Entity:
The addition of totalLeaderboardJurors: BigInt! to the Counter type provides a mechanism to track the total number of jurors on a leaderboard. Ensure this field is updated appropriately in the logic that governs leaderboard statistics.

.github/workflows/codeql.yml (2)

41-41: Updated Harden Runner Action Version
The step-security/harden-runner action is now set to commit 446798f8213ac2e75931c1b0769676d927801858 (v2.10.3), which appears to be the latest approved version. This update aligns with our standardization across workflows for improved security.


45-47: Updated Checkout Action Version
The checkout action has been updated to actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 (v4.2.2), ensuring that we benefit from the latest features and fixes offered by the GitHub Actions team. Please ensure that downstream steps remain compatible with the new version.

@jaybuidl
Copy link
Member Author

jaybuidl commented Feb 3, 2025

@coderabbitai resolve

Copy link
Contributor

coderabbitai bot commented Feb 3, 2025

✅ Actions performed

Comments resolved and changes approved.

@jaybuidl jaybuidl merged commit 0e89b60 into master Feb 3, 2025
27 of 28 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.

4 participants