Ir al contenido
DocuGraph

DocuGraph

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)»

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.

  • 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
package io.docugraph.backend.models.subscription
import kotlinx.serialization.Serializable
@Serializable
data 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 -| | |
  • If RevenueCat API is unreachable (network timeout / offline status):
    • Check offline_grace_until timestamp stored in DB.
    • If CURRENT_TIMESTAMP <= offline_grace_until (up to 7 days from last successful verification), grant cached pro_tier status.
    • If grace period expired, demote session status to free.
SELECT
id,
user_id,
entitlement_id,
status,
revenuecat_customer_id,
current_period_end,
offline_grace_until
FROM subscriptions
WHERE user_id = :userId
LIMIT 1;
UPDATE subscriptions SET
entitlement_id = :entitlementId,
status = :status,
current_period_end = :expiresAt,
offline_grace_until = CURRENT_TIMESTAMP + INTERVAL '7 days',
updated_at = CURRENT_TIMESTAMP
WHERE user_id = :userId;
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.”
  • 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.