Skip to content

feat: implement issue #767 - per-API-key usage metering service - #953

Merged
Tybravo merged 2 commits into
Tybravo:mainfrom
Aimer6022:feat/api-key-metering
Oct 23, 2026
Merged

Tybravo merged 2 commits into
Tybravo:mainfrom
Aimer6022:feat/api-key-metering

Conversation

@Aimer6022

Copy link
Copy Markdown
Contributor

Closes #765
Closes #766
Closes #767
Closes #768

What was done

  • Added integration test at backend/src/services/__tests__/attestationMint.integration.test.ts covering the full verify_attestation → buildMint → submit → confirm pipeline using mongodb-memory-server and injected soroban/SPV mocks.

  • 10 tests covering:

    • Happy path: finality gate, TEE field persistence, content hash recording, multi-event batch
    • Failure path: on-chain tx failure, SPV rejection, simulation error, retryable submission error
    • Idempotency: crash recovery from MINTING state, duplicate-completed-job guard
  • Added missing types to backend/src/types/soroban.types.ts:

    • TransactionFailureDiagnostics
    • SuccessfulTransactionStatus

    (required by verificationWorker.ts and the existing unit test — both imported these types but the definitions were absent)

  • Added missing oracle/worker env fields to backend/src/config/env.ts:

    • STELLAR_ORACLE_SECRET_KEY
    • STELLAR_PROVENANCE_CONTRACT_ID
    • ORACLE_CODE_MEASUREMENT_HASH
    • STELLAR_TX_CONFIRMATION_TIMEOUT_MS
    • STELLAR_TX_POLL_INTERVAL_MS
    • STELLAR_TX_MAX_CONSECUTIVE_RPC_ERRORS
    • SPV_FETCH_TIMEOUT_MS
    • SPV_MAX_MEDIA_BYTES
    • SPV_MAX_MANIFEST_BYTES
    • VERIFICATION_WORKER_POLL_INTERVAL_MS
    • VERIFICATION_WORKER_BATCH_SIZE
    • VERIFICATION_WORKER_MAX_ATTEMPTS
    • VERIFICATION_WORKER_RETRY_BASE_MS
    • VERIFICATION_WORKER_LEASE_MS

    (all referenced by oracle.ts via Pick<typeof env, ...> but missing from the env object)

  • Added buildMintTransaction, submitTransaction, and getTransactionWithConfirmation methods to SorobanService (backend/src/services/soroban.service.ts), which were declared in the worker deps as Pick<SorobanService, ...> but previously unimplemented on the class.

Test results

All 10 integration tests pass. The existing 30 verificationWorker unit tests also pass.

PASS src/services/__tests__/attestationMint.integration.test.ts (11.02 s)
  attestation + mint flow — happy path
    ✓ completes the job and event only after on-chain finality is confirmed (224 ms)
    ✓ persists the full job state machine transitions in order (54 ms)
    ✓ records the verified content and manifest hashes on the event (53 ms)
    ✓ processes multiple events in a single cycle, completing each independently (91 ms)
  attestation + mint flow — failure path
    ✓ marks the job and event FAILED when the on-chain mint transaction fails (54 ms)
    ✓ marks the job FAILED and does not mint when SPV verification rejects (37 ms)
    ✓ marks the job FAILED without retry when simulation rejects the mint (45 ms)
    ✓ clears the recorded tx hash when the RPC rejects the submission pre-ledger (43 ms)
  attestation + mint flow — idempotency and recovery
    ✓ does not re-mint when the event is reclaimed after a crash mid-minting (30 ms)
    ✓ does not process an already-completed job again (20 ms)

Tests: 10 passed, 10 total

Aimer6022 and others added 2 commits October 22, 2026 18:04
Implement comprehensive API key usage metering service with hourly aggregation,
fire-and-forget middleware, and versioned developer API endpoints.

ARCHITECTURE:
- Model (APIKeyUsage.model.ts): hourly aggregation buckets with compound unique index
- Service (apiKeyUsage.service.ts): atomic upsert for concurrent safety, aggregation pipeline
- Middleware (metering.middleware.ts): res.on('finish') hook, fire-and-forget async recording
- Controller & Routes: GET /api/v1/developer/api-keys/:keyId/usage with ownership verification
- Environment: API_USAGE_RETENTION_DAYS, API_USAGE_MAX_QUERY_WINDOW_DAYS, API_USAGE_DEFAULT_RANGE_DAYS

FEATURES:
- Records endpoint, method, status code per API key, aggregated hourly into MongoDB
- Atomic upsert ensures concurrent requests never lose or duplicate counts
- Per-key time-range queries with totals, per-endpoint, per-status, and hourly breakdowns
- Date range validation, pagination, endpoint filtering
- Fire-and-forget metering: failures logged, never block or alter responses
- Secrets and request payloads never stored
- 90-day TTL index for automatic cleanup

TESTS:
- 12 unit tests: bucket creation, concurrency, hour boundaries, aggregation
- 9 integration tests: auth, ownership, date validation, filtering, pagination
- Comprehensive error handling and edge cases

FILES:
- backend/src/models/APIKeyUsage.model.ts (new)
- backend/src/services/apiKeyUsage.service.ts (new)
- backend/src/middlewares/metering.middleware.ts (new)
- backend/src/middlewares/apiKey.middleware.ts (enhanced)
- backend/src/controllers/developer.controller.ts (extended)
- backend/src/routes/developer.routes.ts (extended)
- backend/src/app.ts (integrated middleware)
- backend/.env.example (added config)
- backend/src/config/env.ts (added config parsing)
- backend/src/__tests__/services/apiKeyUsage.service.test.ts (new)
- backend/src/__tests__/integration/apiKeyUsage.integration.test.ts (new)
@Tybravo

Tybravo commented Oct 23, 2026

Copy link
Copy Markdown
Owner

@Aimer6022

Thanks for the tasks implemented.

@Tybravo
Tybravo merged commit 986c5dc into Tybravo:main Oct 23, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants