{
  "id": "get_postback_report",
  "mcp_tool": "get_postback_report",
  "status": "approved",
  "source_system": "cake",
  "environment": ["staging", "prod"],
  "sharded": true,
  "shard_schema": "lucos_ro_cake",
  "shard_view_prefix": "lucos_ro_postback",
  "connections": {
    "shorty": "cake_shorty_ro",
    "admin": "cake_admin_ro"
  },
  "objects": [
    "lucos_ro_cake.lucos_ro_postback_*",
    "Admin.lucos_ro_campaign_directory",
    "Admin.lucos_ro_affiliate_directory",
    "Admin.lucos_ro_hidden_channel_publishers"
  ],
  "parameters": {
    "publisher_id": { "type": "int", "required": false },
    "campaign_id": { "type": "int", "required": false },
    "date_from": { "type": "date", "required": false },
    "date_to": { "type": "date", "required": false }
  },
  "constraints": {
    "max_window_days": 7,
    "default_window_days": 1,
    "max_rows": 2000,
    "timeout_ms": 60000
  },
  "allow_fields": [
    "shard_date",
    "event_time",
    "campaign_id",
    "campaign_name",
    "adv_id",
    "adv_name",
    "publisher_id",
    "affiliate_name",
    "ip_prefix",
    "postback_url",
    "postback_url_redactions",
    "query_param_count"
  ],
  "deny_fields": [
    "postback_url_base",
    "ip",
    "token",
    "sig",
    "secret",
    "payout",
    "clickid",
    "txid",
    "rev_share"
  ],
  "post_processing": [
    "Redact postback_url_base per docs/CAKE-POSTBACK-URL-REDACTION-RULES.md §5, then drop the base column.",
    "Exclude publishers listed in Admin.lucos_ro_hidden_channel_publishers. Cross-instance, so the id list is fetched from Admin and bound into the Shorty query.",
    "Enrich campaign_id to advertiser via Admin.lucos_ro_campaign_directory, replacing the per-row N+1 at getAdvertiserInfoFromCampaignId line 504."
  ],
  "notes": "The only row-grain tool in the P5 set, hence the tightest window (7 days) and row cap (2000) — docs/CAKE-SHARD-AND-DATE-RANGE-RULES.md §3. postback_url_base is on deny_fields even though the query selects it: the redactor consumes it and the field policy then asserts it is gone, so a refactor that let the pre-redaction value reach the response builder fails instead of leaking."
}
