Skip to content

feat/implement-grants-governance-proposal - #3245

Merged
Agilulfo1820 merged 51 commits into
mainfrom
claude/implement-governance-proposal-Yxx0B
May 28, 2026
Merged

Agilulfo1820 merged 51 commits into
mainfrom
claude/implement-governance-proposal-Yxx0B

Conversation

@rosavechain

@rosavechain rosavechain commented Apr 15, 2026 •

Copy link
Copy Markdown
Contributor

Add cost breakdown requirement, spending plan, and expenditure reporting
to the grant application and milestone workflow per governance proposal.

Frontend

  • New Budget step in grant application form (5-step flow)
  • Cost breakdown with freeform categories and line-item justification
  • Spending plan text field for allocation timeline
  • Standardized Grant Expenditure Report (SGER) form and view
  • Expenditure report submission via IPFS with local CID tracking
  • Budget tab on grant detail page
  • Full backward compatibility: existing grants render without new fields

Missing-report warning visibility

  • Warn on every current funding milestone (Pending or Approved) when no expenditure report is recorded on chain
  • Visible to proposer, grants approver, and grants receiver
  • Approver still gates Approve & Fund with an override checkbox; receiver's Claim is not gated
  • Submit / Update expenditure report CTA available to proposer, receiver, and GRANTS_APPROVER_ROLE

GrantsManager V2 -> V3 (contract upgrade)

  • updateMilestoneMetadataURI widened from proposer-only to proposer + grants receiver + GRANTS_APPROVER_ROLE + GOVERNANCE_ROLE
  • Production reason: the grants approver wallet acts as proposer for nearly every grant, so the receiving app could not persist expenditure reports under V2
  • Frozen V2 copy under deprecated/V2/; upgrade script grants-manager-v3.ts + upgradesConfig entry
  • Deploy chain V1 -> V2 -> V3 in deployAll and test/helpers/deploy
  • New v3-metadata-access.test.ts (7 tests, shard4k); 36 existing milestone-creation tests still pass

Demos

New grants creation step

Registrazione.schermo.2026-05-25.alle.15.57.16.mov

First milestone approval (no change)

Registrazione.schermo.2026-05-25.alle.17.04.37.mov

Expenditure report

add.report.mov

Staging demo grant: https://staging.testnet.governance.vebetterdao.org/grants/17676221342976277228059531915983165507149829855567351017761942598283788656553

image image image image

…4937)

Add cost breakdown requirement, spending plan, and expenditure reporting
to the grant application and milestone workflow per governance proposal.

- New Budget step in grant application form (5-step flow)
- Cost breakdown with freeform categories and line-item justification
- Spending plan text field for allocation timeline
- Standardized Grant Expenditure Report (SGER) form and view
- Expenditure report submission via IPFS with local CID tracking
- Soft warning on milestone claim when no report submitted
- Budget tab on grant detail page
- Full backward compatibility: existing grants render without new fields

https://claude.ai/code/session_01ETAH8ARoCSmWYkdaKVHCVz
@coderabbitai

coderabbitai Bot commented Apr 15, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 87623757-c7a8-4abc-9559-7e52fd96cc5f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/implement-governance-proposal-Yxx0B

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Apr 15, 2026 •

Copy link
Copy Markdown

Governance Frontend – Preview

Name Status Preview Updated (UTC)
staging ✅ Ready (3e47bfa) Custom Domain → • Default URL → 2026-05-28 11:08:32
beta ✅ Ready (3e47bfa) Custom Domain → • Default URL → 2026-05-28 11:08:32

⏱️ Note: Custom domains may take 5-10 minutes to activate on first deployment. Use Default URL in the meantime.


Built with commit 3e47bfa • Preview environments are automatically destroyed when PRs are closed

@rosavechain
rosavechain temporarily deployed to AWS staging governance build-time April 15, 2026 13:10 — with GitHub Actions Inactive
@rosavechain
rosavechain temporarily deployed to AWS beta governance build-time April 15, 2026 13:10 — with GitHub Actions Inactive
@davidecarpini
davidecarpini marked this pull request as draft April 15, 2026 13:19
@Agilulfo1820 Agilulfo1820 added the increment:minor PR adds functionality in a backwards compatible manner label Apr 15, 2026
@Agilulfo1820 Agilulfo1820 changed the title claude/implement-governance-proposal-Yxx0B feat/implement-grants-governance-proposal Apr 21, 2026
Use Fragment instead of nested Grid for rows so all cells
are direct children of the same Grid and columns line up
with the headers.

https://claude.ai/code/session_01ETAH8ARoCSmWYkdaKVHCVz
@rosavechain
rosavechain temporarily deployed to AWS staging governance build-time April 21, 2026 13:13 — with GitHub Actions Inactive
@rosavechain
rosavechain temporarily deployed to AWS dev governance build-time April 21, 2026 13:13 — with GitHub Actions Inactive
@rosavechain
rosavechain temporarily deployed to AWS beta governance build-time April 21, 2026 13:13 — with GitHub Actions Inactive
Store SGER data in GrantsManager milestone metadata as versioned JSON
(milestones + expenditureReports), merge on submit, and call
updateMilestoneMetadataURI after pinning. Proposer-only UI for report
submission; preserve reports when editing milestone dates.

Remove local-only expenditure report CID store. Parse legacy array
metadata for backward compatibility. Add i18n string for non-proposer
grant recipients. Fix dynamic route Props exports and snapshot aria i18n
for typecheck.

Made-with: Cursor
@rosavechain
rosavechain temporarily deployed to AWS beta governance build-time April 23, 2026 13:27 — with GitHub Actions Inactive
@rosavechain
rosavechain temporarily deployed to AWS dev governance build-time April 23, 2026 13:27 — with GitHub Actions Inactive
@rosavechain
rosavechain temporarily deployed to AWS staging governance build-time April 23, 2026 13:27 — with GitHub Actions Inactive
Show the expenditure-report warning for the first milestone as well as
later ones. Update copy to describe this payout milestone rather than
"prior tranche" only.

Made-with: Cursor
@rosavechain
rosavechain temporarily deployed to AWS staging governance build-time April 23, 2026 14:56 — with GitHub Actions Inactive
@rosavechain
rosavechain temporarily deployed to AWS dev governance build-time April 23, 2026 14:56 — with GitHub Actions Inactive
@rosavechain
rosavechain temporarily deployed to AWS beta governance build-time April 23, 2026 14:56 — with GitHub Actions Inactive
@rosavechain

Copy link
Copy Markdown
Contributor Author

Adding structured financial accountability to the grant lifecycle without breaking existing grants.

  • Budget step in application form: new 5th step collects itemized cost breakdown (freeform categories + line-item justification) and a spending-plan narrative. Can't proceed if not uploading this info, it is mandatory
  • Standardized Grant Expenditure Report (SGER): form + view for proposers to document actual spend at each milestone; persisted as versioned JSON in the milestone's IPFS metadata URI (merged alongside existing milestone data so history is never lost)
  • Reviewer safeguard: warning shown before every "Approve & Fund" action if no SGER has been submitted for the milestone being funded — covers first payout too, not just later tranches
  • Budget tab on grant detail page: read-only CostBreakdownView surfacing the planned budget to voters and reviewers; a layout fix (Fragment-based Grid rows) ensures columns align with headers
  • Full backward compatibility: existing grants without budget data render cleanly and display

Philosophy: additive-only changes (no schema breaks and no contracts changes), data ownership on-chain via IPFS, soft warnings over hard blocks for UX, and surgical scoping, only the grant flow was touched.

@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS staging governance build-time May 6, 2026 08:54 — with GitHub Actions Inactive
@Agilulfo1820
Agilulfo1820 deployed to AWS dev governance build-time May 6, 2026 08:54 — with GitHub Actions Active
@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS beta governance build-time May 6, 2026 08:54 — with GitHub Actions Inactive
Agilulfo1820 and others added 5 commits May 6, 2026 11:18
…em in report form

- handleSaveEdit re-reads on-chain milestone metadata URI + IPFS doc before
  rebuilding the payload, so concurrently submitted expenditure reports
  (other tab, stale React Query cache) are no longer overwritten when a
  proposer edits milestone dates. Surface a toast on IPFS upload failure
  instead of silently returning.
- ExpenditureReportForm: replace raw <input>/<textarea> with Chakra Input,
  Textarea, Field.Root, Field.Label. Drop inline pixel styles. Add min={0}
  on number inputs. Use semantic status.negative.strong for negative
  unspent amount.
- i18n: add "Failed to upload milestone metadata" across 17 locales and
  sort all locale files alphabetically per translate skill rules.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ExpenditureReportView:
- Flatten nested Grid (rows used inner Grid; headers misaligned). Use
  Fragment per row, mirroring CostBreakdownView.
- Translate Yes/No/Partially achievement label.
- Translate evidence type badge (GitHub/Demo/Dashboard/Audit Report/Other)
  with type-narrowed t() to satisfy strict i18n typing.
- Add rel="noopener noreferrer" to external evidence links and switch to
  Chakra Link variant="underline" instead of raw blue.500.
- Replace red.500 with semantic status.negative.strong for negative
  unspent display.

ExpenditureReportForm:
- Validate evidence URLs (must parse; protocol must be http(s)).
- Require milestone explanation when status is no/partially.
- Require totalReceivedForTranche to be > 0.
- Translate evidence type select options.

i18n: add GitHub, Demo, Audit Report, "Please specify the total amount
received", "Please explain the milestone status" across 17 locales.
Reuse the existing "Please enter a valid URL starting with http:// or
https://" key from validators.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…cAlert

- useUpdateGrantMilestoneMetadata: invalidate by ["grantProposalMetadata",
  proposalId] prefix instead of the full (proposalId, ipfsDescription)
  key. Catches the registered query regardless of the description CID
  used at call time, and removes the unused proposalIpfsDescription arg.
- MilestoneItem: replace raw orange.50/600/700 SGER-missing warning block
  with GenericAlert type="warning". Aligns with the project's semantic
  alert pattern and drops raw palette colors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ssion)

Commit d3795ad switched [proposalId]/[grantId]/[appId] page.tsx Props
from Promise<{...}> + await params back to a sync object to silence a
typecheck error. In Next.js 15+/16, params is a Promise — accessing it
synchronously yields undefined, so any downstream BigInt(proposalId) or
similar coercion threw "Cannot convert undefined to a BigInt" the moment
a user opened a proposal/grant/app page.

Restore Promise-typed params with await across all three dynamic routes
to match the layout.tsx pattern already in the codebase.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Card.Title renders <h3> and a Heading inside it renders <h2>, producing
invalid HTML. Match the sibling "Results" section (which uses Heading
directly with no Card.Title wrapper).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Agilulfo1820 and others added 11 commits May 25, 2026 15:28
Non-blocking warning under the milestones grid when the sum of milestone
amounts doesn't match the cost-breakdown total. Only triggers once both
sides are populated so we don't pester users mid-edit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The expenditure report for Milestone N documents how its funds were
spent, which is the proof reviewers use to fund Milestone N+1. Realign
the UI to that semantic:

- Missing-report warning + Approve & Fund override now check the
  previous milestone's report (Milestone 1 needs no precursor — first
  funding is never gated).
- New warning copy names the two milestones explicitly.
- Submit / Update CTA is no longer pinned to the current step; any
  milestone in InDevelopment (not Rejected) can be reported on by an
  authorized wallet, since reports are filed after each milestone
  closes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The mainnet rule (each milestone starts at least one day after the
previous ends, end > start by a day) blocks practical end-to-end tests
on testnet-staging. Gate that strictness behind getConfig().environment
=== "mainnet"; everywhere else, same-day chains are accepted and the
DatePicker min-pickable date drops the +1 day buffer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
To test the full grant lifecycle quickly (e.g. milestones five minutes
apart) the calendar in FormDateInput now exposes hour and minute inputs
on every env except mainnet. Today becomes selectable, the popover
stays open after picking a day so the tester can dial the time, and a
Done button closes it. Mainnet behaviour is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mainnet)

The grant-edit flow uses src/components/DatePicker (different from the
form's FormDateInput). Add an opt-in enableTimeSelection prop: when on
in single-variant mode, the popover exposes hour/minute inputs, stays
open after the day click for fine-tuning, emits "YYYY-MM-DDTHH:mm",
and shows a Done button. MilestoneItem turns it on when env != mainnet
and seeds the duration state with HH:mm so existing milestone times
round-trip correctly. Transaction-history range picker is untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…osals

Queued proposals can only run after the timelock delay elapses; the
button used to be enabled and tx reverted. Fetch proposalEta from
B3TRGovernor, tick a per-second clock while in Queued, and:

- Disable Execute Proposal while now < eta.
- Render an info alert ("Available to execute in 2h 14m 03s") so the
  user knows when to come back.

useProposalEta refetches every 15s for stale-tab safety.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Once a proposal is past its timelock eta, simulate execute() against the
node and:

- Render an error alert with the decoded revert reason (e.g. "Treasury:
  transfer limit exceeded") so the executor isn't left guessing.
- Disable the Execute Proposal button while the simulation indicates a
  revert; re-enables automatically when underlying state changes
  (re-checked every 30s).

The simulator decodes Solidity Error(string) reverts and falls back to
the raw hex / vmError otherwise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…imed

A report documents how a milestone's funds were spent, so the CTA only
makes sense after the receiver has claimed that milestone. Previously
every milestone in an InDevelopment grant showed Submit, including ones
that had never been funded.

New rule: Submit/Update is visible only when milestone.state === Claimed
(and the wallet has permission). Read-only report cards keep showing on
any milestone that already has a report, regardless of state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…on report submit

ExpenditureReportForm:
- Prefill "Total received for this tranche (USD)" from milestone B3TR
  amount × current B3TR/USD price (only when creating a new report;
  Update mode keeps the existing value). Helper text explains the
  source so the user knows they can override.
- Validation now produces inline Field.ErrorText / red borders per
  field instead of toasts, matching the grant creation form pattern.
  URL invalid → flags the specific evidence-row URL field.
- Submit errors render as inline text under the form.

MilestonesActions:
- handleReportSubmit no longer toasts on success/error; it throws on
  failure so the form can surface the message inline. Success simply
  closes the modal (no toast).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the 12 expenditure-report / timelock / budget keys introduced in
this branch to de, es, fr, hi, it, ja, ko, nl, pt, ro, ru, sv, tr, tw,
vi, zh. Sorts every translation file (including en.json) alphabetically
case-insensitive.

Translations are best-effort and may benefit from a native-speaker pass,
but they're consistent with the fixed-words convention (B3TR/VOT3/B3MO
left untranslated; no endorsement-family terms in these strings).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS beta governance build-time May 25, 2026 16:11 — with GitHub Actions Inactive
@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS staging governance build-time May 25, 2026 16:11 — with GitHub Actions Inactive
@Agilulfo1820
Agilulfo1820 marked this pull request as ready for review May 25, 2026 16:12

@davidecarpini davidecarpini left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTClaude 🤖

Comment thread apps/frontend/src/app/grants/components/MilestoneItem.tsx
Comment thread apps/frontend/src/components/CustomFormFields/FormDateInput.tsx
@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS beta governance build-time May 27, 2026 16:39 — with GitHub Actions Inactive
@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS staging governance build-time May 27, 2026 16:39 — with GitHub Actions Inactive
…rnance-proposal-Yxx0B

# Conflicts:
#	apps/frontend/src/i18n/languages/de.json
#	apps/frontend/src/i18n/languages/en.json
#	apps/frontend/src/i18n/languages/es.json
#	apps/frontend/src/i18n/languages/fr.json
#	apps/frontend/src/i18n/languages/hi.json
#	apps/frontend/src/i18n/languages/it.json
#	apps/frontend/src/i18n/languages/ja.json
#	apps/frontend/src/i18n/languages/ko.json
#	apps/frontend/src/i18n/languages/nl.json
#	apps/frontend/src/i18n/languages/pt.json
#	apps/frontend/src/i18n/languages/ro.json
#	apps/frontend/src/i18n/languages/ru.json
#	apps/frontend/src/i18n/languages/sv.json
#	apps/frontend/src/i18n/languages/tr.json
#	apps/frontend/src/i18n/languages/tw.json
#	apps/frontend/src/i18n/languages/vi.json
#	apps/frontend/src/i18n/languages/zh.json
@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS staging governance build-time May 28, 2026 10:47 — with GitHub Actions Inactive
@Agilulfo1820
Agilulfo1820 temporarily deployed to AWS beta governance build-time May 28, 2026 10:47 — with GitHub Actions Inactive
@Agilulfo1820
Agilulfo1820 merged commit 2f5db1f into main May 28, 2026
80 checks passed
@Agilulfo1820
Agilulfo1820 deleted the claude/implement-governance-proposal-Yxx0B branch May 28, 2026 11:58
@github-actions

Copy link
Copy Markdown

🚀 Preview Environment Status

🎉 PR Merged - Preview environments destroyed

Flavor Status URL Logs
staging 🗑️ Destroyed pr-3245-staging.preview.governance.vebetterdao.org View logs
beta 🗑️ Destroyed pr-3245-beta.preview.governance.vebetterdao.org View logs

Last updated: 2026-05-28T12:00:41.618Z

This branch was successfully deployed

1 active (outdated) and 2 inactive deployments
AWS beta governance build-time — 3e47bfa4 Deployed May 28, 2026 by Agilulfo1820 via Build (beta) / Build and Push Docker Image #1016
AWS staging governance build-time — 3e47bfa4 Deployed May 28, 2026 by Agilulfo1820 via Build (staging) / Build and Push Docker Image #1016
AWS dev governance build-time — c3d0127c Deployed May 6, 2026 by Agilulfo1820 via Build (dev) / Build and Push Docker Image #891
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

increment:minor PR adds functionality in a backwards compatible manner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants