tahamajs/IE / Projects /docs /Subscription&UsageSystem.md
tahamajs's picture
|
download
raw
12.1 kB
# 📘 Subscription & Usage System – Complete Documentation
## 1. Overview
The IE Research Platform offers a **freemium subscription model** with two tiers:
| Tier | Plan ID | Description |
|------|---------|-------------|
| **Free** | `FREE` | Basic features for individual researchers |
| **Professional Monthly** | `PRO_MONTHLY` | Advanced features, billed monthly |
| **Professional Yearly** | `PRO_YEARLY` | Advanced features, billed annually (2 months free) |
All plans include **monthly usage quotas** that reset on the 1st of each month.
---
## 2. Subscription Plans – Detailed Comparison
| Feature | Free | Pro Monthly | Pro Yearly |
|---------|------|-------------|------------|
| **Monthly Price** | $0 | $29.99 | $24.99 (billed $299.99/year) |
| **Articles per month** | 5 | 100 | 100 |
| **Storage space** | 100 MB | 5 GB | 5 GB |
| **API calls per month** | 100 | 5,000 | 5,000 |
| **AI generations per month** | 10 | 500 | 500 |
| **Team members** | 1 | 10 | 10 |
| **AI‑powered search** | ❌ | ✅ | ✅ |
| **Advanced analytics** | ❌ | ✅ | ✅ |
| **API access** | ❌ | ✅ | ✅ |
| **Priority support** | ❌ | ✅ | ✅ |
| **Collaboration tools** | ❌ | ✅ | ✅ |
| **Export citations (BibTeX, RIS, etc.)** | ❌ | ✅ | ✅ |
| **Free trial** | – | 14 days | 14 days |
| **Auto‑renewal** | – | Optional | Optional |
---
## 3. Usage Tracking & Limits
Each user’s monthly usage is tracked per calendar month (UTC). Counters reset automatically on the 1st day of each month.
### 3.1 Tracked Metrics
| Metric | Description | Free Limit | Pro Limit |
|--------|-------------|------------|-----------|
| `articles_created` | Number of published articles | 5 | 100 |
| `storage_used_mb` | Total uploaded files size | 100 MB | 5,120 MB (5 GB) |
| `api_calls` | REST API requests | 100 | 5,000 |
| `ai_generations` | AI‑powered features (summaries, grammar check, etc.) | 10 | 500 |
| `team_members` | Number of users in collaborative projects | 1 | 10 |
### 3.2 Usage Enforcement
- When a user attempts to create a new article, the system checks `articles_created < limit`. If exceeded, the request is rejected with `429 Too Many Requests`.
- File uploads check `storage_used_mb + file_size_mb ≤ limit`.
- Each AI endpoint call consumes one AI generation token.
- API calls are counted per request (excluding public/static endpoints).
### 3.3 Usage Reset & Pro‑rating
- Counters reset to zero on the 1st day of every month at 00:00 UTC.
- When a user upgrades mid‑month, the remaining quota for that month is **not prorated** – they immediately receive the full Pro limit. However, downgrading to Free mid‑month does **not** revoke already‑used quota – the user will be blocked from creating new content if they exceed the Free limit.
---
## 4. Subscription API Endpoints
Base URL: `https://yourdomain.com/api/subscription`
### 4.1 Get Available Plans
```
GET /api/subscription/plans
```
**Response example:**
```json
{
"success": true,
"plans": [
{
"id": "FREE",
"name": "Free",
"priceMonthly": 0.0,
"priceYearly": 0.0,
"currency": "USD",
"features": ["Up to 5 articles", "100 MB storage", "100 API calls per month", ...],
"limits": { "articles": 5, "storageMB": 100, "apiCalls": 100, "aiGenerations": 10, "teamMembers": 1 },
"popular": false,
"recommended": false,
"trialDays": 0
},
{
"id": "PRO_MONTHLY",
"name": "Professional",
"priceMonthly": 29.99,
"priceYearly": 299.99,
"description": "Advanced features for professional researchers",
"features": ["Up to 100 articles", "5 GB storage", "5000 API calls", "500 AI generations", ...],
"limits": { "articles": 100, "storageMB": 5120, "apiCalls": 5000, "aiGenerations": 500, "teamMembers": 10 },
"popular": true,
"trialDays": 14
},
{
"id": "PRO_YEARLY",
"name": "Professional (Yearly)",
"priceMonthly": 24.99,
"priceYearly": 299.99,
"recommended": true,
"trialDays": 14
}
]
}
```
### 4.2 Get Single Plan
```
GET /api/subscription/plan/{planId}
```
**Path parameters:** `planId` = `FREE`, `PRO_MONTHLY`, or `PRO_YEARLY`
### 4.3 Get Current User’s Subscription
```
GET /api/subscription/me
```
**Headers:** `Authorization: Bearer <token>`
**Response example:**
```json
{
"success": true,
"subscription": {
"userId": 123,
"username": "researcher1",
"plan": "PRO_MONTHLY",
"status": "active",
"startDate": "2025-01-15T10:00:00",
"endDate": "2025-02-15T10:00:00",
"autoRenew": true,
"cancelled": false,
"isTrial": false,
"trialDaysRemaining": 0,
"daysRemaining": 28,
"articleLimit": 100,
"storageLimitMB": 5120,
"apiCallsLimit": 5000,
"aiGenerationsLimit": 500,
"teamMembersLimit": 10,
"articlesUsed": 12,
"storageUsedMB": 245,
"apiCallsUsed": 387,
"aiGenerationsUsed": 23,
"teamMembersUsed": 3,
"features": {
"aiSearch": true,
"advancedAnalytics": true,
"apiAccess": true,
"prioritySupport": true,
"collaboration": true,
"exportCitations": true
},
"paymentMethod": "credit_card",
"paymentProvider": "stripe",
"price": 29.99,
"currency": "USD",
"lastInvoiceId": "INV-1737123456789-ABC12345",
"lastInvoiceDate": "2025-01-15T10:00:00",
"lastInvoiceAmount": 29.99
}
}
```
### 4.4 Subscribe to a Plan
```
POST /api/subscription/subscribe
```
**Headers:** `Authorization: Bearer <token>`, `Content-Type: application/json`
**Request body:**
```json
{
"planId": "PRO_MONTHLY",
"paymentMethod": "credit_card",
"paymentToken": "pm_xxx", // from Stripe/PayPal
"couponCode": "WELCOME10", // optional
"autoRenew": true
}
```
**Response:** same as `GET /api/subscription/me`
### 4.5 Upgrade to Pro (convenience)
```
POST /api/subscription/upgrade?yearly=false
```
**Query parameter:** `yearly` – `false` for monthly, `true` for yearly.
**Response:** same as `GET /api/subscription/me`
### 4.6 Cancel Subscription (at period end)
```
POST /api/subscription/cancel
```
**Effect:** sets `cancelled = true` and `autoRenew = false`. Access continues until `endDate`.
**Response:**
```json
{
"success": true,
"message": "Subscription cancelled. You will have access until the end of the billing period."
}
```
### 4.7 Downgrade to Free Immediately
```
POST /api/subscription/downgrade
```
**Effect:** immediately sets plan to `FREE` and removes future expiry. **Warning:** any over‑usage of Free limits will block further actions.
### 4.8 Get Current Usage (without consuming)
```
GET /api/subscription/usage
```
**Response:**
```json
{
"success": true,
"usage": {
"remainingGenerations": 477,
"canCreateArticle": 1
}
}
```
### 4.9 Consume an AI Generation
```
POST /api/subscription/consume
```
**Effect:** increments `ai_generations` counter. Returns `429` if limit reached.
**Response:**
```json
{
"success": true,
"remaining": 477
}
```
### 4.10 List Invoices (paginated)
```
GET /api/subscription/invoices?page=0&limit=20
```
**Response:**
```json
{
"success": true,
"invoices": [
{
"invoiceNumber": "INV-...",
"amount": 29.99,
"currency": "USD",
"status": "paid",
"issuedAt": "2025-01-15T10:00:00",
"pdfUrl": "/api/subscription/invoices/INV-.../pdf"
}
]
}
```
### 4.11 Admin Endpoints
| Endpoint | Method | Description | Role |
|----------|--------|-------------|------|
| `/api/subscription/admin/all?page=0&limit=20` | GET | List all users’ subscriptions (with usage) | ADMIN |
| `/api/subscription/admin/stats` | GET | Aggregated subscription statistics | ADMIN |
**Admin stats response:**
```json
{
"success": true,
"statistics": {
"totalUsers": 1250,
"freeUsers": 980,
"proMonthly": 200,
"proYearly": 70,
"activePro": 270,
"conversionRate": 21.6,
"monthlyRecurringRevenue": 12998.50
}
}
```
---
## 5. Webhook Integration (Payment Providers)
To handle subscription events (payment success, cancellation, renewal), configure a webhook endpoint:
```
POST /api/subscription/webhook/{provider}
```
**Supported providers:** `stripe`, `paypal`
**Example Stripe webhook payload handling:**
```json
{
"type": "invoice.payment_succeeded",
"data": {
"object": {
"customer": "cus_xxx",
"subscription": "sub_xxx",
"amount_paid": 2999,
"currency": "usd"
}
}
}
```
The service will update the user’s subscription expiry date and create a new invoice.
---
## 6. Usage Middleware / Interceptors
To enforce limits, the following filters/interceptors should be applied:
| Limitation | Interceptor |
|------------|-------------|
| Article creation | `ArticleService.create()` checks `articles_used < limit` before saving |
| File upload | `FileUploadService` checks storage limit before writing file |
| API calls | A `RateLimitFilter` or `UsageInterceptor` increments `api_calls` per authenticated request |
| AI features | Each AI endpoint calls `SubscriptionService.consumeGeneration()` |
| Team member invitations | `ProjectService.addMember()` checks team member limit |
---
## 7. Database Schema (Summary)
```sql
-- Users table (extended)
ALTER TABLE users ADD COLUMN subscription_plan VARCHAR(20) DEFAULT 'FREE';
ALTER TABLE users ADD COLUMN subscription_expiry TIMESTAMP;
ALTER TABLE users ADD COLUMN subscription_start TIMESTAMP;
ALTER TABLE users ADD COLUMN subscription_cancelled BOOLEAN DEFAULT 0;
ALTER TABLE users ADD COLUMN subscription_auto_renew BOOLEAN DEFAULT 1;
-- Monthly usage
CREATE TABLE subscription_usage (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
year_month VARCHAR(7) NOT NULL,
articles_created INTEGER DEFAULT 0,
api_calls INTEGER DEFAULT 0,
storage_used_mb INTEGER DEFAULT 0,
ai_generations INTEGER DEFAULT 0,
UNIQUE(user_id, year_month)
);
-- Invoices
CREATE TABLE invoices (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
invoice_number VARCHAR(50) UNIQUE NOT NULL,
plan VARCHAR(20) NOT NULL,
amount DECIMAL(10,2) NOT NULL,
currency VARCHAR(3) DEFAULT 'USD',
status VARCHAR(20) DEFAULT 'pending',
payment_method VARCHAR(50),
payment_provider VARCHAR(50),
payment_provider_id VARCHAR(100),
issued_at TIMESTAMP,
paid_at TIMESTAMP
);
```
---
## 8. Error Codes
| HTTP Status | Code | Description |
|-------------|------|-------------|
| 429 | `LIMIT_REACHED` | Monthly quota exceeded (articles, storage, API calls, or AI generations) |
| 402 | `PAYMENT_REQUIRED` | Subscription expired or missing payment |
| 400 | `SUBSCRIPTION_ERROR` | Invalid plan ID or coupon code |
| 403 | `FORBIDDEN` | Admin endpoint accessed by non‑admin |
---
## 9. Example Frontend Integration
### Show current plan and usage bar
```javascript
fetch('/api/subscription/me', { headers: { 'Authorization': `Bearer ${token}` } })
.then(res => res.json())
.then(data => {
const sub = data.subscription;
document.getElementById('planName').innerText = sub.plan;
document.getElementById('articlesUsed').innerText = `${sub.articlesUsed}/${sub.articleLimit}`;
const percent = (sub.articlesUsed / sub.articleLimit) * 100;
document.getElementById('usageFill').style.width = `${percent}%`;
});
```
### Upgrade button
```javascript
document.getElementById('upgradeBtn').addEventListener('click', async () => {
const res = await fetch('/api/subscription/upgrade?yearly=false', {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` }
});
if (res.ok) location.reload();
else alert('Upgrade failed');
});
```
---
## 10. Automated Renewal & Expiry Check
A scheduled job (cron `0 0 0 * * *`) runs daily to:
- Expire subscriptions where `endDate < now()` and `autoRenew == false`
- For `autoRenew == true`, attempt to charge the saved payment method and extend `endDate` by one billing period
- Send expiry notifications 7, 3, and 1 day before expiry

Xet Storage Details

Size:
12.1 kB
·
Xet hash:
bd73d9d3e40d2b50aa10a04aa2bd94d85867b22891f4df1026e41453738d307c

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.