Skip to content

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