feat: add promo code support for distributing credits per event#535
feat: add promo code support for distributing credits per event#535elliotBraem wants to merge 10 commits intonearai:mainfrom
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9dc717d. Configure here.
There was a problem hiding this comment.
Code Review
This pull request implements a comprehensive credit event and promo code management system, enabling administrative creation of distribution campaigns and user-side credit redemptions. Significant updates include new database migrations for tracking events and claims, the integration of a credit_expires_at field across organization limit models to support expiring grants, and the introduction of several API endpoints for managing the event lifecycle. Review feedback highlights opportunities for performance optimization in promo code generation using bulk inserts, suggests refining the organization selection logic during claims for better determinism, and recommends utilizing available admin context for improved auditing.
…aims, bulk inserts, date validation, audit trail
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
There was a problem hiding this comment.
Pull request overview
This PR introduces Credit Events (admin-managed campaigns) and promo code claiming that grants expiring credits, plus updates credit balance calculations to exclude expired grants.
Changes:
- Adds a new credit events service/repository layer with admin/public/claim flows.
- Adds DB schema for credit events/codes/claims + constraints/indexes, and adds
credit_expires_attoorganization_limits_history. - Updates API routes/OpenAPI/models and adds E2E coverage for the end-to-end lifecycle and expiry filtering.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/services/src/usage/ports.rs | Extends org limit domain type to carry credit_expires_at. |
| crates/services/src/lib.rs | Exposes the new credit_events module and service exports. |
| crates/services/src/credit_events/ports.rs | Defines credit events DTOs, errors, and service/repository traits. |
| crates/services/src/credit_events/mod.rs | Implements service logic: event CRUD, code generation, and claim lifecycle. |
| crates/services/src/admin/ports.rs | Plumbs credit_expires_at through admin limits DTOs. |
| crates/database/src/repositories/organization_limits_repository_impl.rs | Updates spend limit aggregation to exclude expired grants. |
| crates/database/src/repositories/organization_limits.rs | Adds credit_expires_at persistence/queries for limits history. |
| crates/database/src/repositories/mod.rs | Registers new credit event repositories. |
| crates/database/src/repositories/credit_event_repository_impl.rs | Adapts DB repository errors/types to services-layer ports. |
| crates/database/src/repositories/credit_event.rs | Implements credit events storage and transactional claim logic. |
| crates/database/src/repositories/admin_composite.rs | Plumbs credit_expires_at into admin composite responses. |
| crates/database/src/models.rs | Adds credit_expires_at to limits history model + adds credit event models. |
| crates/database/src/migrations/sql/V0049__add_credit_expires_at_to_limits.sql | Adds credit_expires_at column to organization_limits_history. |
| crates/database/src/migrations/sql/V0050__add_credit_events.sql | Creates credit events/codes/claims tables and base indexes. |
| crates/database/src/migrations/sql/V0051__add_credit_events_constraints.sql | Adds per-user-per-event dedup constraint + performance indexes. |
| crates/api/tests/e2e_all/main.rs | Registers new credit events E2E test module. |
| crates/api/tests/e2e_all/credit_events.rs | Adds E2E tests for admin/public/claim flows and expiry filtering. |
| crates/api/src/routes/mod.rs | Registers credit events routes module. |
| crates/api/src/routes/credit_events.rs | Implements admin/public/claim HTTP endpoints and error mapping. |
| crates/api/src/routes/admin.rs | Adds request parsing + response fields for credit_expires_at in limits routes. |
| crates/api/src/openapi.rs | Documents credit events endpoints/schemas and adds admin_token security scheme. |
| crates/api/src/models.rs | Adds API models for credit events and adds creditExpiresAt to limits models. |
| crates/api/src/lib.rs | Wires credit event routes into the Axum app/router and constructs service dependencies. |
| crates/api/Cargo.toml | Adds async-trait dependency (used across the crate ecosystem). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |

Introduces promo codes (an admin route to create and deactivate, a public route to get, and a claim route validated by a session)
Promo codes are generated in batches (e.g. 100 at once) or can be individual, each unguessable (NEAR-A7K3-X9M2-P4Q8), and single-use. When a user claims one, credits expire at a configurable time, are filtered from balance calculations once expired, and stack independently per event via credit_type = 'event:{uuid}'. The claim auto-provisions an org + workspace + API key if the user has none, returning the API key in the response so they can start using credits immediately.
Key changes:
events/codes/claims tables), V0051 (per-user dedup constraint +
composite indexes)
unclaimed code, auto-provision org, add credits, atomic claim
claiming happen in a single DB transaction to prevent race conditions
from claiming multiple codes per event
credit_expires_at column on organization_limits_history
TODO: make a frontend to demonstrate (or get access to the cloud.near.ai frontend and make the page there)
Note
High Risk
Introduces new DB tables and transactional credit-claim flows that modify credit balance calculations and add admin/public endpoints; issues could impact credit accounting and allow unintended claims if auth/constraints are wrong.
Overview
Adds Credit Events as a first-class feature: admins can create/deactivate events and generate/list promo codes, the public can list/get active events, and authenticated users can claim credits via
/v1/credit-events/{id}/claim.Implements the end-to-end claim lifecycle in the services and database layers, including promo code generation, per-user-per-event dedup (unique index), and an atomic DB transaction that increments
claim_count, marks a code claimed, and records acredit_claimsrow.Extends organization limits to support expiring credit grants via
credit_expires_at(new migration + API fields) and updates balance aggregation to exclude expired credits. Updates OpenAPI (new tag, new schemas, andadmin_tokensecurity scheme) and adds comprehensive E2E coverage for the new flows.Reviewed by Cursor Bugbot for commit 9dc717d. Bugbot is set up for automated code reviews on this repo. Configure here.