{
  "market": "good-morning-brighton",
  "updated": "2026-06-15",
  "status": "prep_only",
  "launchBoundary": "Private schema only. Do not import real subscriber exports, publish standings, contact reward recipients or send email until Buttondown credentials exist, tests pass and the editor approves launch.",
  "purpose": "Define the private referral ledger needed between Buttondown subscriber exports and any moderated public leaderboard.",
  "storageRules": [
    "Store hashed subscriber identifiers only; never commit raw emails, Buttondown subscriber IDs or private referral tokens.",
    "Keep raw Buttondown exports outside the repo and delete or archive them according to the approved data-handling process after hashing.",
    "Treat the public leaderboard as a derived view containing display name, area tag, verified referral count and tier only.",
    "Document every fraud-control override in moderation_note before a public refresh.",
    "Stop the refresh if consent, unsubscribe status, duplicate handling or local-intent evidence is unclear."
  ],
  "privateColumns": [
    {
      "name": "subscriber_hash",
      "type": "sha256_hex",
      "required": true,
      "source": "Lower-cased subscriber email hashed outside the public website build.",
      "public": false
    },
    {
      "name": "referrer_code",
      "type": "string",
      "required": true,
      "source": "Buttondown metadata captured from ?ref= or localStorage-backed subscribe form.",
      "public": false
    },
    {
      "name": "verified_referral_count",
      "type": "integer",
      "required": true,
      "source": "Manual count after confirmed-subscriber, duplicate and fraud checks.",
      "public": false
    },
    {
      "name": "area_tag",
      "type": "enum",
      "required": true,
      "allowedValues": [
        "Brighton",
        "Hove",
        "Portslade",
        "Rottingdean",
        "Patcham",
        "Other local"
      ],
      "source": "Signup metadata or manual moderation.",
      "public": true
    },
    {
      "name": "first_seen_path",
      "type": "path",
      "required": false,
      "source": "First landing or CTA path seen with the referral code.",
      "public": false
    },
    {
      "name": "last_credited_at",
      "type": "iso8601",
      "required": false,
      "source": "Manual ledger refresh timestamp.",
      "public": false
    },
    {
      "name": "reward_status",
      "type": "enum",
      "required": true,
      "allowedValues": [
        "pending",
        "verified",
        "credited",
        "withheld",
        "sponsor-prize-ready"
      ],
      "source": "Manual moderation outcome.",
      "public": false
    },
    {
      "name": "moderation_note",
      "type": "string",
      "required": true,
      "source": "Reason for credit, hold, withholding or public-display decision.",
      "public": false
    }
  ],
  "publicProjection": [
    {
      "name": "display_name",
      "source": "Reader-provided or manually approved display name only.",
      "rule": "Default to anonymous local reader if no display consent exists."
    },
    {
      "name": "area_tag",
      "source": "Private ledger area_tag.",
      "rule": "Use broad local tags only; never publish street, email domain or exact signup path."
    },
    {
      "name": "verified_referrals",
      "source": "Private ledger verified_referral_count.",
      "rule": "Publish moderated counts only after the editor approves a refresh."
    },
    {
      "name": "current_tier",
      "source": "Reward tier derived from verified_referrals.",
      "rule": "Do not imply prize fulfilment until sponsor terms and approval exist."
    }
  ],
  "sampleRows": [
    {
      "subscriber_hash": "sample_6b8f1a_redacted_hash",
      "referrer_code": "founding-reader-001",
      "verified_referral_count": 5,
      "area_tag": "Hove",
      "first_seen_path": "/share/",
      "last_credited_at": "2026-06-15T18:30:00Z",
      "reward_status": "verified",
      "moderation_note": "Sample row only; no real subscriber data."
    },
    {
      "subscriber_hash": "sample_a91d42_redacted_hash",
      "referrer_code": "brighton-parent-list",
      "verified_referral_count": 2,
      "area_tag": "Brighton",
      "first_seen_path": "/subscribe/",
      "last_credited_at": "2026-06-15T18:30:00Z",
      "reward_status": "pending",
      "moderation_note": "Sample row below public threshold."
    }
  ],
  "refreshChecklist": [
    "Export confirmed Buttondown subscribers to a private working file outside the repo.",
    "Hash emails before creating the ledger and discard raw identifiers from the publish path.",
    "Merge referrer metadata, first-seen path, signup region and confirmation status.",
    "Apply duplicate, self-referral, disposable-domain and local-intent checks.",
    "Generate a public projection that contains no raw private fields.",
    "Run npm run issue:build, npm run website:build and npm run website:check.",
    "Confirm internally before publishing standings, emailing reward recipients or fulfilling prizes."
  ],
  "linearProof": {
    "primary": "MY-2577",
    "related": [
      "MY-2571"
    ],
    "proofNeeded": [
      "schema committed",
      "public page excludes private subscriber fields from leaderboard shell",
      "website check verifies private ledger page and public leaderboard boundary",
      "Buttondown export test once credentials exist"
    ]
  }
}
