Skip to content

feat: schema changes + ci fix#27

Open
petar-omni wants to merge 1 commit into
mainfrom
feat/schema
Open

feat: schema changes + ci fix#27
petar-omni wants to merge 1 commit into
mainfrom
feat/schema

Conversation

@petar-omni
Copy link
Copy Markdown
Contributor

@petar-omni petar-omni commented May 8, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for yield campaigns with detailed campaign metadata, status tracking, and reward configuration.
    • Expanded yield risk assessments to include staking rewards risk metrics and ratings.
  • Chores

    • Updated CI/CD workflow configuration and tool versions (Node.js 24.15.0, pnpm 10.33.2).
    • Updated yield source nomenclature from "lending_interest" to "lending".

@petar-omni petar-omni requested a review from Philippoes May 8, 2026 13:44
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR restructures yield risk data modeling from flat parameter objects to hierarchical DTOs with staking rewards support, introduces yield campaign management endpoints and types, updates CI infrastructure with pinned actions and tool versions, and removes deprecated RiskParameterDto types.

Changes

Yield Risk & Campaign API Expansion

Layer / File(s) Summary
Build & Tooling
.github/workflows/ci.yml, mise.toml
CI workflow upgraded to pinned checkout action SHA and inline mise script installation; Node.js and pnpm versions pinned to specific patch levels (24.15.0, 10.33.2).
Campaign & Risk Response Types
src/api/schemas/campaignPayoutFrequency.ts, campaignQualificationType.ts, campaignRewardMode.ts, campaignStatus.ts, campaignQualificationConfigDto.ts, yieldCampaignDto.ts, yieldRiskEntryDto.ts, yieldRiskEntryDtoSource.ts, yieldRiskStakingRewardsDto.ts, yieldRiskStakingRewardsDtoChain.ts...yieldRiskStakingRewardsDtoVersion.ts, yieldRiskStakingRewardsMetricsDto.ts, yieldsControllerGetYieldCampaigns*.ts, yieldsControllerGetYieldCampaignsParams.ts
New campaign enums define payout frequencies (weekly/daily/six_hourly/end_of_campaign), qualification types (min_token_amount), reward modes (normal/compound), and campaign statuses (draft/active/paused/ended). YieldCampaignDto models campaign metadata with budgets, timestamps, and nested qualification/reward configs. Yield risk refactored: YieldRiskEntryDto replaces flat risk fields with ratings array of provider entries (credora/exponential/stakingRewards sources). YieldRiskStakingRewardsDto adds optional staking provider data (rating/score, URLs, chain/contract, metrics). Campaign controller responses (200/400/401/429/500) and params schema added for paginated campaign fetching.
Existing Schema Adjustments
src/api/schemas/yieldDto.ts, rewardDtoYieldSource.ts, networks.ts
YieldDto.risk field retyped from YieldRiskDto to YieldRiskSummaryDto (summary view only). RewardDtoYieldSource updated: lending_interest replaced with lending. JSDoc added to networks module.
Schema Barrel Exports
src/api/schemas/index.ts
Barrel expanded to export all new campaign enums, YieldCampaignDto, YieldRiskSummaryDto and staking rewards DTOs, YieldRiskEntryDto/source, campaign controller response/param types, and expanded yield risk supporting types.
API Wrapper Functions
src/api/index.ts
getYieldRisk return type changed from RiskParameterDto[] to YieldRiskDto. New getYieldCampaigns(yieldId, params?, options?) function added with YieldsControllerGetYieldCampaignsParams support and YieldsControllerGetYieldCampaigns200 response. GetYieldCampaignsResult type exported derived from getYieldCampaigns.
MSW Mock Handlers & Data
src/api/index.msw.ts
yieldSource mock literals updated: lending replaces lending_interest. Yield risk mock refactored to use ratings array structure. getYieldsControllerGetYieldRiskResponseMock(overrideResponse?) now generates YieldRiskDto with exponentialFi, credora, stakingRewards fields. New getYieldsControllerGetYieldCampaignsResponseMock and handler added for campaigns endpoint. Handler registered in getYieldXyzAPIMock() aggregator.
Deprecated Type Removals
src/api/schemas/riskParameterDto.ts, riskParameterDtoAsset.ts, riskParameterDtoIntegrationId.ts, riskParameterDtoProtocol.ts, riskParameterDtoValue.ts
RiskParameterDto interface and five supporting types fully removed; no longer used with new YieldRiskDto structure.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • stakekit/sdk#24: Modifies yield API surface including getYieldRisk signature and yield risk/campaign schema exports.

Suggested reviewers

  • Philippoes
  • jdomingos

Poem

🐰 A rabbit hops through yield campaigns,
Risk ratings dance in entry's refrains,
Staking rewards now nestle inside,
Old parameters cast aside,
New schemas bloom—what a grand stride! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague and generic. It uses 'schema changes' without specifying which schemas or what changed, and 'ci fix' is equally non-specific about the actual CI issue resolved. Consider a more descriptive title that highlights the primary change, such as 'feat: add yield campaigns API and update yield risk schema' or similar.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/schema

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

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 8, 2026

⚠️ No Changeset found

Latest commit: 6480d4c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Copy Markdown

@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: 11

🧹 Nitpick comments (3)
src/api/schemas/yieldRiskStakingRewardsMetricsDtoUsers.ts (1)

4-4: ⚡ Quick win

Tighten users metric value typing to numeric values.

On Line 4, using unknown for a “users count” field makes the DTO hard to consume safely. Prefer a numeric map type so callers get useful type-checking.

Proposed change
-export type YieldRiskStakingRewardsMetricsDtoUsers = { [key: string]: unknown };
+export type YieldRiskStakingRewardsMetricsDtoUsers = Record<string, number>;
🤖 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 `@src/api/schemas/yieldRiskStakingRewardsMetricsDtoUsers.ts` at line 4, The
current DTO type YieldRiskStakingRewardsMetricsDtoUsers uses unknown for values
which prevents safe consumption; change its definition to map string keys to
numeric values (e.g., use Record<string, number> or { [key: string]: number })
so callers get compile-time guarantees that each users metric is a number and
can be safely operated on.
src/api/schemas/yieldsControllerGetYieldCampaigns200.ts (1)

4-5: ⚡ Quick win

Consider making items required if the 200 contract always returns a list.

Using items: YieldCampaignDto[] (empty array when no results) simplifies downstream handling and keeps pagination responses stricter.

Proposed tweak
 export type YieldsControllerGetYieldCampaigns200 = PaginatedResponseDto & {
-  items?: YieldCampaignDto[];
+  items: YieldCampaignDto[];
 };
🤖 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 `@src/api/schemas/yieldsControllerGetYieldCampaigns200.ts` around lines 4 - 5,
The response type YieldsControllerGetYieldCampaigns200 currently makes items
optional; change its items?: YieldCampaignDto[] to a required items:
YieldCampaignDto[] so the 200 contract always returns an array (empty when no
results). Update any places that construct or return
YieldsControllerGetYieldCampaigns200 (factory/mapper/handler functions) to
ensure they provide an empty [] instead of undefined, and run type-checks to fix
any call sites expecting items to be optional.
src/api/index.ts (1)

87-99: Call out getYieldRisk response-shape change in release notes/versioning.

This switches consumers from the previous risk-params array contract to YieldRiskDto; make sure the SDK release communication and semver strategy explicitly reflect that.

🤖 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 `@src/api/index.ts` around lines 87 - 99, Update release notes and versioning
to explicitly call out the response-shape change introduced by getYieldRisk: it
now returns YieldRiskDto instead of the previous risk-params array contract;
mention the API contract change in the changelog and bump the SDK version per
your semver policy (e.g., major or minor) so consumers of customFetch and
getYieldRisk can prepare for the breaking/behavioral change.
🤖 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 @.github/workflows/ci.yml:
- Around line 19-21: The PATH updates appended to $GITHUB_PATH won't take effect
until the next step, so before calling mise install add an inline PATH export
that prepends $HOME/.local/share/mise/bin and $HOME/.local/share/mise/shims to
PATH so mise is available immediately, then still append those two paths to
$GITHUB_PATH (the existing echo lines) so they persist for subsequent steps;
update the step that runs mise to perform the inline export before invoking the
mise command.
- Line 18: The workflow currently runs an unverified remote installer via the
line "curl https://mise.run | sh", which is a supply-chain risk; replace that
step with the official GitHub Action "jdx/mise-action" and pin it to a full
commit SHA (not a tag) in the workflow invocation, or, if you must keep the
installer, add proper GPG signature verification per the mise docs; update the
step that contains the "curl https://mise.run | sh" command to use the pinned
action reference or include signature verification logic instead.

In `@src/api/index.msw.ts`:
- Around line 11103-11316: The timestamps for campaigns are sampled
independently which can produce impossible timelines; instead generate a base
startTime (e.g., const start = faker.date.past()), then compute endTime =
faker.date.between(start, someLaterDate) and derive dependent fields:
lastProcessedHour (nullable) must be between start and end (or null),
nextPayoutDueAt (nullable) must be >= lastProcessedHour (when present) and <=
end, and any other time fields (createdAt, updatedAt) should be consistent
relative to start/end; update the code that sets startTime, endTime,
lastProcessedHour, nextPayoutDueAt (and related fields) to use these derived
values and preserve existing randomness for nullability and status handling.

In `@src/api/schemas/yieldRiskStakingRewardsDtoChain.ts`:
- Line 4: The exported type YieldRiskStakingRewardsDtoChain currently allows
arbitrary unknown values; change it so each chain key maps to a string label
instead of unknown objects — update the type definition for
YieldRiskStakingRewardsDtoChain to be a mapping from string keys to string
values (i.e., value type should be string) so callers treat chain entries as
label strings.

In `@src/api/schemas/yieldRiskStakingRewardsDtoProviderName.ts`:
- Line 4: The type YieldRiskStakingRewardsDtoProviderName currently allows any
object ({ [key: string]: unknown }) but should be a string alias; update the
type declaration for YieldRiskStakingRewardsDtoProviderName to be a string
(e.g., export type YieldRiskStakingRewardsDtoProviderName = string) and update
any locations that import or use YieldRiskStakingRewardsDtoProviderName to
expect a string (or a tighter string literal/union if desired) so validation and
typings reflect a provider name string.

In `@src/api/schemas/yieldRiskStakingRewardsDtoRatedSince.ts`:
- Line 4: The exported type YieldRiskStakingRewardsDtoRatedSince is currently an
open object; change it to a date-string type to enforce the DTO contract by
replacing the index-signature with a string alias (e.g., export type
YieldRiskStakingRewardsDtoRatedSince = string) and document/validate it as an
ISO-8601 date where the type is consumed (update any validators, tests, or
parsers that assumed an object). Ensure any code expecting a mapped object uses
the new string type or adapts to read a date string (and add
conversion/validation in functions that parse ratedSince).

In `@src/api/schemas/yieldRiskStakingRewardsDtoRating.ts`:
- Around line 1-4: Replace the permissive index-signature in
YieldRiskStakingRewardsDtoRating and the related files with explicit typed
properties matching the JSDoc: define YieldRiskStakingRewardsDtoRating as an
object with specific fields (e.g., score: number (1-5), potentialScore?: number
(1-5), ratedAt?: string (ISO date), ratedSince?: string (ISO date), profileUrl?:
string, reportUrl?: string, contractAddress?: string, potentialRating?: {...}
same shape as rating, version?: string, type?: string, providerName?: string,
chain?: string); change the separate files: YieldRiskStakingRewardsDtoScore and
YieldRiskStakingRewardsDtoPotentialScore to number,
YieldRiskStakingRewardsDtoRatedAt and RatedSince to string,
ProfileUrl/ReportUrl/ContractAddress/Version/Type/ProviderName/Chain to string,
and ensure the rating/potentialRating types reference the new specific rating
interface so IDEs and the compiler validate structure rather than allowing
{[key:string]: unknown}.

In `@src/api/schemas/yieldRiskStakingRewardsDtoReportUrl.ts`:
- Line 4: The current broad index signature in the exported type
YieldRiskStakingRewardsDtoReportUrl should be replaced with an explicit URL
scalar property to enforce type safety: change the type to require a reportUrl
field (e.g., reportUrl: string or your project’s URL scalar type) instead of {
[key: string]: unknown }, update any serializers/validators that consume
YieldRiskStakingRewardsDtoReportUrl to validate/parse the URL value, and ensure
all usages of YieldRiskStakingRewardsDtoReportUrl (constructors, mappers, tests)
are updated to pass a reportUrl property.

In `@src/api/schemas/yieldRiskStakingRewardsDtoScore.ts`:
- Line 4: Replace the open-object type for YieldRiskStakingRewardsDtoScore with
a bounded numeric type so it only allows the integers 1 through 5; locate the
type alias YieldRiskStakingRewardsDtoScore and change its definition from a
generic {[key: string]: unknown} to a union of the allowed integer literals
(1,2,3,4,5) or an equivalent branded/validated numeric type so compile-time
typing enforces the 1–5 range.

In `@src/api/schemas/yieldRiskStakingRewardsDtoType.ts`:
- Line 4: The DTO currently declares YieldRiskStakingRewardsDtoType as a loose
object ({ [key: string]: unknown }) which allows arbitrary shapes; change it to
a scalar discriminator (e.g., a plain string or a string literal union/enum) so
the product type is a single scalar value. Update the declaration of
YieldRiskStakingRewardsDtoType to a scalar type (or a string enum of allowed
product types), and adjust any validation/serialization code and places that
import/use YieldRiskStakingRewardsDtoType to expect a scalar product type
instead of an object.

In `@src/api/schemas/yieldRiskStakingRewardsDtoVersion.ts`:
- Line 4: The exported type YieldRiskStakingRewardsDtoVersion is currently a
catch-all object ({ [key: string]: unknown }) but should be a scalar version
token; change the type definition of YieldRiskStakingRewardsDtoVersion from an
open object to an appropriate scalar (e.g., string or a narrow union of allowed
tokens) and update any validators or usages that expect a version token to
reflect the new scalar type so DTO correctness is restored.

---

Nitpick comments:
In `@src/api/index.ts`:
- Around line 87-99: Update release notes and versioning to explicitly call out
the response-shape change introduced by getYieldRisk: it now returns
YieldRiskDto instead of the previous risk-params array contract; mention the API
contract change in the changelog and bump the SDK version per your semver policy
(e.g., major or minor) so consumers of customFetch and getYieldRisk can prepare
for the breaking/behavioral change.

In `@src/api/schemas/yieldRiskStakingRewardsMetricsDtoUsers.ts`:
- Line 4: The current DTO type YieldRiskStakingRewardsMetricsDtoUsers uses
unknown for values which prevents safe consumption; change its definition to map
string keys to numeric values (e.g., use Record<string, number> or { [key:
string]: number }) so callers get compile-time guarantees that each users metric
is a number and can be safely operated on.

In `@src/api/schemas/yieldsControllerGetYieldCampaigns200.ts`:
- Around line 4-5: The response type YieldsControllerGetYieldCampaigns200
currently makes items optional; change its items?: YieldCampaignDto[] to a
required items: YieldCampaignDto[] so the 200 contract always returns an array
(empty when no results). Update any places that construct or return
YieldsControllerGetYieldCampaigns200 (factory/mapper/handler functions) to
ensure they provide an empty [] instead of undefined, and run type-checks to fix
any call sites expecting items to be optional.
🪄 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: af6bf88c-f56e-4efb-8bad-f844b1b74c35

📥 Commits

Reviewing files that changed from the base of the PR and between f837a39 and 6480d4c.

📒 Files selected for processing (45)
  • .github/workflows/ci.yml
  • mise.toml
  • src/api/index.msw.ts
  • src/api/index.ts
  • src/api/schemas/campaignPayoutFrequency.ts
  • src/api/schemas/campaignQualificationConfigDto.ts
  • src/api/schemas/campaignQualificationType.ts
  • src/api/schemas/campaignRewardMode.ts
  • src/api/schemas/campaignStatus.ts
  • src/api/schemas/index.ts
  • src/api/schemas/networks.ts
  • src/api/schemas/rewardDtoYieldSource.ts
  • src/api/schemas/riskParameterDto.ts
  • src/api/schemas/riskParameterDtoAsset.ts
  • src/api/schemas/riskParameterDtoIntegrationId.ts
  • src/api/schemas/riskParameterDtoProtocol.ts
  • src/api/schemas/riskParameterDtoValue.ts
  • src/api/schemas/yieldCampaignDto.ts
  • src/api/schemas/yieldDto.ts
  • src/api/schemas/yieldRiskDto.ts
  • src/api/schemas/yieldRiskEntryDto.ts
  • src/api/schemas/yieldRiskEntryDtoSource.ts
  • src/api/schemas/yieldRiskStakingRewardsDto.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoChain.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoContractAddress.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoPotentialRating.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoPotentialScore.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoProfileUrl.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoProviderName.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoRatedAt.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoRatedSince.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoRating.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoReportUrl.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoScore.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoType.ts
  • src/api/schemas/yieldRiskStakingRewardsDtoVersion.ts
  • src/api/schemas/yieldRiskStakingRewardsMetricsDto.ts
  • src/api/schemas/yieldRiskStakingRewardsMetricsDtoUsers.ts
  • src/api/schemas/yieldRiskSummaryDto.ts
  • src/api/schemas/yieldsControllerGetYieldCampaigns200.ts
  • src/api/schemas/yieldsControllerGetYieldCampaigns400.ts
  • src/api/schemas/yieldsControllerGetYieldCampaigns401.ts
  • src/api/schemas/yieldsControllerGetYieldCampaigns429.ts
  • src/api/schemas/yieldsControllerGetYieldCampaigns500.ts
  • src/api/schemas/yieldsControllerGetYieldCampaignsParams.ts
💤 Files with no reviewable changes (5)
  • src/api/schemas/riskParameterDto.ts
  • src/api/schemas/riskParameterDtoProtocol.ts
  • src/api/schemas/riskParameterDtoValue.ts
  • src/api/schemas/riskParameterDtoAsset.ts
  • src/api/schemas/riskParameterDtoIntegrationId.ts

Comment thread .github/workflows/ci.yml
- uses: jdx/mise-action@v2
- name: Install mise
run: |
curl https://mise.run | sh
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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

What is the recommended secure way to install mise in GitHub Actions: pinned jdx/mise-action commit SHA or checksum-verified installer script?

💡 Result:

Recommended secure approach: pin jdx/mise-action to a full commit SHA (not a tag), and avoid the unauthenticated “curl | sh” style installer unless you verify its signature/checksum. In addition, use mise.lock (checksum-verified tool tarballs) to ensure the exact mise-installed tools are reproducible. 1) Pin the GitHub Action to a commit SHA - GitHub recommends pinning third-party Actions to a specific commit SHA to prevent malicious code in newly-updated branches/tags from being used automatically. [1] - Example: - uses: jdx/mise-action@ 2) Prefer mise-action for installing mise/tools in CI - The supported GitHub Actions integration for mise is jdx/mise-action, which installs mise and runs mise install/tool installation according to your configuration. [2][3] 3) If you use the installer script, verify it (signature or checksum), not just curl|sh - The mise install documentation provides an explicit verification flow using GPG: download install.sh and decrypt the detached signature install.sh.sig, verify it was signed by the mise release key, then run the script. [4][5] - The documentation also notes that without changing MISE_VERSION, the script is pinned to “whatever the latest version was when it was downloaded with checksums inside the file,” i.e., the checksum logic inside the script governs what it installs. [4] 4) Use mise.lock for checksum verification of tool tarballs - mise supports lockfiles that “store/verify the checksum of tool tarballs,” and committing mise.lock helps ensure the exact same tool versions are installed across developers and CI/CD systems. [6] Which is more secure: pinned SHA vs checksum-verified installer? - For the Action itself: pinning to a commit SHA is the strongest control against supply-chain changes in the Action code, and is explicitly recommended by GitHub. [1] - For installing the mise binary via script: checksum/signature verification is the secure counterpart when you choose the script-based route. [4][5] So the “secure best practice” stack is: - Pin jdx/mise-action to a full commit SHA for CI governance. [1] - Use mise.lock to checksum-verify the installed tools. [6] - Only if you must use the script, verify its signature/checksum as documented. [4][5] Sample hardened workflow snippet (using mise-action): - uses: jdx/mise-action@c94f0bf # example full SHA pin from jdx/mise repo history with: version: 2026.3.10 install: true cache: true # plus your tool_versions/mise_toml Confidence: high that SHA-pinning and script signature verification are correct because they are explicitly stated in GitHub’s recommendation and mise’s own docs, and mise.lock checksum verification is explicitly described in mise security documentation. [1][4][5][6]

Citations:


Replace curl | sh with jdx/mise-action GitHub Action pinned to a commit SHA.

Line 18 executes a remote installer script without integrity verification, creating a supply-chain risk. Use the official jdx/mise-action Action pinned to a full commit SHA (not a tag) instead, or if you must use the installer script, verify it with GPG signature as documented in the mise installation guide.

🤖 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 @.github/workflows/ci.yml at line 18, The workflow currently runs an
unverified remote installer via the line "curl https://mise.run | sh", which is
a supply-chain risk; replace that step with the official GitHub Action
"jdx/mise-action" and pin it to a full commit SHA (not a tag) in the workflow
invocation, or, if you must keep the installer, add proper GPG signature
verification per the mise docs; update the step that contains the "curl
https://mise.run | sh" command to use the pinned action reference or include
signature verification logic instead.

Comment thread .github/workflows/ci.yml
Comment on lines +19 to +21
echo "$HOME/.local/share/mise/bin" >> $GITHUB_PATH
echo "$HOME/.local/share/mise/shims" >> $GITHUB_PATH
mise install
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 | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

GitHub Actions documentation: when writing to GITHUB_PATH inside a run step, is the updated PATH available in the same step or only subsequent steps?

💡 Result:

When writing to GITHUB_PATH inside a run step in GitHub Actions, the updated PATH is not available in the same step. It is only available to subsequent steps in the same job.[1][2]

Citations:


Fix PATH updates before using mise install in the same step.

Line 21 uses mise in the same step where lines 19-20 append to $GITHUB_PATH, but GitHub Actions environment variable exports don't apply until the next step. Use inline export PATH to make the directories available immediately, then append to $GITHUB_PATH for subsequent steps.

Suggested patch
       - name: Install mise
         run: |
-          curl https://mise.run | sh
-          echo "$HOME/.local/share/mise/bin" >> $GITHUB_PATH
-          echo "$HOME/.local/share/mise/shims" >> $GITHUB_PATH
-          mise install
+          set -euo pipefail
+          curl -fsSL https://mise.run | sh
+          export PATH="$HOME/.local/bin:$HOME/.local/share/mise/bin:$HOME/.local/share/mise/shims:$PATH"
+          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
+          echo "$HOME/.local/share/mise/bin" >> "$GITHUB_PATH"
+          echo "$HOME/.local/share/mise/shims" >> "$GITHUB_PATH"
+          mise install
🤖 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 @.github/workflows/ci.yml around lines 19 - 21, The PATH updates appended to
$GITHUB_PATH won't take effect until the next step, so before calling mise
install add an inline PATH export that prepends $HOME/.local/share/mise/bin and
$HOME/.local/share/mise/shims to PATH so mise is available immediately, then
still append those two paths to $GITHUB_PATH (the existing echo lines) so they
persist for subsequent steps; update the step that runs mise to perform the
inline export before invoking the mise command.

Comment thread src/api/index.msw.ts
Comment on lines +11103 to +11316
createdAt: faker.date.past().toISOString().slice(0, 19) + "Z",
updatedAt: faker.date.past().toISOString().slice(0, 19) + "Z",
yieldId: faker.string.alpha({ length: { min: 10, max: 20 } }),
status: faker.helpers.arrayElement(Object.values(CampaignStatus)),
rewardMode: faker.helpers.arrayElement(
Object.values(CampaignRewardMode),
),
rewardRate: {
...{
total: faker.number.float({ fractionDigits: 2 }),
rateType: faker.string.alpha({ length: { min: 10, max: 20 } }),
components: Array.from(
{ length: faker.number.int({ min: 1, max: 10 }) },
(_, i) => i + 1,
).map(() => ({
rate: faker.number.float({ fractionDigits: 2 }),
rateType: faker.string.alpha({ length: { min: 10, max: 20 } }),
token: {
...{
symbol: faker.string.alpha({
length: { min: 10, max: 20 },
}),
name: faker.string.alpha({ length: { min: 10, max: 20 } }),
decimals: faker.number.float({ fractionDigits: 2 }),
network: faker.helpers.arrayElement([
"ethereum",
"ethereum-goerli",
"ethereum-holesky",
"ethereum-sepolia",
"ethereum-hoodi",
"arbitrum",
"base",
"base-sepolia",
"gnosis",
"optimism",
"polygon",
"polygon-amoy",
"starknet",
"zksync",
"linea",
"unichain",
"monad-testnet",
"monad",
"avalanche-c",
"avalanche-c-atomic",
"avalanche-p",
"binance",
"celo",
"fantom",
"harmony",
"moonriver",
"okc",
"viction",
"core",
"sonic",
"plasma",
"katana",
"hyperevm",
"agoric",
"akash",
"axelar",
"band-protocol",
"bitsong",
"canto",
"chihuahua",
"comdex",
"coreum",
"cosmos",
"crescent",
"cronos",
"cudos",
"desmos",
"dydx",
"evmos",
"fetch-ai",
"gravity-bridge",
"injective",
"irisnet",
"juno",
"kava",
"ki-network",
"mars-protocol",
"nym",
"okex-chain",
"onomy",
"osmosis",
"persistence",
"quicksilver",
"regen",
"secret",
"sentinel",
"sommelier",
"stafi",
"stargaze",
"stride",
"teritori",
"tgrade",
"umee",
"sei",
"mantra",
"celestia",
"saga",
"zetachain",
"dymension",
"humansai",
"neutron",
"polkadot",
"kusama",
"westend",
"bittensor",
"aptos",
"binancebeacon",
"cardano",
"near",
"solana",
"solana-devnet",
"stellar",
"stellar-testnet",
"sui",
"tezos",
"tron",
"ton",
"ton-testnet",
"hyperliquid",
] as const),
address: faker.helpers.arrayElement([
faker.string.alpha({ length: { min: 10, max: 20 } }),
undefined,
]),
logoURI: faker.helpers.arrayElement([
faker.string.alpha({ length: { min: 10, max: 20 } }),
undefined,
]),
isPoints: faker.helpers.arrayElement([
faker.datatype.boolean(),
undefined,
]),
coinGeckoId: faker.helpers.arrayElement([
faker.string.alpha({ length: { min: 10, max: 20 } }),
undefined,
]),
},
},
yieldSource: faker.helpers.arrayElement([
"staking",
"restaking",
"protocol_incentive",
"campaign_incentive",
"points",
"lending",
"mev",
"real_world_asset_yield",
"vault",
] as const),
description: faker.helpers.arrayElement([
faker.string.alpha({ length: { min: 10, max: 20 } }),
undefined,
]),
})),
},
},
totalBudget: faker.string.alpha({ length: { min: 10, max: 20 } }),
distributedBudget: faker.string.alpha({
length: { min: 10, max: 20 },
}),
remainingBudget: faker.string.alpha({ length: { min: 10, max: 20 } }),
configuredHourlyEmission: faker.helpers.arrayElement([
faker.helpers.arrayElement([
faker.string.alpha({ length: { min: 10, max: 20 } }),
null,
]),
undefined,
]),
apyCeiling: faker.helpers.arrayElement([
faker.helpers.arrayElement([
faker.number.float({ fractionDigits: 2 }),
null,
]),
undefined,
]),
qualificationConfig: {
...{
type: faker.helpers.arrayElement(
Object.values(CampaignQualificationType),
),
threshold: faker.string.alpha({ length: { min: 10, max: 20 } }),
maxIncentivizedTvlToken: faker.helpers.arrayElement([
faker.helpers.arrayElement([
faker.string.alpha({ length: { min: 10, max: 20 } }),
null,
]),
undefined,
]),
},
},
startTime: faker.date.past().toISOString().slice(0, 19) + "Z",
endTime: faker.date.past().toISOString().slice(0, 19) + "Z",
lastProcessedHour: faker.helpers.arrayElement([
faker.helpers.arrayElement([
faker.date.past().toISOString().slice(0, 19) + "Z",
null,
]),
undefined,
]),
nextPayoutDueAt: faker.helpers.arrayElement([
faker.helpers.arrayElement([
faker.date.past().toISOString().slice(0, 19) + "Z",
null,
]),
undefined,
]),
payoutFrequency: faker.helpers.arrayElement(
Object.values(CampaignPayoutFrequency),
),
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

Keep the campaign timeline internally consistent.

Line 11103 through Line 11316 samples all campaign timestamps independently, so this mock can generate impossible states like endTime < startTime or nextPayoutDueAt < lastProcessedHour. That makes tests and stories using the new campaigns endpoint brittle, especially when status is also randomized separately.

🤖 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 `@src/api/index.msw.ts` around lines 11103 - 11316, The timestamps for
campaigns are sampled independently which can produce impossible timelines;
instead generate a base startTime (e.g., const start = faker.date.past()), then
compute endTime = faker.date.between(start, someLaterDate) and derive dependent
fields: lastProcessedHour (nullable) must be between start and end (or null),
nextPayoutDueAt (nullable) must be >= lastProcessedHour (when present) and <=
end, and any other time fields (createdAt, updatedAt) should be consistent
relative to start/end; update the code that sets startTime, endTime,
lastProcessedHour, nextPayoutDueAt (and related fields) to use these derived
values and preserve existing randomness for nullability and status handling.

/**
* Chain label returned by Staking Rewards
*/
export type YieldRiskStakingRewardsDtoChain = { [key: string]: unknown };
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 | 🟠 Major | ⚡ Quick win

Type chain as a label string

Line 4 currently allows arbitrary objects for a field documented as a chain label.

Proposed fix
-export type YieldRiskStakingRewardsDtoChain = { [key: string]: unknown };
+export type YieldRiskStakingRewardsDtoChain = string;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type YieldRiskStakingRewardsDtoChain = { [key: string]: unknown };
export type YieldRiskStakingRewardsDtoChain = string;
🤖 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 `@src/api/schemas/yieldRiskStakingRewardsDtoChain.ts` at line 4, The exported
type YieldRiskStakingRewardsDtoChain currently allows arbitrary unknown values;
change it so each chain key maps to a string label instead of unknown objects —
update the type definition for YieldRiskStakingRewardsDtoChain to be a mapping
from string keys to string values (i.e., value type should be string) so callers
treat chain entries as label strings.

/**
* Staking Rewards provider name
*/
export type YieldRiskStakingRewardsDtoProviderName = { [key: string]: unknown };
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 | 🟠 Major | ⚡ Quick win

providerName should be a string alias

Line 4 currently permits arbitrary object payloads for a field documented as a provider name.

Proposed fix
-export type YieldRiskStakingRewardsDtoProviderName = { [key: string]: unknown };
+export type YieldRiskStakingRewardsDtoProviderName = string;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type YieldRiskStakingRewardsDtoProviderName = { [key: string]: unknown };
export type YieldRiskStakingRewardsDtoProviderName = string;
🤖 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 `@src/api/schemas/yieldRiskStakingRewardsDtoProviderName.ts` at line 4, The
type YieldRiskStakingRewardsDtoProviderName currently allows any object ({ [key:
string]: unknown }) but should be a string alias; update the type declaration
for YieldRiskStakingRewardsDtoProviderName to be a string (e.g., export type
YieldRiskStakingRewardsDtoProviderName = string) and update any locations that
import or use YieldRiskStakingRewardsDtoProviderName to expect a string (or a
tighter string literal/union if desired) so validation and typings reflect a
provider name string.

Comment on lines +1 to +4
/**
* Staking Rewards rating
*/
export type YieldRiskStakingRewardsDtoRating = { [key: string]: unknown };
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 | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for OpenAPI spec or API schema definitions

echo "=== Searching for OpenAPI/Swagger specs ==="
fd -e json -e yaml -e yml openapi swagger api-spec

echo -e "\n=== Checking for schema generation config ==="
fd -e json -e js -e ts orval openapi-generator api-codegen

echo -e "\n=== Searching for existing YieldRiskStakingRewardsDto usage ==="
rg -n "YieldRiskStakingRewardsDto" --type=ts -C 3

Repository: stakekit/sdk

Length of output: 11233


Define specific types for StakingRewards DTO properties instead of using permissive index signatures.

The pattern { [key: string]: unknown } appears across 13+ type files in the StakingRewards schema, defeating TypeScript's type safety. Despite JSDoc comments describing specific semantics (e.g., "score (1-5)", "Date when rating was assessed", "profile URL"), the types accept any object shape.

Affected files:

  • yieldRiskStakingRewardsDtoRating.ts → should be a specific rating structure
  • yieldRiskStakingRewardsDtoScore.ts → should be number (1-5 range)
  • yieldRiskStakingRewardsDtoPotentialScore.ts → should be number (1-5 range)
  • yieldRiskStakingRewardsDtoRatedAt.ts → should be string (ISO date)
  • yieldRiskStakingRewardsDtoRatedSince.ts → should be string (ISO date)
  • yieldRiskStakingRewardsDtoProfileUrl.ts → should be string
  • yieldRiskStakingRewardsDtoReportUrl.ts → should be string
  • yieldRiskStakingRewardsDtoContractAddress.ts → should be string
  • yieldRiskStakingRewardsDtoPotentialRating.ts → should be a specific rating structure
  • yieldRiskStakingRewardsDtoVersion.ts → should be string
  • yieldRiskStakingRewardsDtoType.ts → should be string
  • yieldRiskStakingRewardsDtoProviderName.ts → should be string
  • yieldRiskStakingRewardsDtoChain.ts → should be string

This eliminates compile-time validation, IDE autocomplete, and allows runtime type errors. Replace the index signatures with proper types reflecting the semantics documented in JSDoc comments.

🤖 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 `@src/api/schemas/yieldRiskStakingRewardsDtoRating.ts` around lines 1 - 4,
Replace the permissive index-signature in YieldRiskStakingRewardsDtoRating and
the related files with explicit typed properties matching the JSDoc: define
YieldRiskStakingRewardsDtoRating as an object with specific fields (e.g., score:
number (1-5), potentialScore?: number (1-5), ratedAt?: string (ISO date),
ratedSince?: string (ISO date), profileUrl?: string, reportUrl?: string,
contractAddress?: string, potentialRating?: {...} same shape as rating,
version?: string, type?: string, providerName?: string, chain?: string); change
the separate files: YieldRiskStakingRewardsDtoScore and
YieldRiskStakingRewardsDtoPotentialScore to number,
YieldRiskStakingRewardsDtoRatedAt and RatedSince to string,
ProfileUrl/ReportUrl/ContractAddress/Version/Type/ProviderName/Chain to string,
and ensure the rating/potentialRating types reference the new specific rating
interface so IDEs and the compiler validate structure rather than allowing
{[key:string]: unknown}.

/**
* Staking Rewards full report URL
*/
export type YieldRiskStakingRewardsDtoReportUrl = { [key: string]: unknown };
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 | 🟠 Major | ⚡ Quick win

Use a URL scalar type for reportUrl

Line 4 currently allows any object, which breaks type safety for a documented URL field and can hide invalid payload mappings in consumers.

Proposed fix
-export type YieldRiskStakingRewardsDtoReportUrl = { [key: string]: unknown };
+export type YieldRiskStakingRewardsDtoReportUrl = string;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type YieldRiskStakingRewardsDtoReportUrl = { [key: string]: unknown };
export type YieldRiskStakingRewardsDtoReportUrl = string;
🤖 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 `@src/api/schemas/yieldRiskStakingRewardsDtoReportUrl.ts` at line 4, The
current broad index signature in the exported type
YieldRiskStakingRewardsDtoReportUrl should be replaced with an explicit URL
scalar property to enforce type safety: change the type to require a reportUrl
field (e.g., reportUrl: string or your project’s URL scalar type) instead of {
[key: string]: unknown }, update any serializers/validators that consume
YieldRiskStakingRewardsDtoReportUrl to validate/parse the URL value, and ensure
all usages of YieldRiskStakingRewardsDtoReportUrl (constructors, mappers, tests)
are updated to pass a reportUrl property.

/**
* Staking Rewards score (1-5)
*/
export type YieldRiskStakingRewardsDtoScore = { [key: string]: unknown };
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 | 🟠 Major | ⚡ Quick win

Model score as a bounded numeric type (1–5)

Given Line 2’s explicit range, Line 4 should not be an open object; this currently loses critical validation at compile time.

Proposed fix
-export type YieldRiskStakingRewardsDtoScore = { [key: string]: unknown };
+export type YieldRiskStakingRewardsDtoScore = 1 | 2 | 3 | 4 | 5;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type YieldRiskStakingRewardsDtoScore = { [key: string]: unknown };
export type YieldRiskStakingRewardsDtoScore = 1 | 2 | 3 | 4 | 5;
🤖 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 `@src/api/schemas/yieldRiskStakingRewardsDtoScore.ts` at line 4, Replace the
open-object type for YieldRiskStakingRewardsDtoScore with a bounded numeric type
so it only allows the integers 1 through 5; locate the type alias
YieldRiskStakingRewardsDtoScore and change its definition from a generic {[key:
string]: unknown} to a union of the allowed integer literals (1,2,3,4,5) or an
equivalent branded/validated numeric type so compile-time typing enforces the
1–5 range.

/**
* Staking Rewards product type
*/
export type YieldRiskStakingRewardsDtoType = { [key: string]: unknown };
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 | 🟠 Major | ⚡ Quick win

type should be a scalar discriminator, not an object

Line 4 weakens the DTO by allowing arbitrary object shapes for a product type field.

Proposed fix
-export type YieldRiskStakingRewardsDtoType = { [key: string]: unknown };
+export type YieldRiskStakingRewardsDtoType = string;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type YieldRiskStakingRewardsDtoType = { [key: string]: unknown };
export type YieldRiskStakingRewardsDtoType = string;
🤖 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 `@src/api/schemas/yieldRiskStakingRewardsDtoType.ts` at line 4, The DTO
currently declares YieldRiskStakingRewardsDtoType as a loose object ({ [key:
string]: unknown }) which allows arbitrary shapes; change it to a scalar
discriminator (e.g., a plain string or a string literal union/enum) so the
product type is a single scalar value. Update the declaration of
YieldRiskStakingRewardsDtoType to a scalar type (or a string enum of allowed
product types), and adjust any validation/serialization code and places that
import/use YieldRiskStakingRewardsDtoType to expect a scalar product type
instead of an object.

/**
* Staking Rewards methodology version
*/
export type YieldRiskStakingRewardsDtoVersion = { [key: string]: unknown };
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 | 🟠 Major | ⚡ Quick win

Narrow version to a scalar version token

Line 4 exposes an object shape where a methodology version value is expected, reducing DTO correctness.

Proposed fix
-export type YieldRiskStakingRewardsDtoVersion = { [key: string]: unknown };
+export type YieldRiskStakingRewardsDtoVersion = string;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export type YieldRiskStakingRewardsDtoVersion = { [key: string]: unknown };
export type YieldRiskStakingRewardsDtoVersion = string;
🤖 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 `@src/api/schemas/yieldRiskStakingRewardsDtoVersion.ts` at line 4, The exported
type YieldRiskStakingRewardsDtoVersion is currently a catch-all object ({ [key:
string]: unknown }) but should be a scalar version token; change the type
definition of YieldRiskStakingRewardsDtoVersion from an open object to an
appropriate scalar (e.g., string or a narrow union of allowed tokens) and update
any validators or usages that expect a version token to reflect the new scalar
type so DTO correctness is restored.

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.

1 participant