{
  "for_llm": "This page documents the prerequisites of LeadLift's onboarding: the Whop product-name filter in the coded OS and the three Make scenarios the server calls. change_policy: green = the app can write it; amber = a named business rule with a test (change rule + test together, merge through the gate); red = a Make scenario, a route, a setting or a login. Sheni's advice (Loom 3): leave the Make scenarios alone; put 'onboarding' only in the first payment's product name. Facts are as of main e0a8709 (12 Oct 2026).",
  "system": "LeadLift Onboarding",
  "unit": {
    "index": 3,
    "of": 3,
    "node": "Prerequisites: Whop products and Make"
  },
  "platform": "code (Modal) + make.com",
  "code": {
    "repo": "https://github.com/Icarus-Growth/leadlift-os",
    "ref": "main e0a8709",
    "stage": "os/process/ll-onboarding-flow.md",
    "boxes": [
      "2",
      "14"
    ],
    "files": [
      "automations/jobs/onboarding_contract/whop_intake.py (is_onboarding, ONBOARDING_WORD, FIRST_PAYMENT, plan_write)",
      "os/api/whop.py (handle_payment)",
      "tests/onboarding/test_whop_intake.py (TestFilter, TestTheRealMix)",
      "os/api/onboarding_legs.py (drive_leg, after_drive, give_drive_access, drive_access_grants, send_fidel_welcome)",
      "automations/make/onboarding-drive/",
      "automations/make/drive-access/",
      "automations/make/fidel-welcome/"
    ]
  },
  "make_scenarios": [
    {
      "id": 6581813,
      "team": 438268,
      "zone": "us2",
      "name": "STEP 1: Client Paid >> Create Drive Folder",
      "modules": 8,
      "does": "webhook -> create client folder in Fidel's 'Clients' -> Raw Footage, Edited, Lead Sheet, Contract, Brief -> Raw Footage permission {role: writer, type: anyone, allowFileDiscovery: false} -> report ids to callback_url; errors: retry 3x on rate limit/server down, else report blocked or tell /ops/sentry"
    },
    {
      "id": 6585401,
      "team": 438268,
      "zone": "us2",
      "name": "STEP 1C: Drive Folder Made >> Give Edit Access",
      "modules": 4,
      "does": "webhook -> iterate grants -> Drive permissions create (sendNotificationEmail per grant) -> PATCH role when Drive kept another (never owner); each failure tells sentry_url and carries on"
    },
    {
      "id": 6582021,
      "team": 438268,
      "zone": "us2",
      "name": "STEP 1B: Client Channel Created >> Fidel Welcome Message",
      "modules": 3,
      "does": "webhook -> Slack post as Fidel's user connection (chat:write) -> report to callback_url; errors: retry 3x, else report blocked or tell /ops/sentry"
    }
  ],
  "trigger": {
    "type": "every signed Whop event on POST /whop/payment",
    "filter": "event_type == 'payment.succeeded' AND any('onboarding' in t.lower() for t in (product_title, plan_title) if t)",
    "launch_rule": "new client: always launches; existing client matched by payment id: only if never launched; by membership: never (renewal); by Whop user or the one email match: only if billing_reason in {one_time, subscription_create} or missing; '100 - Onboarded' or an onboarding_thread_ts means already launched"
  },
  "reads": [
    {
      "whop": "product.title, plan.title, billing_reason"
    },
    {
      "table": "team",
      "why": "Active members' emails for the Drive grants"
    },
    {
      "table": "clients",
      "why": "email, form_email, google_drive_folder_id, drive_raw_footage_folder_id, drive_lead_sheet_folder_id"
    }
  ],
  "writes": [
    {
      "table": "clients",
      "why": "plan_name (product title), google_drive_folder_id and drive_*_folder_id from Make's callback"
    },
    {
      "drive": "Fidel's 'Clients' folder: one client folder + 5 subfolders, permissions"
    },
    {
      "slack": "Fidel's welcome in the client channel, as Fidel"
    }
  ],
  "notifies": [
    {
      "slack": "client's #onboarding thread via POST /onboarding/leg (Drive folder copied, Fidel welcome message, Client folder access)"
    },
    {
      "slack": "#sentry via /ops/sentry (Make cannot report back; a share fails)"
    }
  ],
  "drive_grants": {
    "source": "os/api/onboarding_legs.py drive_access_grants (Sheni, 11 Oct)",
    "icarusgrowth.com domain": {
      "client_folder": "writer (inherited by all subfolders)"
    },
    "every Active team email": {
      "client_folder": "writer (inherited by all subfolders)"
    },
    "client email + form_email": {
      "client_folder": "reader, notify true",
      "raw_footage": "writer",
      "lead_sheet": "writer",
      "edited_contract_brief": "reader (inherited)"
    },
    "anyone with the link": {
      "raw_footage": "writer (Make 6581813 module 9)"
    }
  },
  "schedules": [],
  "edges": {
    "upstream": [],
    "downstream": [
      {
        "node": "Payment to onboarding started",
        "unit": 1,
        "via": "the product-name filter decides the launch; the three Make scenarios do the Drive leg, the grants and Fidel's welcome"
      },
      {
        "node": "Editing Pipeline (sibling system)",
        "href": "../editing-pipeline/",
        "via": "its footage scenarios also run in the same Make org"
      }
    ]
  },
  "capabilities": [
    "Starts onboarding only for a product or plan title containing 'onboarding' (any case, anywhere in the title)",
    "A renewal or a re-bill of a renamed product never re-onboards a known client",
    "Make makes 6 folders per client and opens Raw Footage to anyone with the link (edit) so clients upload with no Google account",
    "Make shares the client folder per the server's grants and lowers a client who could edit back to view",
    "Make posts Fidel's welcome as Fidel himself"
  ],
  "boundaries": [
    "As of 12 Oct, none of the real Whop products (from the 9 real events, 25 Sep to 8 Oct) has 'onboarding' in its title; tests pin this",
    "The server does not care about price: one product with several prices works; duplicating the product per price is Sheni's advice, not a code requirement",
    "Make decides nothing: the server picks folder names and grants",
    "Grants are sent once when the folder is first reported and once per linked form with a form_email; removing a person from Drive is manual"
  ],
  "change_policy": {
    "green": [
      "team.status / team.email (Team page): Active members get edit on each new client folder"
    ],
    "amber": [
      "ONBOARDING_WORD = 'onboarding' (Sheni, 2026-10-10)",
      "FIRST_PAYMENT = {one_time, subscription_create} (Sheni, 2026-10-10)",
      "drive_access_grants roles + DRIVE_ACCESS_DOMAIN (Sheni, 2026-10-11)"
    ],
    "red": [
      "Make scenarios 6581813 / 6585401 / 6582021",
      "Raw Footage permission in 6581813 module 9 (writer -> reader would stop client uploads)",
      "MAKE_HOOK_DRIVE_FOLDER / MAKE_HOOK_DRIVE_ACCESS / MAKE_HOOK_FIDEL_WELCOME",
      "the 'Clients' parent folder in Fidel's My Drive",
      "Make connections: Fidel's Google Drive connection (expires 11 Apr 2027), Fidel's Slack (user) connection",
      "route.whop_payment_webhook + WHOP_WEBHOOK_SECRET",
      "ONBOARDING_LEG_SECRET (Modal, form worker, Make)"
    ]
  },
  "known_issues": [
    "No real product says 'onboarding' yet; the first real onboarding needs a renamed or new product in Whop (Fidel is the Whop admin)",
    "ONBOARDING_LEG_SECRET is in the webhook body, so it shows in Make's run log for 30 days",
    "A person who leaves keeps Drive access to folders already shared by name",
    "Make Core plan: 10,000 operations a month; past the limit every scenario stops until the reset on the 25th",
    "Loom 3 says the team won't be able to read the backend code: wrong as built; LeadLift receives the repo at handover"
  ],
  "recovery": {
    "git": "every change is a commit on main, merged through the gate",
    "rollback": "modal app rollback leadlift-os",
    "blueprint_backup": [
      "backups/bp_6581813.json",
      "backups/bp_6585401.json",
      "backups/bp_6582021.json"
    ]
  }
}