# 🚀 Vibn Marketing Attribution & Identity Sync SDK

A modular, highly scalable, and decoupled SDK package to link anonymous site traffic tracking (**Umami Analytics**) with registered user profiles (**Vibn Database**), providing comprehensive **First-Touch Marketing Attribution** and acquisition logs.

Developed originally for **Missinglettr** and structured specifically to be drop-in ready for the **Vibn Platform** architecture.

---

## 📁 Package Inventory

This package contains three decoupled layers designed to be copied directly into your respective repositories:

| Path | Purpose | Language / Framework |
| :--- | :--- | :--- |
| `frontend/VibnTracker.tsx` | Client-side search params listener, sessionStorage / Cookie persistence, automated Umami injection, and session identity bridging (`identify()`). | TypeScript / Next.js React |
| `backend/models.py` | Abstract Base Django Model adding UTM and Referrer fields to any User / Client record. | Python / Django |
| `backend/mixins.py` | Django REST Framework (DRF) interceptor mixin to auto-capture attribution variables from incoming signup payloads. | Python / Django REST Framework |
| `umami-bridge/umami_service.py` | Reusable bridge to pull aggregated pageviews, session timestamps, and raw click-trails from Umami (via REST API or raw DB joins). | Python / Django |

---

## 🏛️ Architecture Overview

The system bridges anonymous traffic with database records using a secure **Identity Exchange**:

```
[Anonymous Visitor Clicks Ad / Tweet]
              │
              ▼
[Lands on Website with UTMs & Referrer]
              │  ├── Auto-logged in Umami (analytics.vibnai.com)
              │  └── Cached client-side in sessionStorage & Cookie fallback
              ▼
[Signs Up / Logs in via Google OAuth]
              │
              ▼
[Frontend POSTs Signup payload + UTM params to Backend]
              │
              ▼
[Django Backend saves user record + permanently binds UTM columns]
              │
              ▼
[Frontend calls useVibnTracker.identify(user_id)]
              │
              ▼
[Umami merges ALL previous anonymous browsing history with this new User ID!]
```

---

## 💻 Step-by-Step Implementation Guide

### 1. Frontend Integration (Vibn Next.js Web App)

Copy `frontend/VibnTracker.tsx` into your Next.js project (e.g., inside `components/metrics/VibnTracker.tsx`):

#### A. Wrap your Root Layout:
In `app/layout.tsx` (or your entry file), wrap the tree with `VibnTrackerProvider`. This will automatically inject your Umami tracking script and listen for UTM parameters across your landing and console domains:

```tsx
import { VibnTrackerProvider } from "@/components/metrics/VibnTracker";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <VibnTrackerProvider 
        umamiWebsiteId="your-umami-website-uuid" 
        umamiScriptUrl="https://analytics.vibnai.com/script.js"
      >
        <body>{children}</body>
      </VibnTrackerProvider>
    </html>
  );
}
```

#### B. Capture & Send on Signup / Google OAuth exchange:
In your signup or Google OAuth exchange page (where the user completes registration), extract the cached attribution parameters using the `useVibnTracker` hook and send them in the request body to your backend:

```tsx
import { useVibnTracker } from "@/components/metrics/VibnTracker";

export default function GoogleCallbackPage() {
  const { getStoredAttribution, identify, track } = useVibnTracker();

  const handleOAuthSignup = async (googleToken: string) => {
    // 1. Get first-touch parameters cached in browser
    const attribution = getStoredAttribution();

    // 2. POST to your register endpoint
    const response = await fetch("/api/auth/register", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        google_token: googleToken,
        ...attribution // Sends utm_source, utm_medium, utm_campaign, referrer, etc.
      })
    });

    if (response.ok) {
      const user = await response.json();

      // 3. BRIDGING IDENTITY: Link anonymous browser history with real user ID!
      identify({
        userId: user.id, // Primary key in your database
        email: user.email,
        name: user.name,
        plan: user.plan
      });

      // 4. Track custom sign-up conversion in Umami
      track("user_completed_signup", { plan: user.plan });
    }
  };
  
  // ...
}
```

---

### 2. Backend Integration (Vibn Django API)

Copy `backend/models.py` and `backend/mixins.py` into your Django apps.

#### A. Inherit from the Abstract Model:
Add first-touch marketing attribution columns to your active User or APIClient model by inheriting from `VibnAbstractAttributionModel`:

```python
# your_app/models.py
from backend.models import VibnAbstractAttributionModel

class UserProfile(VibnAbstractAttributionModel):
    # Your existing fields
    email = models.EmailField(unique=True)
    name = models.CharField(max_length=255)
    
    class Meta:
        db_table = "user_profile"
```

Then generate and apply your database migrations:
```bash
python manage.py makemigrations
python manage.py migrate
```

#### B. Intercept requests with the DRF View Mixin:
Add the `VibnAttributionCaptureMixin` to your Signup or Authentication API ViewSet. It will automatically intercept, extract, and write the UTM parameters into the saving model:

```python
# your_app/views.py
from rest_framework import viewsets
from backend.mixins import VibnAttributionCaptureMixin
from .models import UserProfile
from .serializers import UserProfileSerializer

class RegisterViewSet(VibnAttributionCaptureMixin, viewsets.ModelViewSet):
    """
    User registration API view. 
    VibnAttributionCaptureMixin automatically grabs utm_source, utm_campaign,
    and Referrer headers from requests and binds them onto the UserProfile on save.
    """
    queryset = UserProfile.objects.all()
    serializer_class = UserProfileSerializer
```

---

### 3. Expose Live Traffic Trails in Admin Consoles

Copy `umami-bridge/umami_service.py` into your Python services.

You can securely query stats directly from your Umami self-hosted database (read-only) inside your Admin panels, allowing you to render **actual pageviews, device breakdowns, and exact visitor session timelines** for any specific client.

#### A. Configure Umami DB Connection:
In Django's `settings.py`, register your Umami database:

```python
DATABASES = {
    'default': {
        # Your main application DB
    },
    'umami_db': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'umami_production_db',
        'USER': 'readonly_user',
        'PASSWORD': 'password',
        'HOST': '34.19.250.135',
        'PORT': '5432',
    }
}
```

#### B. Fetch Live Session Data for Admin Console:
In your Admin API view (e.g. `admin_user_detail`), call the service to fetch raw click-trails:

```python
# your_admin_app/views.py
from rest_framework.response import Response
from umami_bridge.umami_service import VibnUmamiService

def get_admin_user_profile(request, user_id):
    # Initialize service
    umami = VibnUmamiService()
    
    # 1. Fetch total web sessions, total pageviews, and first interaction timestamp
    funnel = umami.get_aggregated_funnel_for_user(user_id, db_connection_name="umami_db")
    
    # 2. Fetch the actual 50 most recent page clicks, devices, and browsers used by this client!
    click_trail = umami.get_user_session_click_trail(user_id, db_connection_name="umami_db")
    
    return Response({
        "user_id": user_id,
        "first_touch_web_funnel": funnel,
        "live_click_trail": click_trail
    })
```

---

## 🛡️ Best Practices & GDPR Compliance

1. **Self-Hosted Privacy:** Because Umami is hosted on your domain (`analytics.vibnai.com`), cookie and script blockades are minimized, and no data is shared with third parties (complying strictly with GDPR, CCPA, and PECR).
2. **First-Touch Preservation:** The mixin uses `if not client.utm_source:` checks on save, ensuring first-touch parameters (the exact ad or link that *originally* brought the user in) are preserved and never overwritten by subsequent organic logins.
3. **No Database Blockades:** The `umami_service.py` uses read-only connections and limits queries to `LIMIT 50` to make sure raw analytics querying never causes performance blocks on your main application database thread.
