Operations Log¶
Operations log is a complete audit log of all actions with subscribers, packages, and subscriptions in Catena. Every change is recorded with a timestamp, enabling history tracking and billing calculations.
What is an Operation¶
An operation is a record of a specific action performed in the system. Each operation contains information about what was done, when, and with which objects.
Why operations log is needed:
- 💰 Revenue calculation — counting created and cancelled subscriptions for billing
- 📊 Action audit — who, what, and when did in the system
- 🔍 Problem debugging — change history to identify causes
- 📈 Business analytics — growth metrics, churn rate, popular packages
- 🔐 Security — tracking suspicious actions
- 📝 Compliance — evidence for regulators and auditors
What is recorded:
Subscription creation → Operation createPackageSubscriber
↓
Billing period start
↓
Subscription cancellation → Operation deletePackageSubscriber
↓
Cost calculation = (cancel date - create date) × price
Operation Types¶
Subscriber Operations¶
autoCreateSubscriber — automatic subscriber creation
- Happens on first SMS login (if auto-registration enabled)
- System creates account "on the fly"
- May automatically connect free packages
createSubscriber — manual subscriber creation
- Administrator or billing created account
- Via web interface or Management API
- Usually followed by package connection
deleteSubscriber — subscriber deletion
- Complete account removal
- Automatically cancels all subscriptions
- Irreversible action
disableSubscriber — subscriber blocking
- Temporary access blocking
- Subscriptions preserved but viewing access blocked
- Used for non-payment, rule violations
enableSubscriber — subscriber unblocking
- Access restoration after blocking
- Subscriptions remain active
Subscription Operations¶
createPackageSubscriber — subscription creation
- Package connection to subscriber
- Key billing operation — paid period start
- Records subscription start date
deletePackageSubscriber — subscription deletion
- Package disconnection from subscriber
- Key billing operation — paid period end
- Used for cost calculation
Package Operations¶
createPackage — package creation
- New tariff plan created
- Audit for tracking product line changes
deletePackage — package deletion
- Package removed from system
- All subscriptions to it must be cancelled beforehand
Operation Structure¶
Main Fields¶
operationId — unique operation identifier
- Format: base64-encoded Snowflake ID
- Example:
oKl9SW3AAAE.
- Generated automatically when creating record
type — operation type
- One of predefined types (see above)
- Used for filtering and grouping
- Example:
createPackageSubscriber
portalId — portal identifier
- Which portal the operation relates to
- Used for data isolation between portals
- Example:
pKl9SW3AAAE.
subscriberId — subscriber identifier (optional)
- Present in subscriber-related operations
- Null for package operations
- Example:
sKl9SW3AAAE.
packageId — package identifier (optional)
- Present in package-related operations
- Null for subscriber create/delete operations
- Example:
pkKl9SW3AAAE.
createdAt — operation creation time
- Format: ISO 8601 timestamp
- Example:
2024-10-16T10:00:00Z
- Key field for billing — exact event date
updatedAt — last update time
- Usually matches createdAt
- May differ if operation was modified
- Example:
2024-10-16T10:00:00Z
payload — additional operation data
- JSON object with operation details
- Content depends on operation type
- Examples:
{"subscriberId": "sKl9SW3AAAE.", "name": "John Doe"}
{"packageId": "pkKl9SW3AAAE.", "packageName": "premium"}
Getting Operations List¶
Basic Request¶
Get all operations:
curl -X GET https://your-catena-domain.com/tv-management/api/v1/operations \
-H "X-Auth-Token: your-api-key"
Response:
{
"operations": [
{
"operationId": "opKl9SW3AAAE.",
"type": "createSubscriber",
"portalId": "pKl9SW3AAAE.",
"subscriberId": "sKl9SW3AAAE.",
"packageId": null,
"createdAt": "2024-10-16T10:00:00Z",
"updatedAt": "2024-10-16T10:00:00Z",
"payload": {
"name": "John Doe",
"phone": "+12345678901"
}
},
{
"operationId": "opKl9SW3AAAB.",
"type": "createPackageSubscriber",
"portalId": "pKl9SW3AAAE.",
"subscriberId": "sKl9SW3AAAE.",
"packageId": "pkKl9SW3AAAE.",
"createdAt": "2024-10-16T10:05:00Z",
"updatedAt": "2024-10-16T10:05:00Z",
"payload": {
"packageName": "premium"
}
}
],
"next": "cursor-for-next-page"
}
Billing Calculations¶
Revenue Calculation for Period¶
Task: Calculate revenue for October 2024
Python example:
import requests
from datetime import datetime
from collections import defaultdict
API_URL = "https://catena.example.com/tv-management/api/v1"
API_KEY = "your-api-key"
# Package prices (store in your billing DB)
PACKAGE_PRICES = {
"basicKl9SW3AAAE.": 10.0, # $10/month
"premiumKl9SW3AAAE.": 20.0, # $20/month
"sportKl9SW3AAAE.": 15.0 # $15/month
}
def calculate_monthly_revenue(year, month):
"""Calculate revenue for month based on operations"""
start_date = f"{year}-{month:02d}-01"
if month == 12:
end_date = f"{year + 1}-01-01"
else:
end_date = f"{year}-{month + 1:02d}-01"
# Get subscription creations
subscriptions = get_operations(
type="createPackageSubscriber",
created_at_gte=start_date,
created_at_lt=end_date
)
# Calculate revenue
total_revenue = 0
for op in subscriptions:
package_id = op['packageId']
price = PACKAGE_PRICES.get(package_id, 0)
total_revenue += price
return total_revenue
revenue = calculate_monthly_revenue(2024, 10)
print(f"Revenue for October 2024: ${revenue:.2f}")
Best Practices¶
Data Retention¶
Recommendations:
- In Catena: Store operations minimum 90 days
- In billing DB: Store forever for tax reporting
- Archiving: Export old operations to cold storage (S3, glacier)
Duplicate Prevention¶
Use idempotent processing to avoid duplicate billing
See Also¶
- Subscriber Management — subscriber creation records operations
- Subscription Management — subscription create/delete
- Package Management — package operations
- Play Sessions — additional data for traffic billing