Skip to content

Add a persistence adapter so usage, services, and API keys survive process restarts #31

Description

@mikewheeleer

Implement a persistence adapter so usage, services, and API keys survive process restarts

Description

Every data store in src/index.ts is an in-memory Map/Set (usageStore, servicesStore, servicesMetadata, servicesDisabled, apiKeyStore, webhookStore, eventLog) and the comments openly state that "a process restart resets the counters." For a metering and billing backend this is a correctness hazard: a restart silently drops unsettled usage that real money is owed against. This issue introduces a storage abstraction with a pluggable backend so durability becomes possible without rewriting every handler.

Requirements and context

  • Repository scope: Agentpay-Org/Agentpay-backend only.
  • Define a Store interface (get/set/delete/entries/scan-by-prefix) in a new src/store/index.ts that the existing handlers consume instead of touching Map directly.
  • Ship an InMemoryStore implementation (preserving current behaviour) and a file-backed or SQLite-backed implementation selected via an env var (e.g. STORAGE_DRIVER=memory|sqlite).
  • Migrate usageStore, servicesStore, servicesDisabled, servicesMetadata, and apiKeyStore to the new interface without changing any HTTP response shape.
  • Keep the composite key convention ${agent}::${serviceId} (usageKey in src/index.ts) intact so existing exports and rollups still work.
  • Add graceful-shutdown flush so the SIGTERM/SIGINT handler persists state before exit.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b feature/db-01-persistence-adapter
  • Implement changes
    • Write code in: new src/store/index.ts and refactor the store accesses in src/index.ts.
    • Write comprehensive tests in: new src/store/store.test.ts — round-trip persistence, restart simulation, prefix scans.
    • Add documentation: update README.md with a "Persistence" section documenting STORAGE_DRIVER and the on-disk format.
    • Add TSDoc comments on every method of the Store interface.
    • Validate security assumptions: no path traversal on the file path, safe serialization, no secret keys written in plaintext logs.
  • Test and commit

Test and commit

  • Run npm run build, npm test, and npm run lint.
  • Cover edge cases: empty store, restart with existing data, concurrent writes, corrupt/missing data file.
  • Include the full npm test output and a short note on the durability guarantees in the PR description.

Example commit message

feat: add pluggable persistence adapter with in-memory and sqlite drivers

Guidelines

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

Community & contribution rewards

  • 💬 Join the AgentPay community on Discord for questions, reviews, and faster merges: https://discord.gg/eXvRKkgcv
  • ⭐ 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
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions