Skip to content
This repository was archived by the owner on Feb 8, 2026. It is now read-only.

⚡️ Stable version of fees and soft delete implemented#139

Merged
garry-sharp merged 1 commit into
mainfrom
fee-stable
Jul 28, 2025
Merged

⚡️ Stable version of fees and soft delete implemented#139
garry-sharp merged 1 commit into
mainfrom
fee-stable

Conversation

@garry-sharp

@garry-sharp garry-sharp commented Jul 24, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added support for configuring the Ethereum chain ID in fee-related settings and workflows.
    • Updated configuration files to include a new option for setup messaging in the vault service.
  • Bug Fixes

    • Improved transaction signing requests to use hashed transaction digests for enhanced security.
  • Refactor

    • Changed policy deletion to use soft delete instead of hard delete, preserving policy data for future reference.
    • Updated HTTP responses for policy deletion to provide clearer feedback to users.
    • Enforced data integrity rules on policies marked as deleted to prevent their insertion or modification and ensure they become inactive.
    • Removed redundant checks for recently proposed transactions to streamline transaction processing.

Copilot AI review requested due to automatic review settings July 24, 2025 11:11
@coderabbitai

coderabbitai Bot commented Jul 24, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

The updates introduce a new ChainId configuration for Ethereum in the fee plugin, adjust transaction signing to use hashed digests, and change plugin policy deletion to a soft-delete mechanism. Additionally, there are minor changes to API responses and configuration files, including a new boolean property in the vault service configuration. Database schema changes add triggers to enforce data integrity on soft-deleted policies. Dependency versions in go.mod were also updated. The removal of redundant IsAlreadyProposed methods in fee and payroll plugins is included.

Changes

File(s) Change Summary
plugin/fees/config.go Added ChainId *big.Int to FeeConfig, new WithChainId option, and validation in constructor.
plugin/fees/fees.go Updated to use feeConfig.ChainId for Ethereum SDK initialization; removed previous chain ID retrieval logic.
plugin/fees/transaction.go Changed transaction signing to use hexutil encoding and SHA-256 hashed transaction digests; updated signing request fields; removed IsAlreadyProposed method.
plugin/payroll/transaction.go Removed IsAlreadyProposed method and related imports.
storage/postgres/policy.go Switched policy deletion to soft-delete (deleted=true), removed deletion from transaction_history table.
storage/postgres/schema/schema.sql Added deleted boolean column to plugin_policies; created triggers and functions to enforce no insert/update on deleted policies and auto-set inactive on delete.
api/plugin.go Changed delete policy API response from HTTP 204 (no content) to HTTP 200 with JSON body containing deleted policy ID.
fee.worker.example.json Added "do_setup_msg": true to vault_service section.
go.mod Updated versions of github.com/vultisig/recipes and github.com/vultisig/verifier dependencies.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant API
    participant DB

    User->>API: DELETE /plugin/policy/{id}
    API->>DB: Update plugin_policies set deleted=true where id={id}
    API->>User: 200 OK { "id": "{id}" }
Loading
sequenceDiagram
    participant FeePlugin
    participant FeeConfig
    participant EthereumSDK

    FeePlugin->>FeeConfig: Get ChainId
    FeePlugin->>EthereumSDK: Initialize with ChainId
Loading
sequenceDiagram
    participant FeePlugin
    participant EthereumTx
    participant Signer

    FeePlugin->>EthereumTx: Decode unsigned payload
    FeePlugin->>Signer: Get transaction hash
    Signer->>FeePlugin: Return hash
    FeePlugin->>FeePlugin: SHA-256 hash of transaction hash
    FeePlugin->>Signer: Send base64-encoded hash for signing
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hops through fields of code,
With hashes signed and configs bestowed.
Policies now softly sleep,
Chain IDs set, no secrets to keep.
The vault says "hello" with a flag so new,
While Ethereum hops on, with IDs in view.
🐇✨


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6073c74 and ca36ae3.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • api/plugin.go (1 hunks)
  • fee.worker.example.json (1 hunks)
  • go.mod (1 hunks)
  • plugin/fees/config.go (4 hunks)
  • plugin/fees/fees.go (1 hunks)
  • plugin/fees/transaction.go (4 hunks)
  • plugin/payroll/transaction.go (0 hunks)
  • storage/postgres/policy.go (1 hunks)
  • storage/postgres/schema/schema.sql (3 hunks)
💤 Files with no reviewable changes (1)
  • plugin/payroll/transaction.go
✅ Files skipped from review due to trivial changes (2)
  • go.mod
  • plugin/fees/fees.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • fee.worker.example.json
  • api/plugin.go
  • storage/postgres/policy.go
  • plugin/fees/config.go
  • plugin/fees/transaction.go
  • storage/postgres/schema/schema.sql
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fee-stable

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
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @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 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.

Copilot AI 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.

Pull Request Overview

This PR implements soft delete functionality for plugin policies and stabilizes the fee plugin transaction handling. The changes introduce database-level constraints to prevent updates to deleted policies while ensuring proper transaction signing.

  • Implements soft delete pattern for plugin_policies table with database triggers for data integrity
  • Updates fee plugin to use proper Ethereum transaction hashing and base64 encoding for signing
  • Changes API response for policy deletion to return JSON instead of empty response

Reviewed Changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
storage/postgres/schema/schema.sql Adds deleted column and database triggers for soft delete functionality
storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql Migration implementing soft delete with database constraints
storage/postgres/policy.go Updates delete operation to use soft delete instead of hard delete
plugin/fees/transaction.go Improves transaction signing with proper Ethereum hash calculation
go.mod Updates verifier dependency version
fee.worker.example.json Adds configuration option for setup messages
api/plugin.go Changes delete API response from 204 to 200 with JSON body

Comment thread storage/postgres/policy.go
Comment thread plugin/fees/transaction.go Outdated
Comment thread plugin/fees/transaction.go Outdated
Comment thread api/plugin.go

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🧹 Nitpick comments (2)
api/plugin.go (1)

183-186: API response change may break existing clients

Changing from 204 No Content to 200 OK with a JSON response body is a breaking change for API clients. Clients expecting a 204 status may fail when receiving 200.

Consider:

  1. Documenting this breaking change in the API changelog
  2. Versioning the API endpoint if backward compatibility is needed
  3. Ensuring all API clients are updated to handle the new response format
storage/postgres/schema/schema.sql (1)

178-181: Missing partial index for fast look-ups on non-deleted active policies

Typical queries will filter on WHERE deleted = false AND active = true.
Creating a partial index greatly speeds these reads and keeps bloat down:

CREATE INDEX idx_plugin_policies_active_not_deleted
  ON plugin_policies(id)
  WHERE active = true AND deleted = false;

Consider adding this in a follow-up migration.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4c39122 and 62ca56f.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (7)
  • api/plugin.go (1 hunks)
  • fee.worker.example.json (1 hunks)
  • go.mod (1 hunks)
  • plugin/fees/transaction.go (5 hunks)
  • storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql (1 hunks)
  • storage/postgres/policy.go (1 hunks)
  • storage/postgres/schema/schema.sql (3 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: webpiratt
PR: vultisig/plugin#89
File: storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql:13-13
Timestamp: 2025-06-11T18:42:54.241Z
Learning: In the `tx_indexer` table (storage/postgres/migrations/plugin/*_tx_indexer.sql), the `policy_id` column is intentionally **not** defined with a foreign-key constraint to `plugin_policies(id)`.
go.mod (2)

Learnt from: RaghavSood
PR: #36
File: api/server.go:21-33
Timestamp: 2025-05-07T08:23:45.882Z
Learning: The import path github.com/vultisig/verifier/plugin refers to an external dependency that provides the plugin interface, and should not be changed to github.com/vultisig/plugin/plugin as these are distinct packages with different purposes.

Learnt from: johnnyluo
PR: #108
File: Dockerfile.Payroll.server:14-19
Timestamp: 2025-07-02T04:55:36.331Z
Learning: In the vultisig/plugin repository, the team maintains both the main repository and the go-wrappers dependency repository, so they are comfortable downloading from the master branch rather than pinning to specific commits.

fee.worker.example.json (3)

Learnt from: johnnyluo
PR: #108
File: cmd/payroll/worker/main.go:84-84
Timestamp: 2025-07-02T04:58:30.139Z
Learning: VaultServiceConfig is defined as a field of type vault_config.Config from the external package "github.com/vultisig/verifier/vault_config" in worker configuration structs across the vultisig/plugin codebase (cmd/payroll/worker/config.go, cmd/fees/worker/config.go, cmd/dca/worker/config.go). The vault_config.Config struct contains an EncryptionSecret field that can be accessed via cfg.VaultServiceConfig.EncryptionSecret.

Learnt from: johnnyluo
PR: #108
File: cmd/payroll/worker/main.go:84-84
Timestamp: 2025-07-02T04:58:30.139Z
Learning: VaultServiceConfig is defined as a field of type vault_config.Config in worker configuration structs across the vultisig/plugin codebase (cmd/payroll/worker/config.go, cmd/fees/worker/config.go, cmd/dca/worker/config.go). It contains an EncryptionSecret field that can be accessed via cfg.VaultServiceConfig.EncryptionSecret.

Learnt from: garry-sharp
PR: #113
File: fee.worker.example.json:9-9
Timestamp: 2025-07-03T15:54:18.797Z
Learning: In configuration files, local_party_prefix values can contain hexadecimal digit patterns like "feee" which are intentional, not typos.

storage/postgres/policy.go (2)

Learnt from: webpiratt
PR: #89
File: storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql:13-13
Timestamp: 2025-06-11T18:42:54.241Z
Learning: In the tx_indexer table (storage/postgres/migrations/plugin/*_tx_indexer.sql), the policy_id column is intentionally not defined with a foreign-key constraint to plugin_policies(id).

Learnt from: webpiratt
PR: #125
File: plugin/payroll/policy.go:160-160
Timestamp: 2025-07-09T22:23:17.348Z
Learning: In plugin/payroll/policy.go, the "token" case in the checkRule method intentionally does not call validateToken() as this is a temporary implementation that will be replaced with generic schema validation. The missing validation call is expected behavior during this transition period.

plugin/fees/transaction.go (10)

Learnt from: webpiratt
PR: #96
File: plugin/payroll/transaction.go:0-0
Timestamp: 2025-06-18T18:23:20.077Z
Learning: In the payroll plugin (plugin/payroll/transaction.go), signRequest.Transaction is stored with the "0x" prefix, making it compatible with gcommon.FromHex which requires 0x-prefixed hex strings.

Learnt from: webpiratt
PR: #96
File: plugin/payroll/transaction.go:43-44
Timestamp: 2025-06-18T18:22:06.358Z
Learning: In the vultisig/plugin codebase, the hardcoded ethereumEvmChainID = big.NewInt(1) in plugin/payroll/transaction.go is intentional for the current implementation phase. The team is implementing ETH first, with plans to add other EVM chains later. The functions/methods are already designed to work with all EVM chains.

Learnt from: garry-sharp
PR: #117
File: plugin/fees/policy.go:46-47
Timestamp: 2025-07-04T10:47:47.927Z
Learning: For the fee plugin in plugin/fees/policy.go, the resource validation and recipe specification are intentionally configured to accept only USDC transfers ("ethereum.usdc.transfer"), not general ERC20 transfers ("ethereum.erc20.transfer"), as fees are only collected in USDC.

Learnt from: webpiratt
PR: #125
File: plugin/payroll/transaction.go:186-197
Timestamp: 2025-07-09T22:22:36.651Z
Learning: In plugin/payroll/transaction.go, the getTokenID function is designed to return evm.ZeroAddress.Hex() when no "token" parameter constraint is found, rather than returning an error. This is expected behavior according to the team's design intent, even though the token parameter is marked as required in the recipe specification.

Learnt from: webpiratt
PR: #96
File: plugin/payroll/transaction.go:178-183
Timestamp: 2025-06-18T18:28:19.759Z
Learning: In the payroll plugin, the Hash field in PluginKeysignRequest is intentionally set to the unsigned transaction hex (same as Message field) because computing a hash with empty V,R,S signature fields doesn't make sense, and it's documented as "not on-chain hash without signature". This is a deliberate placeholder approach.

Learnt from: webpiratt
PR: #126
File: plugin/fees/policy.go:26-26
Timestamp: 2025-07-10T20:41:44.025Z
Learning: The constant vtypes.PluginVultisigFees_feee in the vultisig/plugin project is correctly spelled with "feee" (including the extra 'e'). This is the actual constant name defined in the external dependency github.com/vultisig/verifier/types and should not be changed to "fee" singular, as this is how it's defined in the external package.

Learnt from: RaghavSood
PR: #36
File: api/server.go:21-33
Timestamp: 2025-05-07T08:23:45.882Z
Learning: The import path github.com/vultisig/verifier/plugin refers to an external dependency that provides the plugin interface, and should not be changed to github.com/vultisig/plugin/plugin as these are distinct packages with different purposes.

Learnt from: johnnyluo
PR: #108
File: Dockerfile.Payroll.server:14-19
Timestamp: 2025-07-02T04:55:36.331Z
Learning: In the vultisig/plugin repository, the team maintains both the main repository and the go-wrappers dependency repository, so they are comfortable downloading from the master branch rather than pinning to specific commits.

Learnt from: garry-sharp
PR: #117
File: plugin/fees/constraints.go:3-3
Timestamp: 2025-07-04T10:50:42.832Z
Learning: For the vultisig/plugin project, use "fee" (singular) throughout the codebase wherever possible, not "fees" (plural). This applies to all naming conventions including plugin types, variable names, function names, comments, and documentation.

Learnt from: webpiratt
PR: #96
File: plugin/payroll/transaction.go:510-514
Timestamp: 2025-06-18T18:20:59.510Z
Learning: The erc20ABI constant is defined in plugin/payroll/constants.go within the payroll package, making it accessible to other files in the same package like transaction.go.

storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql (2)

Learnt from: webpiratt
PR: #89
File: storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql:13-13
Timestamp: 2025-06-11T18:42:54.241Z
Learning: In the tx_indexer table (storage/postgres/migrations/plugin/*_tx_indexer.sql), the policy_id column is intentionally not defined with a foreign-key constraint to plugin_policies(id).

Learnt from: RaghavSood
PR: #75
File: storage/postgres/db_plugin.go:25-40
Timestamp: 2025-05-30T02:44:31.711Z
Learning: The embed.FS directive //go:embed migrations/plugin/*.sql in storage/postgres/db_plugin.go correctly embeds plugin migration files that exist in the storage/postgres/migrations/plugin/ directory. The path "migrations/plugin" passed to goose.Up() references the embedded filesystem structure, not the physical file system path.

storage/postgres/schema/schema.sql (1)

Learnt from: webpiratt
PR: #89
File: storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql:13-13
Timestamp: 2025-06-11T18:42:54.241Z
Learning: In the tx_indexer table (storage/postgres/migrations/plugin/*_tx_indexer.sql), the policy_id column is intentionally not defined with a foreign-key constraint to plugin_policies(id).

🔇 Additional comments (5)
fee.worker.example.json (1)

13-14: Configuration property addition looks good

The new do_setup_msg property is properly added with correct JSON syntax.

go.mod (1)

23-23: Verified compatibility of updated verifier dependency – no breaking changes detected

The commit history between de5b88138d5c and 058f80801ad2 only includes UI, build, and configuration tweaks (marketplace v2, styling, vite config fixes, etc.) with no alterations to the transaction signing API or related interfaces. You can safely merge this update.

storage/postgres/policy.go (1)

160-178: Soft delete implementation validated

The soft delete for plugin_policies is correctly implemented and verified:

  • The deleted boolean column (default false) exists in both schema and migration (20250721200403_delete_policy_constraints.sql).
  • Triggers are in place:
    • set_policy_inactive_on_delete sets active = false when deleted = true.
    • prevent_update_if_policy_deleted blocks any updates once deleted is true.
  • Manual removal of time_triggers is required (there’s no ON DELETE CASCADE on that table).
  • Related fee_run records reference plugin_policies(id) ON DELETE CASCADE, but since we’re only marking rows as deleted, those entries remain—preserving audit/history data.

Please confirm this retention strategy aligns with your data-retention requirements. All checks pass.

plugin/fees/transaction.go (2)

129-135: Good security improvement: signing transaction hash instead of raw bytes

The change to decode the transaction and compute its proper hash before signing is a security best practice. This prevents transaction malleability attacks.


150-161: Double hashing pattern confirmed and intentional
The SHA256 double-hash approach (Message = base64(txHash), Hash = base64(sha256(txHash)), HashFunction = SHA256) is already used in both plugin/fees/transaction.go and plugin/payroll/transaction.go. No further changes are required.

Comment thread storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql Outdated
Comment thread storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql Outdated
Comment thread storage/postgres/schema/schema.sql
@garry-sharp
garry-sharp force-pushed the fee-stable branch 4 times, most recently from c847827 to 847c555 Compare July 24, 2025 12:10

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
storage/postgres/schema/schema.sql (2)

25-35: Remove redundant check inside trigger function

Because the trigger is already declared with WHEN (NEW.deleted = true), the internal IF NEW.deleted = true THEN … END IF; is never false.
Dropping the extra conditional trims a branch that will never be taken and makes the intent clearer.

BEGIN
-    IF NEW.deleted = true THEN
-        RAISE EXCEPTION 'Cannot insert a deleted policy';
-    END IF;
+    RAISE EXCEPTION 'Cannot insert a deleted policy';
     RETURN NEW;
END;

189-193: Trigger firing order is undefined – ensure deterministic behaviour

All three policy triggers fire BEFORE UPDATE. PostgreSQL executes them in alphabetical name order unless an explicit FOLLOWS/PRECEDES clause is used.
If future edits add more logic, an unexpected order (e.g. trg_update_plugin_policies_updated_at running before trg_set_policy_inactive_on_delete) could persist stale timestamps or raise false exceptions.

Consider adding explicit ordering directives:

CREATE TRIGGER trg_set_policy_inactive_on_delete
BEFORE UPDATE ON plugin_policies
FOR EACH ROW
WHEN (OLD.deleted = false AND NEW.deleted = true)
EXECUTE FUNCTION set_policy_inactive_on_delete()
    FOLLOWS trg_prevent_update_if_policy_deleted;
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 62ca56f and 847c555.

📒 Files selected for processing (6)
  • api/plugin.go (1 hunks)
  • fee.worker.example.json (1 hunks)
  • plugin/fees/transaction.go (5 hunks)
  • storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql (1 hunks)
  • storage/postgres/policy.go (1 hunks)
  • storage/postgres/schema/schema.sql (3 hunks)
✅ Files skipped from review due to trivial changes (1)
  • fee.worker.example.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • storage/postgres/policy.go
  • plugin/fees/transaction.go
  • api/plugin.go
  • storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: webpiratt
PR: vultisig/plugin#89
File: storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql:13-13
Timestamp: 2025-06-11T18:42:54.241Z
Learning: In the `tx_indexer` table (storage/postgres/migrations/plugin/*_tx_indexer.sql), the `policy_id` column is intentionally **not** defined with a foreign-key constraint to `plugin_policies(id)`.
storage/postgres/schema/schema.sql (1)

Learnt from: webpiratt
PR: #89
File: storage/postgres/migrations/plugin/20250603181247_tx_indexer.sql:13-13
Timestamp: 2025-06-11T18:42:54.241Z
Learning: In the tx_indexer table (storage/postgres/migrations/plugin/*_tx_indexer.sql), the policy_id column is intentionally not defined with a foreign-key constraint to plugin_policies(id).

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build

Comment thread storage/postgres/schema/schema.sql
@garry-sharp
garry-sharp force-pushed the fee-stable branch 3 times, most recently from 5469dae to c0e889d Compare July 24, 2025 12:39
Comment thread storage/postgres/migrations/plugin/20250721200403_delete_policy_constraints.sql Outdated

@RaghavSood RaghavSood 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.

Need to fix the migrations to use the system flow from verifier as mentioned in vultisig/verifier#274

@garry-sharp
garry-sharp force-pushed the fee-stable branch 4 times, most recently from 9809c90 to 6073c74 Compare July 25, 2025 13:06

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
storage/postgres/schema/schema.sql (1)

97-109: updated_at column never advances for plugin_policies

The table adds updated_at (line 107) but unlike fee_run (line 195) there is no BEFORE UPDATE trigger to call update_updated_at_column().
Consequently any change —including the soft-delete path—leaves the timestamp stale, breaking audit expectations.

+-- keep naming consistent with other tables
+CREATE TRIGGER "trg_update_plugin_policies_updated_at"
+BEFORE UPDATE ON "plugin_policies"
+FOR EACH ROW
+EXECUTE FUNCTION "public"."update_updated_at_column"();

Also applies to: 189-195

🧹 Nitpick comments (1)
storage/postgres/schema/schema.sql (1)

107-109: Consider indexing the deleted flag

Queries that need “only active policies” will now add WHERE deleted = false. A small, low-cardinality partial index helps:

CREATE INDEX idx_plugin_policies_not_deleted
  ON plugin_policies(id)  -- or any frequently-filtered column
  WHERE deleted = false;

This keeps the hot path fast without bloating the index for rarely-touched deleted rows.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9809c90 and 6073c74.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (8)
  • api/plugin.go (1 hunks)
  • fee.worker.example.json (1 hunks)
  • go.mod (1 hunks)
  • plugin/fees/config.go (4 hunks)
  • plugin/fees/fees.go (1 hunks)
  • plugin/fees/transaction.go (4 hunks)
  • storage/postgres/policy.go (1 hunks)
  • storage/postgres/schema/schema.sql (3 hunks)
✅ Files skipped from review due to trivial changes (1)
  • go.mod
🚧 Files skipped from review as they are similar to previous changes (6)
  • fee.worker.example.json
  • api/plugin.go
  • plugin/fees/fees.go
  • storage/postgres/policy.go
  • plugin/fees/transaction.go
  • plugin/fees/config.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: migration-test

Comment thread storage/postgres/schema/schema.sql
@garry-sharp
garry-sharp merged commit dca16ce into main Jul 28, 2025
3 checks passed
@garry-sharp
garry-sharp deleted the fee-stable branch July 28, 2025 17:00
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants