postas_platform_api es la fuente de verdad para planes, features, limites,
suscripciones, pagos y consumo mensual. En esta primera etapa no hay integracion
con MercadoPago, frontend ni cliente dentro de postas_api.
Configurar DATABASE_URL. Por defecto se usa SQLite local:
sqlite:///./postas_platform.dbAplicar migraciones:
alembic upgrade headEl catalogo de planes y features se carga de forma idempotente:
python scripts/seed_billing.pyEl seed actualiza planes, features y configuraciones PlanFeature existentes
sin duplicar registros.
El catalogo incluye un plan privado test. Ese plan habilita todas las
features y configura limite 1 para las features de tipo monthly_usage y
resource_limit, para probar permisos y limites rapidamente.
Para generar datos locales de prueba, uno por cada plan activo:
python scripts/seed_plan_tenants.pyEl script primero sincroniza el catalogo de billing. Luego reutiliza la primera
suscripcion activa existente por plan y crea suscripciones active para los
planes faltantes. Los nuevos tenants usan UUIDs consecutivos al mayor tenant ya
presente en billing. Tambien crea un pago manual aprobado cuando la
suscripcion no tiene pago asociado.
En esta API no hay una tabla tenant; para billing, un tenant de prueba queda
representado por su tenant_id en billing_tenant_subscriptions y
billing_payments.
Los endpoints internos viven bajo /internal/v1.
Headers:
X-Postas-SourceX-Postas-Service-Token
Variables:
POSTAS_SERVICE_TOKENALLOWED_REQUEST_SOURCES, separado por coma.
Si POSTAS_SERVICE_TOKEN esta configurado, el token debe coincidir. Si
ALLOWED_REQUEST_SOURCES esta configurado, X-Postas-Source debe estar en la
lista. Los fallos devuelven 403.
GET /internal/v1/tenants/{tenant_id}/statusPOST /internal/v1/entitlements/checkPOST /internal/v1/usage/consumePOST /internal/v1/usage/check-and-consume
Si un tenant no tiene suscripcion, el status endpoint devuelve 404 con
detail: "subscription_not_found". Los checks devuelven allowed: false y
reason: "subscription_not_found".
curl http://localhost:8001/internal/v1/tenants/00000000-0000-0000-0000-000000000001/status \
-H "X-Postas-Source: postas_api" \
-H "X-Postas-Service-Token: local-service-token"curl -X POST http://localhost:8001/internal/v1/entitlements/check \
-H "Content-Type: application/json" \
-H "X-Postas-Source: postas_api" \
-H "X-Postas-Service-Token: local-service-token" \
-d '{
"tenant_id": "00000000-0000-0000-0000-000000000001",
"feature_key": "document_extraction",
"amount": 1,
"resource_count": null,
"context": {"source": "document_extraction"}
}'curl -X POST http://localhost:8001/internal/v1/usage/consume \
-H "Content-Type: application/json" \
-H "X-Postas-Source: postas_ai_api" \
-H "X-Postas-Service-Token: local-service-token" \
-d '{
"tenant_id": "00000000-0000-0000-0000-000000000001",
"feature_key": "document_extraction",
"amount": 1,
"external_id": "document_extraction_uuid",
"idempotency_key": "document-extraction:document_extraction_uuid",
"metadata": {"provider": "google_genai", "model": "gemini-2.5-flash-lite"}
}'curl -X POST http://localhost:8001/internal/v1/usage/check-and-consume \
-H "Content-Type: application/json" \
-H "X-Postas-Source: postas_api" \
-H "X-Postas-Service-Token: local-service-token" \
-d '{
"tenant_id": "00000000-0000-0000-0000-000000000001",
"feature_key": "document_extraction",
"amount": 1,
"external_id": "document_extraction_uuid",
"idempotency_key": "document-extraction:document_extraction_uuid"
}'- Agregar endpoints admin cuando exista autenticacion/roles admin.
- Crear cliente interno en
postas_apipara consultar permisos y registrar consumos.