Skip to content

Persist investor lock records to the database instead of the in-memory _lockStore Map #505

Description

@mikewheeleer

Persist investor lock records to durable storage

Description

The investor commitment service in src/services/investorCommitment.js persists investor_commitments rows to the database via Knex, but it keeps the separate lock records (claimNotBefore, investorEffectiveYieldBps per funder/invoice) in a process-local Map named _lockStore, populated through setInvestorLock/getInvestorLock/getAllInvestorLocks. Those locks back the investor-facing GET /api/investor/locks endpoints in src/routes/investor.js, so every funder lock is lost on restart, invisible across replicas, and every record is flagged stale: true. This issue moves lock records into durable, tenant-scoped storage.

Requirements and context

  • Repository scope: Liquifact/Liquifact-backend only.
  • Replace the _lockStore Map in src/services/investorCommitment.js with a persisted table via src/db/knex.js, keyed by invoiceId + funderAddress and scoped to tenant.
  • Keep the public surface (setInvestorLock, getInvestorLock, getAllInvestorLocks, getInvestorLocksByAddress, clearInvestorLocks, seedInvestorLocks) stable so src/routes/investor.js needs no shape changes, and preserve the offset-pagination meta contract.
  • Resolve the stale flag from real read freshness rather than hardcoding true.
  • Add a migration mirroring the style of migrations/20260601000001_create_investor_commitments.js.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b feature/investor-locks-01-db-persistence
  • Implement changes
    • Write code in: src/services/investorCommitment.js and a new migration.
    • Write comprehensive tests in: create tests/investorLocks.persistence.test.js.
    • Add documentation: update the investor section in README.md and the @swagger block in src/routes/investor.js.
    • Add JSDoc on the persistence helpers.
    • Validate security: funder/tenant scoping on every read; no cross-funder lock leakage.
  • Test and commit

Test and commit

  • Run npm test and npm run lint.
  • Cover edge cases: lock survives restart, pagination bounds, funder-scoped vs all-locks, invoiceId filter, empty store.
  • Include the full npm test output and a short security-notes section in the PR description.

Example commit message

feat(investor-locks): persist lock records to the database with tenant scoping

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • 💬 Join the Liquifact community on Discord for questions, reviews, and faster merges: https://discord.gg/JrGPH4V3
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.

Metadata

Metadata

Assignees

No one assigned

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions