The Trinity Beast — Aurora Data Dictionary

Complete schema reference for CPMP_Backend_Aurora — Aurora PostgreSQL Serverless v2. All 35 tables, columns, indexes, and foreign keys.

Database: CPMP_Backend_Aurora Engine: Aurora PostgreSQL Serverless v2 Updated: May 3, 2026 Version: v16

Table of Contents

  1. Group 1 — Core: Users & Authentication
    1. 1.1 api_keys — API key management for subscribers
    2. 1.2 rate_limit_template — Rate limit presets
    3. 1.3 users — Subscriber / donor accounts
  2. Group 2 — Configuration
    1. 2.1 application_parameter_profiles — System-mode parameter profiles
    2. 2.2 application_parameters — Runtime configuration parameters
    3. 2.3 report_parameters — LRS-specific configuration
  3. Group 3 — Billing & Payments
    1. 3.1 payment_links — Stripe Payment Link management for checkout
    2. 3.2 transactions — Payment records
  4. Group 4 — Usage Logging
    1. 4.1 monthly_report_counts — Monthly report usage aggregation
    2. 4.2 report_count — Per-API-key report limit tracking
    3. 4.3 report_usage_logs — LRS report request log
    4. 4.4 usage_logs — LPO API call log
  5. Group 5 — Exchange & Pricing
    1. 5.1 asset_categories — Crypto asset category groupings
    2. 5.2 exchange_asset_map — Exchange-to-asset symbol translations
    3. 5.3 exchange_feeds — Exchange WebSocket feed configurations
  6. Group 6 — Email & Newsletters
    1. 6.1 email_drafts — Email composition drafts
    2. 6.2 email_senders — Verified SES sender identities
    3. 6.3 email_templates — SES email templates
    4. 6.4 email_translations — Multi-language email template fields
    5. 6.5 newsletter_subscribers — Newsletter mailing list
    6. 6.6 newsletter_templates — Newsletter email templates
    7. 6.7 newsletter_translations — Multi-language newsletter content
    8. 6.8 newsletters — Sent newsletter campaigns
  7. Group 7 — Support & Engagement
    1. 7.1 demo_leads — Demo registration captures
    2. 7.2 map_pins — CPMP mission impact map markers
    3. 7.3 partner_applications — AWS Partner application submissions
    4. 7.4 support_replies — Support ticket replies
    5. 7.5 support_tickets — Customer support system
  8. Group 8 — Operations & Maintenance
    1. 8.1 cron_execution_logs — Cron job execution tracking
    2. 8.2 cron_reset_logs — Monthly usage reset audit log
    3. 8.3 cron_reset_summary — Reset summary statistics
  9. Group 9 — Website Analytics
    1. 9.1 page_events — Website interaction event tracking
    2. 9.2 page_views — Website page view analytics
  10. Group 10 — Webhook Push
    1. 10.1 webhook_subscriptions — Webhook subscriber configurations & delivery state
    2. 10.2 webhook_delivery_log — Webhook delivery attempt log
Group 1 — Core: Users & Authentication3 tables

1.1 api_keys

Purpose: API key management for subscribers. Stores every issued API key along with its tier, rate limits, usage counters, Stripe billing references, and subscription state. Central table for authentication and authorization of all LPO/LRS API requests.

24 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the API key record
user_id FK → users.iduuidYESOwner of the key; references the users table
key_hashtextYESLegacy hash field (unused in current implementation)
nametextYESSubscriber name associated with this key
tiertext'free'NOSubscription tier: free, pro, enterprise, unlimited, lifetime, or partner
query_limitinteger1000NOMaximum number of API queries allowed per month
current_usageinteger0NOCurrent month's query count; reset monthly by cron job
last_usedtimestamptzYESTimestamp of the most recent API call using this key
created_attimestamptznow()NOWhen this API key was created
revokedbooleanfalseNOWhether this key has been disabled/revoked
rate_limit_qpsinteger10NOMaximum queries per second allowed for this key
burst_limitinteger20NOToken bucket burst capacity for rate limiting
burst_tokensnumeric20.0NOCurrent token balance in the rate-limit token bucket
api_keytextNOThe actual API key string (plaintext); used for authentication
last_successtimestamptzYESTimestamp of the last successful (non-error) API call
minimum_wait_secondsnumeric0.1NOMinimum time between requests when the key is being throttled
lrs_enabledbooleanfalseNOWhether unlimited LRS (Listener Report Service) reports are enabled
response_formattext'tbc'NOPreferred response format: tbc (The Trinity Beast Canonical) or plain
stripe_customer_idtextYESStripe customer ID used for webhook event lookups
stripe_subscription_idtextYESMain LPO subscription ID in Stripe
stripe_lrs_subscription_idtextYESSeparate LRS add-on subscription ID in Stripe
subscription_statustext'active'NOCurrent subscription state: active, past_due, or canceled
tier_effective_datetimestamptzYESWhen the current tier took effect (for proration tracking)
payment_failed_attimestamptzYESTimestamp of the first payment failure (triggers grace period logic)

Indexes

  • api_keys_pkey — Primary key on id
  • idx_api_keys_stripe_customer_id — Partial index on stripe_customer_id WHERE stripe_customer_id IS NOT NULL
  • idx_api_keys_stripe_subscription_id — Partial index on stripe_subscription_id WHERE stripe_subscription_id IS NOT NULL

Foreign Keys

  • user_idusers.id

1.2 rate_limit_template

Purpose: Rate limit presets by subscription tier. Defines QPS, burst, query limits, and minimum wait configurations for each tier. Used by the Lambda receipt handler when creating new API keys and by the LPO server for runtime rate limiting. Single source of truth for all tier configurations — 11 tiers: 6 LPO + 5 Webhook.

8 columns 11 tiers

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the template
tiervarcharNOTier name: free, pro, enterprise, unlimited, lifetime, partner (LPO) or webhook_starter, webhook_standard, webhook_professional, webhook_enterprise, webhook_partner (Webhook)
query_limitintegerNOMonthly query limit (999999999 = unlimited)
rate_limit_qpsintegerNOQueries per second limit (0 = no limit for partner)
burst_limitintegerNOToken bucket burst capacity
burst_tokensnumericNOInitial token balance
min_wait_secondsnumericNOMinimum wait between requests in seconds (0 = no wait)
descriptiontextYESHuman-readable description of the tier

Indexes

  • rate_limit_template_pkey — Primary key on id
  • rate_limit_template_tier_key — Unique on tier
Current Tier Data (11 rows):
TierQuery LimitQPSBurstMin Wait
LPO Subscription Tiers (6)
free1,000151.0s
pro50,0005100.2s
enterprise500,00010200.1s
unlimitedUnlimited831000.012s
lifetimeUnlimited831000.012s
partnerUnlimited0 (none)0 (none)0 (none)
Webhook Associate Tiers (5) — all numbers multiples of 3
webhook_starter999360.3s
webhook_standard4,9986120.15s
webhook_professional9,99912240.06s
webhook_enterprise49,99824480.03s
webhook_partnerUnlimited0 (none)0 (none)0 (none)

1.3 users

Purpose: Subscriber and donor accounts. Minimal user profile storing email, name, tier, and preferred language. Referenced by api_keys and transactions tables. Preferred language is captured from the Stripe checkout locale at subscription/donation time.

6 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the user
emailtextNOUser's email address (UNIQUE)
nametextYESUser's display name
tiertextYESCurrent subscription tier
preferred_langvarchar(5)NULLYESPreferred language code (e.g., en, de, ja) — captured from Stripe checkout locale
created_attimestamptznow()NOAccount creation timestamp

Indexes

  • users_pkey — Primary key on id
  • users_email_key — Unique constraint on email
Group 2 — Configuration3 tables

2.1 application_parameter_profiles

Purpose: System-mode parameter profiles. Stores named configuration profiles (demo, fresh-price, stress, debug, etc.) that can be applied at runtime via GET /admin/system-mode?mode=<profile_name>. Each profile defines a complete set of tuning parameters — rate limits, cache TTLs, connection pool sizes, batch settings, and logging levels. Profiles can be added or modified via SQL without code deploys. Created at startup via idempotent migration with default seed profiles.

24 columns

ColumnData TypeDefaultNullableDescription
id PKserialauto-incrementNOAuto-increment primary key
profile_nametextNOUnique profile identifier (UNIQUE); used in system-mode API calls
descriptiontextYESHuman-readable description of the profile's purpose and tuning rationale
qpsinteger1000NOQueries per second rate limit applied globally
burstinteger1000NOToken bucket burst capacity for rate limiting
log_leveltext'info'NOApplication log level: debug, info, warn, or error
sqs_batch_sizeinteger10NOMessages per SQS SendMessageBatch call (1-10)
sqs_flush_msinteger100NOSQS producer flush interval in milliseconds
sqs_buffer_sizeinteger50000NOSQS producer channel buffer capacity
sqs_timeout_msinteger3000NOPer-batch SQS API call timeout in milliseconds
db_max_openinteger150NOMaximum open Aurora database connections
db_max_idleinteger75NOMaximum idle Aurora database connections
db_conn_lifetime_mininteger10NOMaximum lifetime of a database connection in minutes
db_conn_idle_mininteger5NOMaximum idle time for a database connection in minutes
cache_ttlinteger9NOElastiCache price TTL in seconds before expiry
config_pollinteger300NOInterval in seconds between application parameter reloads
cache_pool_sizeinteger600NOElastiCache connection pool size (must be multiple of 3 — one per container)
cache_min_idleinteger120NOMinimum idle ElastiCache connections pre-warmed in the pool
cache_max_retriesinteger1NOMaximum retry attempts for failed ElastiCache operations
cache_dial_msinteger500NOElastiCache connection dial timeout in milliseconds
cache_read_msinteger500NOElastiCache read timeout in milliseconds
cache_write_msinteger500NOElastiCache write timeout in milliseconds
created_attimestamptznow()NOWhen this profile was created
updated_attimestamptznow()NOLast time this profile was modified

Indexes

  • application_parameter_profiles_pkey — Primary key on id
  • application_parameter_profiles_profile_name_key — Unique constraint on profile_name

Seeded Profiles

  • demo — Low-throughput demo mode (QPS 3, TTL 30s, verbose logging)
  • debug — Debug mode with verbose logging and relaxed limits
  • fresh-price — Production mode with 13s cache TTL for near-real-time pricing
  • stress — Stress testing baseline (QPS 100K, TTL 300s)
  • stress-tcp-direct — TCP direct single-node stress testing
  • stress-tcp-alb — TCP via ALB multi-node stress testing
  • stress-udp-direct — UDP direct single-node stress testing
  • stress-udp-nlb — UDP via NLB multi-node stress testing

2.2 application_parameters

Purpose: Runtime configuration parameters. Stores key-value pairs that control application behavior (cache TTLs, prewarm intervals, feature flags, pool sizes, etc.). Values are stored as text and parsed by the application at load time. Synced to ElastiCache as the app:config hash.

4 columns

ColumnData TypeDefaultNullableDescription
id PKintegerserialNOAuto-increment primary key
keytextNOParameter name (UNIQUE); e.g. cache_ttl_seconds, log_level
valuetextNOParameter value stored as text; parsed by the application
updated_attimestamptznow()NOLast time this parameter was modified

Indexes

  • application_parameters_pkey — Primary key on id
  • application_parameters_key_key — Unique constraint on key

2.3 report_parameters

Purpose: LRS-specific configuration parameters. Same structure as application_parameters but dedicated to the Listener Report Service. Controls report limits, retention periods, and LRS feature flags.

4 columns

ColumnData TypeDefaultNullableDescription
id PKintegerserialNOAuto-increment primary key
keytextNOParameter name (UNIQUE)
valuetextNOParameter value stored as text
updated_attimestamptznow()NOLast time this parameter was modified

Indexes

  • report_parameters_pkey — Primary key on id
  • report_parameters_key_key — Unique constraint on key
Group 3 — Billing & Payments2 tables

3.2 transactions

Purpose: Payment records for all Stripe transactions. Covers subscriptions, donations, and LRS add-on purchases. Links to the users table and stores the Stripe session/charge IDs for reconciliation. Preferred language is captured from the Stripe checkout locale.

15 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for this transaction
user_id FK → users.iduuidYESUser who made the payment
typetextYESTransaction type: subscription, donation, or lrs-addon
stripe_session_idtextYESStripe checkout session ID
stripe_charge_idtextYESStripe payment intent / charge ID
amount_usdnumericYESPayment amount in USD
statustextYESTransaction status: completed or refunded
donor_nametextYESName of the donor (for donation transactions)
donor_emailtextYESEmail of the donor (for donation transactions)
tiertextYESSubscription tier at the time of purchase
api_keytextYESAPI key generated as part of this subscription purchase
recurringbooleanYESWhether this is a recurring subscription payment
preferred_langvarchar(5)NULLYESLanguage code at checkout time (e.g., en, de, ja) — from Stripe locale
created_attimestamptznow()NOWhen the transaction was recorded
updated_attimestamptznow()NOLast time the transaction record was updated

Indexes

  • transactions_pkey — Primary key on id

Foreign Keys

  • user_idusers.id
Group 4 — Usage Logging4 tables

4.1 monthly_report_counts

Purpose: Monthly report usage aggregation. Stores a per-API-key, per-month count of LRS reports generated. Used for billing reconciliation and historical usage analytics.

4 columns

ColumnData TypeDefaultNullableDescription
id PKuuidNOUnique identifier
api_key_iduuidYESAPI key this count belongs to
monthdateYESFirst day of the month this count covers
countintegerYESTotal reports generated in this month

Indexes

  • monthly_report_counts_pkey — Primary key on id

4.2 report_count

Purpose: Per-API-key report limit tracking. Enforces monthly caps on LRS report generation. The reset_month column enables automatic month rollover — when the current month differs from reset_month, the counter resets to zero without a cron job. Daily counts are tracked but not enforced (subscribers choose their own pace).

8 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier
api_key FK → api_keys.iduuidNOAPI key this counter belongs to
monthly_countinteger0NONumber of reports generated this month (auto-resets when reset_month changes)
daily_countinteger0NONumber of reports generated today (resets when last_report_date changes)
last_report_datetimestamptznow()NOTimestamp of the most recent report request
monthly_limitinteger10NOMaximum reports allowed per month
daily_limitinteger5NOMaximum reports allowed per day (tracked but not enforced)
reset_monthintegerEXTRACT(MONTH FROM NOW())NOMonth number (1–12) when counters were last reset — enables automatic month rollover without cron

Indexes

  • report_count_pkey — Primary key on id

Foreign Keys

  • api_keyapi_keys.id

4.3 report_usage_logs

Purpose: Every LRS report request is logged here. Tracks which report type was requested, the output format, date/asset filters applied, row count returned, and processing time. Used for auditing, the /reports/report-usage and /reports/report-summary meta-report endpoints, and MemoryDB cache mirroring.

13 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for this report log entry
api_key_idtextYESAPI key that requested the report
report_typetextYESReport type: usage, summary, report-usage, or report-summary
report_run_datetimestamptzYESWhen the report was executed
asset_filtertextYESAsset filter applied to the report (e.g., BTC, ETH, or empty for all)
start_date_filtertimestamptzYESStart date filter applied to the report query
end_date_filtertimestamptzYESEnd date filter applied to the report query
max_rows_returnedintegerYESNumber of rows returned in the report
report_duration_msintegerYESReport processing time in milliseconds
output_formattextYESOutput format: json, csv, tsv, or text
additional_filtersjsonbYESAdditional query filters as JSON (cached, source, etc.)
regiontextYESAWS region where the report was processed
cluster_nodetextYESWhich ECS container handled the request (BeastMain, BeastMirror, BeastLRS)

Indexes

  • report_usage_logs_pkey — Primary key on id

4.4 usage_logs

Purpose: Every LPO API call is logged here. Written by the QueuedWriter Lambda which drains the SQS queue in batches. Records the asset queried, price returned, source, latency, cache status, client IP, and query metadata. Primary data source for LRS usage and summary reports. Mirrored to MemoryDB for fast LRS queries.

18 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for this log entry
user_idtextYESUser ID associated with the API key
api_key_idtextYESAPI key that was used for this request
timestamptimestamptznow()NOWhen the request occurred (set by QueuedWriter at insert time)
ip_addresstextYESClient IP address
query_typetextYESType of query (e.g., price, multi-price)
duration_msbigintYESTotal request processing time in milliseconds
token_countintegerYESRate limit tokens consumed by this request
latency_msbigintYESSource fetch latency in milliseconds (0 on cache hit)
statustextYESRequest outcome status (success, error, rate_limited)
errortextYESError message if the request failed (NULL on success)
cachedbooleanYESWhether the response was served from ElastiCache
assettextYESCryptocurrency asset queried (BTC, ETH, SOL, etc.)
cache_age_secondsdouble precisionYESAge of the cached price in seconds at time of request
pricedouble precisionYESPrice returned to the caller
sourcetextYESPrice source: coinbase-ws, gemini-ws, kraken-ws, gateio-ws, bybit-ws, okx-ws
cluster_nodetextYESWhich ECS container handled the request (BeastMain, BeastMirror, BeastLRS, BeastWebhook)
aws_regiontextYESAWS region where the request was processed (e.g., us-east-2)

Indexes

  • usage_logs_pkey — Primary key on id
Group 5 — Exchange & Pricing3 tables

5.1 asset_categories

Purpose: Crypto asset category groupings. Organizes the 150 supported assets into logical categories (Layer 1, DeFi, Meme, Stablecoin, etc.) for the public GET /asset-categories endpoint. Display order controls the sort on the subscribe-listener page. Categories can be enabled/disabled without code deploys.

6 columns

ColumnData TypeDefaultNullableDescription
id PKserialauto-incrementNOAuto-increment primary key
category_nametextNOCategory display name (e.g., "Layer 1", "DeFi", "Meme Coins")
descriptiontext''NOBrief description of the category
display_orderinteger100NOSort order for display — lower numbers appear first
enabledbooleantrueNOWhether this category is visible in the API response
created_attimestamptznow()NOWhen this category was created

Indexes

  • asset_categories_pkey — Primary key on id

5.2 exchange_asset_map

Purpose: Exchange-to-asset symbol translations. Maps normalized asset names (BTC, ETH) to exchange-specific symbols (BTC-USD, btcusd, BTC/USD, BTCUSDT, BTC_USDT, BTC-USDT). Each exchange has 25 unique assets with zero overlap. 150 total assets across 6 exchanges. The category column powers the GET /asset-categories endpoint for grouped asset display. Managed via /admin/exchange-assets API.

6 columns

ColumnData TypeDefaultNullableDescription
id PKserialauto-incrementNOAuto-increment primary key
exchange_nametextNOExchange this mapping belongs to (references exchange_feeds)
assettextNONormalized asset name (BTC, ETH, SOL, etc.)
exchange_symboltextNOExchange-specific symbol (BTC-USD, btcusd, BTC/USD, BTCUSDT, etc.)
enabledbooleantrueNOPer-asset enable/disable switch
categorytext'Infrastructure'NOAsset category grouping (Major Currencies, DeFi, Layer 2, AI & Data, Gaming & NFTs, Meme Coins, Infrastructure) — references asset_categories

Indexes

  • exchange_asset_map_pkey — Primary key on id
  • exchange_asset_map_exchange_name_asset_key — Unique constraint on (exchange_name, asset)
  • idx_exchange_asset_map_exchange — Index on exchange_name
  • idx_exchange_asset_map_asset — Index on asset

5.3 exchange_feeds

Purpose: Exchange WebSocket feed configurations. Table-driven exchange management — each row defines a complete WebSocket connection including endpoint, subscribe message template, JSON paths for parsing trade messages, ping requirements, and symbol formatting. Adding a new exchange is an INSERT, not a code deploy. Managed via the TBCC Exchange Manager widget and /admin/exchange-feeds API.

25 columns

ColumnData TypeDefaultNullableDescription
id PKserialauto-incrementNOAuto-increment primary key
exchange_nametextNOUnique exchange identifier (UNIQUE); e.g., coinbase, kraken, gateio
display_nametextNOHuman-readable name (e.g., "Gate.io", "Coinbase")
ws_endpointtextNOWebSocket URL (e.g., wss://ws.kraken.com/v2)
subscribe_formattext'json'NOSubscribe message format (legacy column from initial migration)
pair_suffixtext'USD'NOQuote currency: USD or USDT
symbol_templatetextNOHow to build subscribe symbols (e.g., {ASSET}-USD, {asset}usdt)
symbol_separatortext'-'NOSeparator in symbol format (-, /, _, or empty)
parse_regextextYESLegacy regex for parsing trade messages (superseded by JSON path columns)
source_tagtextNOTag in API responses and usage logs (e.g., coinbase-ws, gateio-ws)
subscribe_templatetextYESJSON template for the subscribe message with {SYMBOLS} placeholder
trade_channel_matchtextYESRules to identify trade messages (e.g., channel=trade)
price_pathtextYESJSON path to the price field in trade messages
symbol_pathtextYESJSON path to the symbol field in trade messages
timestamp_pathtextYESJSON path to the timestamp field in trade messages
timestamp_formattext'rfc3339'YESTimestamp format: rfc3339, unix_ms, unix_ns, unix_ms_string
ping_interval_secinteger0YESKeepalive ping interval in seconds (0 = no ping needed)
ping_messagetextYESPing payload (JSON string or plain text like "ping")
symbol_styletext'standard'YESSubscribe message style: standard, coinbase, gemini, okx, bybit
msg_is_arraybooleanfalseYESWhether trade messages arrive as JSON arrays (e.g., Gate.io sends arrays of trades)
array_pathtextYESJSON path to the array within the message when msg_is_array is true
enabledbooleantrueNOMaster switch — disable an exchange without a code deploy
notestextYESOperational notes (e.g., "Replaced Binance — geo-blocked from US")
created_attimestamptznow()NOWhen this exchange feed was created
updated_attimestamptznow()NOLast time this exchange feed was modified (updated on every save)

Indexes

  • exchange_feeds_pkey — Primary key on id
  • exchange_feeds_exchange_name_key — Unique constraint on exchange_name
  • idx_exchange_feeds_enabled — Index on enabled for fast filtering
Group 6 — Email & Newsletters8 tables

6.1 email_drafts

Purpose: Email composition drafts. Stores in-progress emails being composed in the admin panel. References a template and sender identity, supports multiple recipients (to/cc/bcc as comma-separated text), and tracks draft status through to sent.

13 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the draft
template_id FK → email_templates.iduuidYESEmail template this draft is based on
sender_id FK → email_senders.iduuidYESVerified sender identity to use for this email
subjectvarchar(500)''NOEmail subject line
contenttext''NOEmail body content (HTML)
recipientstext''NOComma-separated list of recipient email addresses
cctext''NOComma-separated list of CC email addresses
bcctext''NOComma-separated list of BCC email addresses
statusvarchar(20)'draft'NODraft status: draft or sent
created_attimestamptznow()NOWhen the draft was created
updated_attimestamptznow()NOLast time the draft was modified
sent_attimestamptzYESWhen the email was sent (NULL while still a draft)

Indexes

  • email_drafts_pkey — Primary key on id

6.2 email_senders

Purpose: Verified SES sender identities. Stores email addresses and display names that can be used as the "From" address in outbound emails. Each sender has a unique email and an optional reply-to address. Managed via /admin/email-senders API.

5 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the sender
display_namevarchar(255)NOSender display name (e.g., "Cross Power Ministries")
emailvarchar(255)NOSender email address (UNIQUE) — must be verified in SES
reply_tovarchar(255)''NOReply-to email address (empty string if same as sender)
created_attimestamptznow()NOWhen the sender was added

Indexes

  • email_senders_pkey — Primary key on id
  • email_senders_email_key — Unique constraint on email

6.3 email_templates

Purpose: SES email templates. Stores reusable email templates for transactional and marketing emails sent via Amazon SES. Separate from newsletter_templates; these are used for system emails (receipts, welcome emails, etc.). Managed via /admin/email-templates API.

6 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the template
topicvarchar(100)NOTemplate topic/category (e.g., subscription, donation, welcome)
namevarchar(255)NOTemplate name (e.g., SubscriptionReceipt, DonationReceipt)
subjectvarchar(500)''NOEmail subject line
contenttextNOHTML body content of the email template
created_attimestamptznow()NOWhen the template was created

Indexes

  • email_templates_pkey — Primary key on id

6.4 email_translations

Purpose: Multi-language email template field translations. Stores translated versions of SES email template fields (subject, heading, body, footer, etc.) for each supported language. 153 rows covering 9 languages × 2 templates (SubscriptionReceipt, DonationReceipt). The Lambda receipt handler looks up the subscriber's preferred_lang and uses the matching translation. Uses {{variable}} placeholders for dynamic content.

6 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the translation row
template_namevarcharNOSES template name (e.g., SubscriptionReceipt, DonationReceipt)
langvarcharNOISO language code (en, es, fr, de, pt, ja, ko, zh, ar)
field_namevarcharNOTemplate field being translated (subject, heading, body, footer, etc.)
field_valuetextNOTranslated content — may contain {{variable}} placeholders
created_attimestamptznow()YESWhen this translation was created

Indexes

  • email_translations_pkey — Primary key on id
  • Unique constraint on (template_name, lang, field_name)

6.5 newsletter_subscribers

Purpose: Newsletter mailing list. Stores subscribers from both the LPO and CPMP websites. Tracks subscription source, opt-in/opt-out status for CAN-SPAM compliance, and preferred language for localized newsletter delivery.

7 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the subscriber
emailtextNOSubscriber's email address (UNIQUE)
nametextYESSubscriber's name
sourcetextYESWhere they subscribed from: lpo or cpmp
preferred_langvarchar'en'YESPreferred language for newsletter delivery — each subscriber receives their language version
subscribedbooleantrueNOWhether the subscriber is currently opted in
created_attimestamptznow()NOWhen the subscription was created

Indexes

  • newsletter_subscribers_pkey — Primary key on id
  • newsletter_subscribers_email_key — Unique constraint on email

6.6 newsletter_templates

Purpose: Newsletter email templates. Reusable HTML templates for newsletter campaigns. Each template has a name, subject line, and full HTML body that can be used across multiple newsletter sends.

6 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the template
nametextYESTemplate name for identification in the admin panel
subjecttextYESDefault email subject line
html_bodytextYESFull HTML body of the newsletter template
created_attimestamptznow()NOWhen the template was created
updated_attimestamptznow()NOLast time the template was modified

Indexes

  • newsletter_templates_pkey — Primary key on id

6.7 newsletter_translations

Purpose: Multi-language newsletter content. Stores translated versions of each newsletter for all 9 supported languages. Auto-generated via POST /newsletter/{id}/translate using AWS Translate, then optionally reviewed before sending. The newsletter send handler delivers each subscriber their language version based on newsletter_subscribers.preferred_lang.

9 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the translation
newsletter_id FKuuidNOReferences newsletters.id — the newsletter being translated
langvarcharNOISO language code (en, es, fr, de, pt, ja, ko, zh, ar)
subjecttextNOTranslated email subject line
body_htmltextNOTranslated full HTML email body
auto_translatedbooleantrueYESWhether this was auto-generated by AWS Translate
reviewedbooleanfalseYESWhether a human has reviewed and approved the translation
created_attimestamptznow()YESWhen this translation was created
updated_attimestamptznow()YESLast time this translation was modified

Indexes

  • newsletter_translations_pkey — Primary key on id
  • Unique constraint on (newsletter_id, lang)

6.8 newsletters

Purpose: Sent newsletter campaigns. Tracks each newsletter send including its template, delivery status, recipient count, and success/failure metrics. Status progresses from draft → sending → sent.

9 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the newsletter campaign
template_iduuidYESNewsletter template used for this send
subjecttextYESSubject line used for this send (may override template)
statustextYESCampaign status: draft, sending, or sent
recipientsintegerYESTotal number of intended recipients
sent_countintegerYESNumber of emails successfully sent
failed_countintegerYESNumber of emails that failed to send
created_attimestamptznow()NOWhen the campaign was created
sent_attimestamptzYESWhen the campaign finished sending

Indexes

  • newsletters_pkey — Primary key on id
Group 7 — Support & Engagement5 tables

7.1 demo_leads

Purpose: Demo registration captures. Stores leads from the enterprise demo request form on the website. Used by the sales pipeline for follow-up.

6 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the lead
emailtextYESLead's email address
nametextYESLead's name
companytextYESLead's company name
use_casetextYESDescribed use case for the API
created_attimestamptznow()NOWhen the demo request was submitted

Indexes

  • demo_leads_pkey — Primary key on id

7.2 map_pins

Purpose: CPMP mission impact map markers. Each pin represents a real-world impact event (medical aid, water well, wheelchair delivery, etc.) displayed on the interactive mission map. Supports multiple media attachments via the media_urls JSONB array.

10 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the map pin
typetextYESImpact type: medical, water, wheelchair, freedom, provisions, word, or education
latdouble precisionYESLatitude coordinate
lngdouble precisionYESLongitude coordinate
regiontextYESGeographic region name
captiontextYESDescription of the impact event shown on the pin
media_urltextYESLegacy single media URL (superseded by media_urls)
datetimestamptzYESDate of the impact event
statustextYESPin status: active or inactive
media_urlsjsonbYESArray of media URLs (Google Drive, YouTube, direct images)

Indexes

  • map_pins_pkey — Primary key on id

7.3 partner_applications

Purpose: AWS Partner application submissions. Stores applications from AWS companies requesting partner-tier API access to live crypto prices. The exchanges The Trinity Beast depends on share their data at no cost — this program passes that generosity forward to the AWS community. Applications are submitted via the public POST /partner/apply endpoint and reviewed through the TBCC Partner Management widget. Approved partners receive a tier=partner API key with no rate limiting, no monthly caps, and no billing.

16 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the application
company_nametextNOPartner company name (e.g., Coinbase, Gemini)
contact_nametextNOPrimary contact person at the partner company
contact_emailtextNOContact email for application correspondence
aws_account_idtextNOPartner's 12-digit AWS account ID for PrivateLink/VPC Peering setup
aws_regiontextNOAWS region where the partner's VPC is located
vpc_cidrtextYESPartner's VPC CIDR block (required for VPC Peering, optional for PrivateLink)
connection_typetextNORequested connection method: privatelink, peering, or privatelink,peering
data_providedtextYESDescription of what the partner is building and how they plan to use live crypto prices
estimated_volumetextYESEstimated monthly API volume: under-100k, 100k-1m, 1m-10m, 10m-plus, unknown
notestextYESAdditional notes from the applicant
statustext'pending'NOApplication status: pending, approved, rejected, or onboarded
reviewed_attimestamptzYESWhen the application was reviewed by an admin
reviewer_notestextYESAdmin notes from the review process
api_key_iduuidYESReference to the generated partner API key (set when onboarded)
created_attimestamptznow()NOWhen the application was submitted

Indexes

  • partner_applications_pkey — Primary key on id
  • idx_partner_apps_status — Index on status for filtering pending/approved applications
  • idx_partner_apps_email — Index on contact_email for duplicate detection

Application Lifecycle

  • pending → Application submitted, awaiting admin review in TBCC
  • approved → Admin approved, ready for infrastructure onboarding
  • onboarded → PrivateLink/VPC Peering configured, partner API key issued
  • rejected → Application declined with reviewer notes

7.4 support_replies

Purpose: Support ticket replies. Stores the conversation thread for each support ticket. Each reply is tagged with the sender type (admin or customer) and can include file attachments.

7 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for this reply
ticket_id FK → support_tickets.iduuidNOParent ticket this reply belongs to
sendertextYESWho sent the reply: admin or customer
messagetextYESReply message body
attachmentsjsonbYESFile attachments (array of URLs/metadata)
created_attimestamptznow()NOWhen the reply was sent
updated_attimestamptznow()NOLast time the reply was modified

Indexes

  • support_replies_pkey — Primary key on id

Foreign Keys

  • ticket_idsupport_tickets.id

7.5 support_tickets

Purpose: Customer support system. Stores support tickets submitted through the website or admin panel. Each ticket has a human-readable ticket number, status tracking, priority, and category classification.

12 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the ticket
ticket_numbertextNOHuman-readable ticket number (UNIQUE)
emailtextYESSubmitter's email address
nametextYESSubmitter's name
subjecttextYESTicket subject line
messagetextYESTicket body / initial message
statustext'open'NOTicket status: open, in-progress, resolved, or closed
prioritytext'normal'NOTicket priority level
categorytextYESTicket category for routing and reporting
preferred_langvarchar'en'YESVisitor's language at submission time — auto-captured from cpmp-lang cookie
created_attimestamptznow()NOWhen the ticket was submitted
updated_attimestamptznow()NOLast time the ticket was updated

Indexes

  • support_tickets_pkey — Primary key on id
  • support_tickets_ticket_number_key — Unique constraint on ticket_number
Group 8 — Operations & Maintenance3 tables

8.1 cron_execution_logs

Purpose: Cron job execution tracking. General-purpose log for all scheduled jobs (not just resets). Records job name, start/end times, status, rows affected, and any error messages. Used for operational monitoring.

7 columns

ColumnData TypeDefaultNullableDescription
id PKuuidNOUnique identifier for the execution log entry
job_nametextYESName of the cron job that was executed
started_attimestamptzYESWhen the job started
completed_attimestamptzYESWhen the job completed
statustextYESJob status: success or error
rows_affectedintegerYESNumber of rows affected by the job
error_messagetextYESError details if the job failed

Indexes

  • cron_execution_logs_pkey — Primary key on id

8.2 cron_reset_logs

Purpose: Monthly usage reset audit log. Records every execution of the monthly cron job that resets current_usage counters on all API keys. Tracks how many keys were reset, timing, and any errors.

7 columns

ColumnData TypeDefaultNullableDescription
id PKuuidNOUnique identifier for the reset log entry
reset_typetextYESType of reset performed
keys_resetintegerYESNumber of API keys that were reset
started_attimestamptzYESWhen the reset job started
completed_attimestamptzYESWhen the reset job completed
statustextYESJob status: success or error
error_messagetextYESError details if the job failed

Indexes

  • cron_reset_logs_pkey — Primary key on id

8.3 cron_reset_summary

Purpose: Reset summary statistics. Stores aggregate before/after usage totals for each monthly reset. Provides a quick audit trail to verify that resets completed correctly and no usage was lost.

6 columns

ColumnData TypeDefaultNullableDescription
id PKuuidNOUnique identifier
reset_datedateYESDate the reset was performed
total_keysintegerYESTotal number of API keys at time of reset
total_usage_beforebigintYESSum of all current_usage values before reset
total_usage_afterbigintYESSum of all current_usage values after reset (should be 0)
created_attimestamptzYESWhen this summary record was created

Indexes

  • cron_reset_summary_pkey — Primary key on id
Group 9 — Website Analytics2 tables

9.1 page_events

Purpose: Website interaction event tracking. Records user interactions beyond page views — button clicks, form submissions, navigation events, language changes, error page navigation, and custom events. The event_data JSONB column stores event-specific metadata. Powers the Page Analytics dashboard click tracking and /admin/page-analytics API.

8 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the event
page_pathvarcharNOURL path where the event occurred
event_typevarcharNOEvent category (click, submit, error_nav, lang_change, etc.)
event_targetvarchar''NOElement that triggered the event (button ID, link text, etc.)
event_datajsonb'{}'NOEvent-specific metadata (e.g., {destination: "/give.html", error_code: 404})
visitor_idvarchar''NOAnonymous persistent visitor identifier (matches page_views)
session_idvarchar''NOAnonymous session identifier (matches page_views)
created_attimestamptznow()NOWhen the event was recorded

Indexes

  • page_events_pkey — Primary key on id

9.2 page_views

Purpose: Website page view analytics. Records every page load across the CPMP website. Captures the page path, title, referrer, user agent, screen dimensions, and an anonymous visitor/session ID pair for session reconstruction. Powers the Page Analytics dashboard and /admin/page-analytics API.

11 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the page view
page_pathvarcharNOURL path of the page viewed (e.g., /subscribe-listener.html)
page_titlevarchar''NOHTML page title at time of view
referrervarchar''NOHTTP referrer URL (where the visitor came from)
user_agentvarchar''NOBrowser user agent string
visitor_idvarchar''NOAnonymous persistent visitor identifier (localStorage)
session_idvarchar''NOAnonymous session identifier (sessionStorage)
screen_widthinteger0NOVisitor's screen width in pixels
screen_heightinteger0NOVisitor's screen height in pixels
countryvarchar''NOVisitor's country (from CloudFront geo header)
created_attimestamptznow()NOWhen the page view was recorded

Indexes

  • page_views_pkey — Primary key on id
Group 10 — Webhook Push2 tables

10.1 webhook_subscriptions

Purpose: Webhook subscriber (Associate) configurations and delivery state. Each row represents one webhook subscription tied to an API key. Stores the delivery endpoints (UDP IP:port and/or HTTPS URL), selected assets, tier-based limits (interval, max assets), verification status, and Stripe billing references. The delivery engine reads active rows every 30 seconds to start/stop per-subscription push loops. Managed via /webhook/configure, /webhook/verify, /webhook/assets, and /webhook/status endpoints.

20 columns

ColumnData TypeDefaultNullableDescription
id PKuuidgen_random_uuid()NOUnique identifier for the webhook subscription
api_key_id FK → api_keys.iduuidNOAPI key this subscription belongs to; ON DELETE CASCADE
tiertext'webhook_starter'NOWebhook tier: webhook_starter, webhook_standard, webhook_professional, webhook_enterprise, or webhook_partner
delivery_methodtext'both'NODelivery mode: udp, https, or both
udp_hosttextYESAssociate's UDP endpoint IP address (e.g., 203.0.113.10)
udp_portintegerYESAssociate's UDP endpoint port (1024–65535)
https_urltextYESAssociate's HTTPS endpoint URL for signed POST delivery
interval_secondsinteger60NOPush interval in seconds — tier-dependent (60, 15, 6, or 3)
max_assetsinteger9NOMaximum assets allowed for this tier (9, 30, 75, or 150)
selected_assetstextYESComma-separated list of selected asset symbols (e.g., BTC,ETH,SOL)
statustext'pending_verification'NODelivery status: pending_verification, active, or suspended
verification_tokentextYES32-byte hex token for endpoint ownership verification; doubles as HMAC signing secret for HTTPS delivery
verified_attimestamptzYESWhen the endpoint was verified via POST /webhook/verify
stripe_customer_idtextYESStripe customer ID for billing event correlation
stripe_subscription_idtextYESStripe subscription ID for tier change and cancellation handling
subscription_statustext'active'NOBilling status: active, past_due, or canceled — updated by Lambda receipt handler on Stripe events
monthly_push_countinteger0NONumber of price pushes delivered this month; reset by cron
last_delivered_attimestamptzYESTimestamp of the most recent successful price push
created_attimestamptznow()NOWhen this subscription was created (at checkout)
updated_attimestamptznow()NOLast time this subscription was modified

Indexes

  • webhook_subscriptions_pkey — Primary key on id
  • idx_webhook_subs_api_key_id — Index on api_key_id for fast lookup by API key
  • idx_webhook_subs_status — Index on status for delivery engine active-subscription queries

Foreign Keys

  • api_key_idapi_keys.id (ON DELETE CASCADE)

Check Constraints

  • tier IN ('webhook_starter', 'webhook_standard', 'webhook_professional', 'webhook_enterprise', 'webhook_partner')
  • delivery_method IN ('udp', 'https', 'both')
  • status IN ('pending_verification', 'active', 'suspended')
  • subscription_status IN ('active', 'past_due', 'canceled')
Tier Configuration (from rate_limit_template):
TierIntervalMax AssetsPush Frequency
webhook_starter60s91 push/min
webhook_standard15s304 pushes/min
webhook_professional6s7510 pushes/min
webhook_enterprise3s15020 pushes/min
webhook_partner3s15020 pushes/min

10.2 webhook_delivery_log

Purpose: Webhook delivery attempt log. Every price push — UDP and HTTPS — is logged here with protocol, status, latency, and error details. Used by the GET /webhook/status endpoint to compute 24-hour delivery stats (total, successful, failed, avg latency). High-volume table — one row per delivery attempt per protocol per subscription per interval cycle.

8 columns

ColumnData TypeDefaultNullableDescription
id PKbigserialauto-incrementNOAuto-increment primary key (bigserial for high-volume writes)
webhook_subscription_id FK → webhook_subscriptions.iduuidNOSubscription this delivery belongs to; ON DELETE CASCADE
delivery_idtextNOUnique delivery identifier (format: {sub_id_prefix}-{unix_ms}-{sequence})
protocoltextNODelivery protocol: udp or https
statustextNODelivery outcome: delivered or failed
latency_msbigintNOEnd-to-end delivery latency in milliseconds
error_messagetextYESError details on failure (NULL on success)
delivered_attimestamptznow()NOWhen the delivery attempt was made

Indexes

  • webhook_delivery_log_pkey — Primary key on id
  • idx_wdl_sub_id_delivered — Composite index on (webhook_subscription_id, delivered_at) for 24-hour stats queries
  • idx_wdl_status — Index on status for failure monitoring

Foreign Keys

  • webhook_subscription_idwebhook_subscriptions.id (ON DELETE CASCADE)