Skip to content

feat(metering): service + endpoint usage courant (THI-126 — 2/2) - #12

Merged
Tbeaumont79 merged 1 commit into
mainfrom
feat/metering-service
Jun 9, 2026
Merged

Tbeaumont79 merged 1 commit into
mainfrom
feat/metering-service

Conversation

@Tbeaumont79

@Tbeaumont79 Tbeaumont79 commented Jun 9, 2026 •

Copy link
Copy Markdown
Owner

THI-126 — Metering 2/2 · Service d'enregistrement + endpoint usage

Branche le metering sur la base posée en 1/2 (#11). À merger après #11.

Contenu

  • server/utils/metering.ts :
    • recordUsageEvent — crée un usage_event et incrémente le usage_counter de la période, de façon atomique ($transaction). Appelé par les chemins génération (THI-124) et export PDF (THI-125).
    • readUsageSummary — usage courant agrégé + état des quotas.
    • isUsageAllowed — garde de quota à appeler avant une action.
    • Logique de mapping/agrégat pure + accès base derrière une interface minimale MeteringClient (à la manière de DbPinger) → testable sans base.
  • server/utils/session.ts : requireUserId(event) découplé du lot Auth — lit event.context.userId (renseigné par le middleware auth [THI-131]), 401 sinon. Pas d'import de l'instance auth → PR indépendante de l'ordre de merge.
  • GET /api/usage/current : usage de la période en cours + quotas, pour l'utilisateur authentifié. Aucune donnée de contenu.

Tests

8 specs (apps/app/test/metering.spec.ts) : builders purs, création d'event, agrégation du compteur sur plusieurs actions, refus quand quota atteint.

Vérif locale

pnpm --filter @cvo/app test ✅ (23/23) · nuxt typecheck ✅ (le client Prisma satisfait MeteringClient) · eslint . ✅

Intégration restante (hors PR)

Le branchement recordUsageEvent / isUsageAllowed dans les routes génération (THI-124) et export PDF (THI-125) se fera côté de ces routes — appel d'une ligne. La 401 du endpoint suppose que le middleware auth (THI-131) renseigne event.context.userId.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a new endpoint for authenticated users to retrieve their current usage summary and quota status for the active billing period.
    • Implemented usage tracking and quota enforcement system to monitor consumption against plan limits and prevent overages.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Free

Run ID: d7d42c70-4ecd-421b-a46e-98618ce037da

📥 Commits

Reviewing files that changed from the base of the PR and between f68f56b and 0fd8dfa.

📒 Files selected for processing (4)
  • apps/app/server/api/usage/current.get.ts
  • apps/app/server/utils/metering.ts
  • apps/app/server/utils/session.ts
  • apps/app/test/metering.spec.ts

📝 Walkthrough

Walkthrough

This PR introduces a complete usage metering system for tracking and enforcing per-period quotas. It adds event recording with transactional counter updates, quota enforcement checks, session authentication utilities, a public API endpoint, and comprehensive test coverage with an injectable fake client for testability.

Changes

Usage Metering System

Layer / File(s) Summary
Metering data contracts and mappings
apps/app/server/utils/metering.ts (ranges 1–137)
Defines event-type to Prisma enum mappings and counter column selectors; introduces UsageCounterRow and RecordUsageInput shapes, plus pure builder utilities (eventCreateData, counterCreateData, counterUpdateData, snapshotFromRow) that generate creation and update payloads. Establishes injectable MeteringClient and transaction contracts for unit-test isolation.
Metering service operations
apps/app/server/utils/metering.ts (ranges 138–196)
Implements recordUsageEvent (transactional event + counter upsert), readSnapshot (period lookup and aggregation), readUsageSummary (snapshot + quota state), and isUsageAllowed (quota enforcement check). All functions work through the MeteringClient interface and current period computation from now.
Session authentication utility
apps/app/server/utils/session.ts
Adds requireUserId function to extract authenticated user ID from event context, with h3 module augmentation to type context.userId as optional string. Throws 401 if user is unauthenticated.
Usage current API endpoint
apps/app/server/api/usage/current.get.ts
Defines GET /api/usage/current handler that requires authentication via requireUserId, then calls readUsageSummary with Prisma client, user ID, free-tier quotas, and current date to return typed UsageSummary.
Metering service tests
apps/app/test/metering.spec.ts
Comprehensive Vitest suite with makeFakeClient in-memory stub, builder validation tests, recordUsageEvent behavior across multiple calls, readUsageSummary quota status verification, and isUsageAllowed enforcement tests confirming quotas block usage while others permit it.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hoppy metering hops in place,
Quotas tracked at current pace,
Events counted, periods neat,
Auth and snapshots, all complete!
Usage summaries served with grace. 🥕


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login.

Comment @coderabbitai help to get the list of available commands and usage tips.

@Tbeaumont79
Tbeaumont79 changed the base branch from feat/metering-contract to main June 9, 2026 17:08
…I-126 — 2/2)

Branche le metering sur la base posée en 1/2.

- server/utils/metering.ts: recordUsageEvent (event + upsert compteur atomique),
  readUsageSummary, isUsageAllowed (garde de quota). Client injectable minimal
  (MeteringClient) à la manière de DbPinger -> testable sans base.
- server/utils/session.ts: requireUserId(event) découplé du lot Auth (lit
  event.context.userId renseigné par le middleware auth THI-131) -> 401 sinon.
- GET /api/usage/current: usage de la période en cours + état des quotas.
- Tests: 8 specs (builders purs, création event, agrégation compteur, gate quota).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@Tbeaumont79
Tbeaumont79 force-pushed the feat/metering-service branch from 0a24692 to 0fd8dfa Compare June 9, 2026 17:15
@Tbeaumont79
Tbeaumont79 merged commit c1652c4 into main Jun 9, 2026
1 check passed
@Tbeaumont79
Tbeaumont79 deleted the feat/metering-service branch June 9, 2026 17:16
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