# Phase 3 — Salesforce (per-user OAuth) setup

## A. Create the Salesforce Connected App (you do this once, as SF admin)

1. Salesforce Setup → App Manager → **New Connected App**.
2. Basic info: name it "DataSBJC".
3. Enable **OAuth Settings**:
   - Callback URL: `https://data.matladu.com/data-manager/callback/salesforce`
   - Selected OAuth scopes: **Manage user data via APIs (api)**, **Perform requests at any time (refresh_token, offline_access)**
   - **Require Proof Key for Code Exchange (PKCE)**: enabled
   - **Require Secret for Web Server Flow**: enabled
4. Save. Wait ~10 minutes for Salesforce to propagate.
5. From **Manage Consumer Details**, copy the **Consumer Key** and **Consumer Secret**.

Every DataSBJC user authenticates against THIS one app — they don't create their own.
When a user clicks Connect, they log in with their own Salesforce account and grant
access; Salesforce then enforces exactly what that user can see.

## B. Add credentials to .env

    SALESFORCE_CLIENT_ID=your_consumer_key
    SALESFORCE_CLIENT_SECRET=your_consumer_secret
    SALESFORCE_REDIRECT_URI=https://data.matladu.com/data-manager/callback/salesforce

Then: `php artisan config:cache`

## C. Apply the overlay

    cp -R phase3-salesforce/app/*        ./app/
    cp -R phase3-salesforce/config/*     ./config/
    cp -R phase3-salesforce/database/*   ./database/
    cp -R phase3-salesforce/tests/*      ./tests/

Merge routes/salesforce-web.php into routes/web.php (see its header).

## D. Register the adapter + per-user sync
Follow docs/adapter-registration.md (two small edits to AdapterManager + SyncManager).
Mark Salesforce as user-scoped in the registry seeder / DB:

    App\Integrations\Models\Integration::where('key','salesforce')
        ->update(['connection_scope' => 'user']);

## E. Migrate + build + test

    php artisan migrate --force
    php artisan test --filter=SalesforceOAuth
    node node_modules/vite/bin/vite.js build
    cd /home/voiceagent/public_html && chown -R voiceagent:voiceagent data.matladu.com

## F. Try it
Log in → Data Manager → Salesforce → Connect. You'll be sent to Salesforce to log in
and approve, then bounced back with the connection established. The first sync pulls
only the Leads/Contacts/Accounts/Opportunities THAT user can see.

## Per-user isolation (the B1 guarantee)
- Each user's credential is stored against (organization_id, user_id).
- Each user's synced rows carry user_id; another user in the same org cannot read them.
- Because we query AS the user, Salesforce never returns records they can't see —
  so we physically cannot warehouse data beyond their access.
