Backend Spec: Subscription Entitlement & Offline Grace Verification (paywall.check_entitlement)
Estado de fase (MASTER-00): POST_MVP — documento de catálogo de producto sujeto a validación; no es alcance aprobado de Gate 0 / PoC / MVP. Gobernanza: MASTER-00.
Backend Spec: Subscription Entitlement & Offline Grace Verification (paywall.check_entitlement)
Sección titulada «Backend Spec: Subscription Entitlement & Offline Grace Verification (paywall.check_entitlement)»1. Overview & Objectives
Sección titulada «1. Overview & Objectives»This specification defines the server-side endpoint (checkEntitlement) for verifying user subscription status against RevenueCat API v1 with offline grace period fallback support. It processes GET /api/v1/subscriptions/entitlement, queries PostgreSQL subscriptions, evaluates RevenueCat webhooks or REST responses, and returns entitlement status, active tier (free vs pro_tier), and feature limit caps.
2. API Endpoint Signature & Traceability
Sección titulada «2. API Endpoint Signature & Traceability»- HTTP Method & Path:
GET /api/v1/subscriptions/entitlement - operationId:
checkEntitlement - Upstream Requirements:
US-06,IX-01,SCHEMA-01 - Primary Service Class:
EntitlementService.kt - Ktor Route Handler:
SubscriptionRoutes.kt
3. Data Models & Kotlin Data Classes
Sección titulada «3. Data Models & Kotlin Data Classes»package io.docugraph.backend.models.subscription
import kotlinx.serialization.Serializable
@Serializabledata class EntitlementStatusResponse( val entitlementId: String, // "free" | "pro_tier" val status: String, // "active" | "canceled" | "grace_period" | "expired" val isPro: Boolean, val revenuecatCustomerId: String?, val expiresAt: String?, val offlineGraceUntil: String?, val maxProjectsAllowed: Int, // -1 for unlimited, 3 for Free tier val maxTraversalDepth: Int // -1 for unlimited, 2 for Free tier)4. Sequence & Offline Grace Verification Logic
Sección titulada «4. Sequence & Offline Grace Verification Logic»Client (FE-05) Ktor Route EntitlementService RevenueCat REST API PostgreSQL DB | | | | | |-- GET /entitlement >| | | | | |-- checkEntitlement ---->|--------------------------------------------->| SELECT subscriptions | | |<- sub record --------------------------------| | | | | | | | |-- online check? ------->| | | | | GET /v1/subscribers | | | | |<- 200 OK customer info -| | | | | | | | | |-- IF offline / network error: | | | | eval offline_grace_until | | | | | | | | |-- UPDATE cache in DB ----------------------->| UPDATE subscriptions |<- 200 EntitlementResp-|<- EntitlementStatusResp -| | |4.1 Offline Grace Evaluation Rule
Sección titulada «4.1 Offline Grace Evaluation Rule»- If RevenueCat API is unreachable (network timeout / offline status):
- Check
offline_grace_untiltimestamp stored in DB. - If
CURRENT_TIMESTAMP <= offline_grace_until(up to 7 days from last successful verification), grant cachedpro_tierstatus. - If grace period expired, demote session status to
free.
- Check
5. Database Interaction & SQL Queries
Sección titulada «5. Database Interaction & SQL Queries»SELECT id, user_id, entitlement_id, status, revenuecat_customer_id, current_period_end, offline_grace_untilFROM subscriptionsWHERE user_id = :userIdLIMIT 1;UPDATE subscriptions SET entitlement_id = :entitlementId, status = :status, current_period_end = :expiresAt, offline_grace_until = CURRENT_TIMESTAMP + INTERVAL '7 days', updated_at = CURRENT_TIMESTAMPWHERE user_id = :userId;6. Error Handling & HTTP Status Codes
Sección titulada «6. Error Handling & HTTP Status Codes»| Error Condition | HTTP Code | Internal Code | Response Message |
|---|---|---|---|
| Missing Bearer token | 401 Unauthorized | UNAUTHORIZED |
“Authentication required to check entitlement.” |
| Subscription record not found | 404 Not Found | SUBSCRIPTION_NOT_FOUND |
“No subscription record found for user.” |
| External billing provider API error | 502 Bad Gateway | REVENUECAT_UNAVAILABLE |
“RevenueCat server unavailable, using cached status.” |
7. Verification & Test Plan
Sección titulada «7. Verification & Test Plan»- Unit Test: Test offline grace logic for active, expired grace, and valid online states.
- Integration Test: Mock RevenueCat HTTP response and verify database entitlement cache update.