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.
Persist investor lock records to durable storage
Description
The investor commitment service in
src/services/investorCommitment.jspersistsinvestor_commitmentsrows to the database via Knex, but it keeps the separate lock records (claimNotBefore,investorEffectiveYieldBpsper funder/invoice) in a process-localMapnamed_lockStore, populated throughsetInvestorLock/getInvestorLock/getAllInvestorLocks. Those locks back the investor-facingGET /api/investor/locksendpoints insrc/routes/investor.js, so every funder lock is lost on restart, invisible across replicas, and every record is flaggedstale: true. This issue moves lock records into durable, tenant-scoped storage.Requirements and context
_lockStoreMap insrc/services/investorCommitment.jswith a persisted table viasrc/db/knex.js, keyed byinvoiceId+funderAddressand scoped to tenant.setInvestorLock,getInvestorLock,getAllInvestorLocks,getInvestorLocksByAddress,clearInvestorLocks,seedInvestorLocks) stable sosrc/routes/investor.jsneeds no shape changes, and preserve the offset-paginationmetacontract.staleflag from real read freshness rather than hardcodingtrue.migrations/20260601000001_create_investor_commitments.js.Suggested execution
git checkout -b feature/investor-locks-01-db-persistencesrc/services/investorCommitment.jsand a new migration.create tests/investorLocks.persistence.test.js.README.mdand the@swaggerblock insrc/routes/investor.js.Test and commit
npm testandnpm run lint.npm testoutput and a short security-notes section in the PR description.Example commit message
feat(investor-locks): persist lock records to the database with tenant scopingGuidelines
Community & contribution rewards