Skip to content

initial commit of cagematch - #311

Draft
jasonmorais wants to merge 1 commit into
mainfrom
jason/rate-limit-cagematch
Draft

initial commit of cagematch#311
jasonmorais wants to merge 1 commit into
mainfrom
jason/rate-limit-cagematch

Conversation

@jasonmorais

@jasonmorais jasonmorais commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Introduce backend-neutral feature rate limiting with MongoDB and Redis contenders and integrate it into the API and local dev tooling.

New Features:

  • Add @cagematch/rate-limiting core package defining feature-level rate limiting contracts, policy resolution, and a ServiceRateLimiting facade.
  • Add MongoDB-based rate limiting contender with atomic counters and TTL cleanup plus Redis-based contender using a Lua script for fixed-window limits.
  • Introduce Redis memory-server seedwork and an application Redis mock server for local and test environments.
  • Wire rate limiting into the OCOM API context and community creation workflow, deriving principals from JWTs and enforcing community.create limits by account class.
  • Add rate limiting service configuration in apps/api with switchable Mongo vs Redis backends driven by env and explicit policies.

Enhancements:

  • Extend application services and context-spec to expose a rateLimitingService and rateLimitPrincipal for downstream consumers.
  • Update community application services to accept optional rate limiting dependencies and apply them during community creation.
  • Enhance local-dev tooling to support deterministic Redis worktree ports and convert REDIS_URL alongside Mongo and Azurite settings.
  • Adjust API bootstrap to register a shared Mongoose service and a new rate limiting infrastructure service, selecting Redis or Mongo implementations at startup.

Documentation:

  • Document the new cagematch rate limiting packages, Mongo and Redis contenders, Redis memory-server seedwork, and Redis mock server usage.
  • Update cellix and ocom local-dev documentation to describe Redis port handling and REDIS_URL worktree conversion.

Tests:

  • Add unit and integration tests for rate limiting core, Mongo and Redis contenders, and Redis memory-server seedwork.
  • Add tests ensuring community.create short-circuits when rate limits deny requests and that API bootstrap registers the Redis contender when enabled.
  • Extend local-dev tests to cover Redis port derivation and REDIS_URL worktree conversions.

@sourcery-ai

sourcery-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Introduces the cagematch rate-limiting system and wires it into the OCOM API: a backend-neutral rate-limiting facade with Mongo and Redis contenders, Redis memory-server dev tooling, application-level policies, and integration into the Community create flow plus worktree-aware Redis dev config.

Sequence diagram for community.create rate limiting flow

sequenceDiagram
    actor EndUser
    participant CommunityCreate as create
    participant ServiceRateLimiting
    participant Implementation as RateLimitingServiceImplementation
    participant Store as RateLimitStore
    participant ReadRepo as EndUserReadRepo

    EndUser->>CommunityCreate: CommunityCreateCommand
    CommunityCreate->>ServiceRateLimiting: consume({ feature: 'community.create', subject })
    ServiceRateLimiting->>Implementation: consume(request)
    Implementation->>Store: consume(storeRequest)
    Store-->>Implementation: RateLimitStoreDecision
    Implementation-->>ServiceRateLimiting: RateLimitDecision
    alt allowed
        ServiceRateLimiting-->>CommunityCreate: RateLimitDecision.allowed = true
        CommunityCreate->>ReadRepo: getByExternalId(endUserExternalId)
        ReadRepo-->>CommunityCreate: CommunityEntityReference
        CommunityCreate-->>EndUser: CommunityEntityReference
    else denied
        ServiceRateLimiting-->>CommunityCreate: RateLimitDecision.allowed = false
        CommunityCreate-->>EndUser: throw Error('Rate limit exceeded for feature community.create')
    end
Loading

File-Level Changes

Change Details Files
Add backend-neutral rate-limiting contracts and facade with Mongo and Redis implementations and tests.
  • Define RateLimit* types, policy resolution, key construction, and ServiceRateLimiting facade in @cagematch/rate-limiting.
  • Implement MongoRateLimitStore and ServiceMongoRateLimiting using atomic findOneAndUpdate with TTL index and duplicate-key retry.
  • Implement RedisRateLimitStore and ServiceRedisRateLimiting using a Lua EVAL fixed-window script and client lifecycle.
  • Add unit and live-integration tests for both contenders against real MongoDB/Redis.
  • Document each cagematch package with manifests, READMEs, tsconfigs, and Vitest configs.
packages/cagematch/rate-limiting/src/rate-limiting.ts
packages/cagematch/rate-limiting/src/index.ts
packages/cagematch/rate-limiting/index.test.ts
packages/cagematch/rate-limiting/README.md
packages/cagematch/rate-limiting/manifest.md
packages/cagematch/rate-limiting/package.json
packages/cagematch/rate-limiting/tsconfig.json
packages/cagematch/rate-limiting/vitest.config.ts
packages/cagematch/rate-limiting/.gitignore
packages/cagematch/rate-limiting/tsconfig.vitest.json
packages/cagematch/rate-limiting/turbo.json
packages/cagematch/rate-limiting-mongo/src/mongo-rate-limiting.ts
packages/cagematch/rate-limiting-mongo/src/index.ts
packages/cagematch/rate-limiting-mongo/index.test.ts
packages/cagematch/rate-limiting-mongo/src/mongo-rate-limiting.integration.test.ts
packages/cagematch/rate-limiting-mongo/README.md
packages/cagematch/rate-limiting-mongo/manifest.md
packages/cagematch/rate-limiting-mongo/package.json
packages/cagematch/rate-limiting-mongo/tsconfig.json
packages/cagematch/rate-limiting-mongo/vitest.config.ts
packages/cagematch/rate-limiting-mongo/.gitignore
packages/cagematch/rate-limiting-mongo/tsconfig.vitest.json
packages/cagematch/rate-limiting-mongo/turbo.json
packages/cagematch/rate-limiting-redis/src/redis-rate-limiting.ts
packages/cagematch/rate-limiting-redis/src/index.ts
packages/cagematch/rate-limiting-redis/index.test.ts
packages/cagematch/rate-limiting-redis/src/redis-rate-limiting.integration.test.ts
packages/cagematch/rate-limiting-redis/README.md
packages/cagematch/rate-limiting-redis/manifest.md
packages/cagematch/rate-limiting-redis/package.json
packages/cagematch/rate-limiting-redis/tsconfig.json
packages/cagematch/rate-limiting-redis/vitest.config.ts
packages/cagematch/rate-limiting-redis/.gitignore
packages/cagematch/rate-limiting-redis/tsconfig.vitest.json
packages/cagematch/rate-limiting-redis/turbo.json
Introduce a reusable Redis memory-server seedwork and an app-specific Redis mock server for local dev and tests.
  • Add startRedisMemoryServer seedwork that boots a redis-memory-server instance and exposes connection info plus idempotent shutdown.
  • Add application wrapper package that resolves env, configures host/port/version, and exposes startAppRedisMemoryServer/start script.
  • Wire NodeDevRunner-based dev entrypoint and vitest config for the Redis mock server.
  • Add tests verifying real Redis interaction and config resolution/delegation.
packages/cagematch/server-redis-memory-mock-seedwork/src/index.ts
packages/cagematch/server-redis-memory-mock-seedwork/src/index.test.ts
packages/cagematch/server-redis-memory-mock-seedwork/README.md
packages/cagematch/server-redis-memory-mock-seedwork/manifest.md
packages/cagematch/server-redis-memory-mock-seedwork/package.json
packages/cagematch/server-redis-memory-mock-seedwork/tsconfig.json
packages/cagematch/server-redis-memory-mock-seedwork/vitest.config.ts
packages/cagematch/server-redis-memory-mock-seedwork/.gitignore
packages/cagematch/server-redis-memory-mock-seedwork/tsconfig.vitest.json
packages/cagematch/server-redis-memory-mock-seedwork/turbo.json
packages/cagematch/server-redis-memory-mock/src/index.ts
packages/cagematch/server-redis-memory-mock/src/index.test.ts
packages/cagematch/server-redis-memory-mock/src/start.ts
packages/cagematch/server-redis-memory-mock/src/setup-environment.ts
packages/cagematch/server-redis-memory-mock/start-dev.ts
packages/cagematch/server-redis-memory-mock/README.md
packages/cagematch/server-redis-memory-mock/manifest.md
packages/cagematch/server-redis-memory-mock/package.json
packages/cagematch/server-redis-memory-mock/tsconfig.json
packages/cagematch/server-redis-memory-mock/vitest.config.ts
packages/cagematch/server-redis-memory-mock/.env
packages/cagematch/server-redis-memory-mock/.gitignore
packages/cagematch/server-redis-memory-mock/tsconfig.vitest.json
packages/cagematch/server-redis-memory-mock/turbo.json
Wire rate limiting into the OCOM API bootstrap and application-services, including per-request principal extraction and Community.create enforcement.
  • Extend ApiContextSpec and ApplicationServices to carry a RateLimitingService and a rateLimitPrincipal.
  • Derive RateLimitSubject from JWTs for community and staff users, including tenantId and staffRole when applicable; default anonymous subject otherwise.
  • Register a single ServiceRateLimiting facade in apps/api bootstrap using either Mongo or Redis contenders based on new rate-limiting config (CAGEMATCH_USE_REDIS, REDIS_URL) and make it available in the context.
  • Thread rateLimitingService and rateLimitPrincipal into Community context and Community.create, consuming a policy before executing the command and throwing with retry metadata when denied.
  • Add focused tests validating rate-limit enforcement short-circuiting and bootstrap wiring for the Redis contender.
  • Update apps/api tests to reset new env vars and expect the extra infrastructure service registration call.
packages/ocom/context-spec/src/index.ts
packages/ocom/context-spec/package.json
packages/ocom/application-services/package.json
packages/ocom/application-services/src/index.ts
packages/ocom/application-services/src/contexts/community/index.ts
packages/ocom/application-services/src/contexts/community/community/index.ts
packages/ocom/application-services/src/contexts/community/community/create.ts
packages/ocom/application-services/src/contexts/community/community/create-rate-limit.test.ts
apps/api/src/index.ts
apps/api/src/service-config/rate-limiting/index.ts
apps/api/src/service-config/rate-limiting/index.test.ts
apps/api/src/index.test.ts
apps/api/package.json
Add worktree-aware Redis URL handling alongside Mongo/Azurite in local-dev and local-dev-config.
  • Extend WorktreeConversionPlan and convertSettingsForWorktree to support redisKeys, using getRedisPort for URL port replacement.
  • Introduce getRedisPort with the same offset strategy as getMongoPort; export it from cellix/local-dev root and worktree index.
  • Update local-dev tests to validate Redis port derivation and Redis URL conversion, and adjust README/manifest to mention Redis.
  • Teach buildOcomApiLocalSettings to mark REDIS_URL as redisKeys for worktree conversion and update tests/README/manifest accordingly.
  • Seed api local.settings.json fixtures with REDIS_URL and assert worktreeConversion.redisKeys in local-dev-config tests.
packages/cellix/local-dev/src/worktree/ports.ts
packages/cellix/local-dev/src/worktree/conversion.ts
packages/cellix/local-dev/src/worktree/index.ts
packages/cellix/local-dev/src/index.ts
packages/cellix/local-dev/src/index.test.ts
packages/cellix/local-dev/README.md
packages/cellix/local-dev/manifest.md
packages/ocom/local-dev-config/src/api-settings/index.ts
packages/ocom/local-dev-config/src/index.test.ts
packages/ocom/local-dev-config/README.md
packages/ocom/local-dev-config/manifest.md
Update workspace configuration and dependencies to accommodate cagematch packages and Redis tooling.
  • Add packages/cagematch/* to pnpm-workspace and enable redis/redis-memory-server in catalog and allowBuilds.
  • Wire @cagematch/rate-limiting as a dependency of ocom/context-spec and ocom/application-services, and add Redis dependency to apps/api.
  • Bump brace-expansion@2 override to 2.1.4 in pnpm-workspace.yaml.
  • Generate pnpm-lock.yaml changes (not shown here) for new packages and dependencies.
pnpm-workspace.yaml
apps/api/package.json
packages/ocom/application-services/package.json
packages/ocom/context-spec/package.json
pnpm-lock.yaml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

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.

1 participant