Skip to content

feat: manual raid revenue flow#17

Merged
ECWireless merged 3 commits into
mainfrom
codex/manual-raid-revenue-flow
Jun 13, 2026
Merged

feat: manual raid revenue flow#17
ECWireless merged 3 commits into
mainfrom
codex/manual-raid-revenue-flow

Conversation

@ECWireless

@ECWireless ECWireless commented Jun 13, 2026

Copy link
Copy Markdown
Member

This pull request introduces support for managing manual raid revenue entries in the admin quarter transactions workflow. It adds backend logic and UI components for saving and removing manual revenue entries, ensures proper validation and permissions, and updates the database schema to support these features.

Manual Raid Revenue Management

Database Schema Changes

  • Altered the ledger_entries table to add a source_external_id column and created a unique index to prevent duplicate manual entries for the same source.
  • Updated migration journal to include the new schema migration.

User Interface Enhancements

  • Enhanced the transaction lookup panel to support saving and removing manual raid revenue entries, including new UI components (SaveSubmitButton, RemoveRevenueButton) and toast notifications for user feedback. [1] [2]

These changes collectively enable admins to manually classify and manage raid revenue transactions that are not imported automatically, improving the flexibility and accuracy of the accounting workflow.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added manual ledger entry management in admin transactions view with remove capability for draft quarters.
    • Introduced manual raid revenue entry and tracking functionality.
    • Redesigned raid management interface using modals for streamlined interaction.
  • Style

    • Enhanced treasury dashboard layout with improved accounts section styling and responsive card grid.
  • Refactor

    • Restructured raids page UI with updated entity and raid display components.

Copilot AI review requested due to automatic review settings June 13, 2026 16:10
@vercel

vercel Bot commented Jun 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
raidguild-accounting Ready Ready Preview, Comment Jun 13, 2026 4:54pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

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

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

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

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

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

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

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e1d28a04-366f-47c5-9f62-70f45e16f561

📥 Commits

Reviewing files that changed from the base of the PR and between 1c086d3 and 2e6468f.

📒 Files selected for processing (4)
  • src/app/admin/quarters/[id]/transactions/page.tsx
  • src/app/raids/page.tsx
  • src/app/raids/remove-manual-revenue-form.tsx
  • src/app/raids/transaction-lookup-actions.ts
📝 Walkthrough

Walkthrough

This PR introduces a complete manual raid revenue ledger entry system. Users can record off-chain raid revenue by looking up manual transactions and saving them as ledger entries. The system includes server-side validation, deduplication via source_external_id, quarter-aware lifecycle enforcement, and audit logging. The raids page transitions from flow-based routing to modal-based routing, displaying manual revenues inline. Admin pages can view and remove manual entries when quarters are in draft status.

Changes

Manual Raid Revenue Ledger System

Layer / File(s) Summary
Database Schema & Migrations for Deduplication
drizzle/0012_lively_wind_dancer.sql, src/db/schema.ts, drizzle/meta/*
Add source_external_id nullable text column and unique index to ledger_entries table to enforce single-entry-per-transaction deduplication.
Manual Ledger Entry View Model & Queries
src/lib/transaction-classification.ts
Define ManualLedgerEntryClassificationView type and listManualLedgerEntryClassifications() query to fetch manual ledger entries by quarter with notes decryption.
Manual Revenue Save/Remove Server Actions
src/app/raids/transaction-lookup-actions.ts
Implement saveManualRaidRevenue, removeManualRaidRevenue, and removeManualRaidRevenueFromForm server actions with authorization, transaction lookup, transfer/USD validation, deduplication check, raid/quarter resolution, quarter edit/remove enforcement, encrypted notes, audit logging, and path revalidation.
Transaction Lookup Panel Save/Remove UI
src/app/raids/transaction-lookup-panel.tsx
Add SaveSubmitButton, RemoveRevenueButton, SavedRevenuePanel for removal with toast feedback, and RevenueSaveForm with transfer selection, USD input, and notes—all wired via useActionState to server actions.
Raids Page Modal-Based Routing & Layout Refactor
src/app/raids/page.tsx
Refactor from flow-based inline creation to modal-based routing with query parameters (?modal, ?entity, ?raid). Add ManualRaidRevenueView and listManualRaidRevenues() query. Introduce row-based rendering (EntityRows/EntityRow, RaidRows/RaidRow), ModalShell overlay, and ActiveModal dispatcher for conditional form/detail rendering.
Manual Ledger Entry Display in Admin Quarters Page
src/app/admin/quarters/[id]/transactions/page.tsx
Add ManualLedgerEntryCard component to render manual entries with classification metadata, transaction links, and conditional destructive removal button when quarter is draft and entry is raid_revenue.
Treasury Dashboard Layout Improvements
src/components/treasury/treasury-dashboard.tsx
Refactor "Included accounts" section from divided list to card-based grid with header row, icon, count pill, and repositioned address display.

Sequence Diagram

sequenceDiagram
    participant User
    participant TransactionLookupPanel
    participant saveManualRaidRevenue
    participant TransactionAPI
    participant Database
    participant AuditLog
    
    User->>TransactionLookupPanel: Enter chain, tx hash
    TransactionLookupPanel->>saveManualRaidRevenue: lookupRaidTransaction()
    saveManualRaidRevenue->>TransactionAPI: Fetch transaction details
    TransactionAPI-->>saveManualRaidRevenue: Returns transfers, amounts
    saveManualRaidRevenue-->>TransactionLookupPanel: Returns lookup result
    
    User->>TransactionLookupPanel: Select transfer, USD amount, submit
    TransactionLookupPanel->>saveManualRaidRevenue: saveManualRaidRevenue(formData)
    saveManualRaidRevenue->>Database: Check sourceExternalId uniqueness
    saveManualRaidRevenue->>Database: Fetch/create accounting quarter
    saveManualRaidRevenue->>Database: Validate quarter draft status
    saveManualRaidRevenue->>Database: Insert ledger entry with encrypted notes
    saveManualRaidRevenue->>AuditLog: Log entry creation
    saveManualRaidRevenue-->>TransactionLookupPanel: Return savedEntry
    TransactionLookupPanel->>TransactionLookupPanel: Show SavedRevenuePanel
    
    User->>TransactionLookupPanel: Click Remove button
    TransactionLookupPanel->>saveManualRaidRevenue: removeManualRaidRevenue(ledgerEntryId)
    saveManualRaidRevenue->>Database: Load entry + verify quarter draft
    saveManualRaidRevenue->>Database: Delete ledger entry
    saveManualRaidRevenue->>AuditLog: Log deletion
    saveManualRaidRevenue-->>TransactionLookupPanel: Return removed: true
    TransactionLookupPanel->>User: Show removal success
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • raid-guild/accounting#16: Both PRs extend the raid transaction lookup feature with manual revenue support; this PR adds the full save/remove workflow with deduplication and UI integration.

Poem

🐰 A rabbit's joy, when ledgers align!
Manual raids recorded, with sourceExternalId to shine,
Modal routes guide the journey through,
Draft quarters protected—only admins may undo.
From lookup to saved, a revenue trail so fine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: manual raid revenue flow' directly matches the PR's main objective of adding support for managing manual raid revenue entries, clearly summarizing the primary feature addition.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/manual-raid-revenue-flow

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds an end-to-end “manual raid revenue” flow so raid revenue transfers can be manually looked up, saved into the quarter ledger as ledger_entries with source="manual", and (while draft) removed again—surfacing these entries in both the /raids workflow and the admin quarter transactions review.

Changes:

  • Introduces server actions to save/remove manual raid revenue entries with permission checks, quarter-status validation, de-duplication via source_external_id, and audit logging.
  • Updates /raids UI to support transaction lookup + saving revenue to a selected raid, plus shows/removes saved manual revenue per raid.
  • Updates admin quarter transactions page to list manual ledger entries for the quarter and allow removal (draft only), and extends DB schema/migrations to support source_external_id.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/lib/transaction-classification.ts Adds a manual-ledger-entry view model and query to list manual ledger entries for a quarter.
src/db/schema.ts Adds ledger_entries.source_external_id and a unique index to prevent duplicate external-source entries.
src/components/treasury/treasury-dashboard.tsx Layout/UI tweaks for the “included accounts” list presentation.
src/app/raids/transaction-lookup-panel.tsx Extends the lookup panel UI to save manual raid revenue and remove it with toast feedback.
src/app/raids/transaction-lookup-actions.ts Implements server actions and validation for saving/removing manual raid revenue, including audit + revalidation.
src/app/raids/page.tsx Updates raids page to pass raids into the lookup panel, adds modal-based navigation, and displays/removes manual revenue entries per raid.
src/app/admin/quarters/[id]/transactions/page.tsx Fetches/displays manual ledger entries for a quarter and exposes a removal action (draft only).
drizzle/meta/0012_snapshot.json Drizzle snapshot update reflecting the new schema.
drizzle/meta/_journal.json Drizzle journal updated to include the new migration.
drizzle/0012_lively_wind_dancer.sql Migration adding source_external_id and a unique index on it.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/app/raids/page.tsx Outdated
Comment thread src/app/raids/transaction-lookup-actions.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/app/raids/transaction-lookup-actions.ts (1)

335-350: 💤 Low value

Unnecessary optional chaining on entry?.id.

On line 347, entry?.id uses optional chaining, but entry is guaranteed to exist at this point due to the check on lines 331-333. This is a minor inconsistency that could mislead readers about the variable's guaranteed presence.

🔧 Suggested fix
     await writeAuditEvent({
       action: "import",
       actorWalletAddress: session.address,
       metadata: {
         chainId,
         quarterId: quarter.id,
         raidId: raid.id,
         sourceExternalId,
         transferIndex,
         txHash: result.txHash,
       },
       quarterId: quarter.id,
-      subjectId: entry?.id,
+      subjectId: entry.id,
       subjectTable: "ledger_entries",
       summary: "Saved manual raid revenue",
     });
🤖 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/app/raids/transaction-lookup-actions.ts` around lines 335 - 350, The
audit event call uses unnecessary optional chaining on entry (entry?.id) even
though entry is guaranteed to exist earlier; update the writeAuditEvent
metadata/subjectId to use entry.id (remove the ?) in the call sites referencing
writeAuditEvent so the code reflects the guaranteed presence of entry and avoids
the misleading optional chaining.
src/app/raids/page.tsx (1)

1036-1081: 💤 Low value

Consider adding focus management for improved accessibility.

The modal has proper ARIA attributes (role="dialog", aria-modal, aria-label) and visible close affordances. For enhanced accessibility, consider:

  1. Focus trap: Focus should be contained within the modal while open
  2. Escape key: Allow closing with keyboard
  3. Initial focus: Focus the first focusable element or close button on open
  4. Restore focus: Return focus to trigger element on close

This would require converting to a Client Component or using a modal library like @headlessui/react or @radix-ui/react-dialog.

🤖 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/app/raids/page.tsx` around lines 1036 - 1081, ModalShell lacks focus
management; convert it to a Client Component (add "use client" at top) and
implement accessible modal behaviors: capture and save document.activeElement on
open and restore on close, trap focus within the modal (cycle focus among
tabbable elements inside the ModalShell container), move initial focus to the
close Link or first focusable child when mounting, and listen for Escape to
trigger the same close navigation (use router.push or Link navigation handler).
Alternatively, replace ModalShell with a tested dialog from
`@radix-ui/react-dialog` or `@headlessui/react-dialog` and wire the same
close/navigation to /raids so focus restoration and trapping are handled by the
library.
🤖 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 `@src/app/admin/quarters/`[id]/transactions/page.tsx:
- Around line 740-748: The remove form for manual raid revenue entries currently
submits destructively without confirmation; add a client-side confirmation step
by attaching an onSubmit handler to the <form> that wraps the hidden
ledgerEntryId and calls confirm('Remove this manual entry? This action cannot be
undone.'), calling event.preventDefault() when the user cancels; implement this
on the form that uses removeManualRaidRevenueFromForm (or alternatively
implement a two-step confirm state on the Remove <Button>) so the destructive
action only proceeds after explicit user confirmation.

---

Nitpick comments:
In `@src/app/raids/page.tsx`:
- Around line 1036-1081: ModalShell lacks focus management; convert it to a
Client Component (add "use client" at top) and implement accessible modal
behaviors: capture and save document.activeElement on open and restore on close,
trap focus within the modal (cycle focus among tabbable elements inside the
ModalShell container), move initial focus to the close Link or first focusable
child when mounting, and listen for Escape to trigger the same close navigation
(use router.push or Link navigation handler). Alternatively, replace ModalShell
with a tested dialog from `@radix-ui/react-dialog` or `@headlessui/react-dialog` and
wire the same close/navigation to /raids so focus restoration and trapping are
handled by the library.

In `@src/app/raids/transaction-lookup-actions.ts`:
- Around line 335-350: The audit event call uses unnecessary optional chaining
on entry (entry?.id) even though entry is guaranteed to exist earlier; update
the writeAuditEvent metadata/subjectId to use entry.id (remove the ?) in the
call sites referencing writeAuditEvent so the code reflects the guaranteed
presence of entry and avoids the misleading optional chaining.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: a88d26ff-eda3-4f7b-ba26-f7c245507699

📥 Commits

Reviewing files that changed from the base of the PR and between 808d5c1 and 1c086d3.

📒 Files selected for processing (10)
  • drizzle/0012_lively_wind_dancer.sql
  • drizzle/meta/0012_snapshot.json
  • drizzle/meta/_journal.json
  • src/app/admin/quarters/[id]/transactions/page.tsx
  • src/app/raids/page.tsx
  • src/app/raids/transaction-lookup-actions.ts
  • src/app/raids/transaction-lookup-panel.tsx
  • src/components/treasury/treasury-dashboard.tsx
  • src/db/schema.ts
  • src/lib/transaction-classification.ts

Comment thread src/app/admin/quarters/[id]/transactions/page.tsx
@ECWireless ECWireless merged commit 2764f7c into main Jun 13, 2026
5 checks passed
@ECWireless ECWireless deleted the codex/manual-raid-revenue-flow branch June 13, 2026 16:58
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.

2 participants