# Ads Platform — Alignment with Aihub

**Everything is modules.** Same app, same auth, same hubs pattern — no split systems.

---

## Modules (not separate products)

| Module slug | Purpose | Unlock |
|-------------|---------|--------|
| `ads` | Ads hub (watch + post tabs) | Visible in Hubs when `modules.status = enabled` |
| Watch & earn | Tab inside Ads hub | `unlock_rules`: `subscription` → Ads plan |
| Post ads | Tab inside Ads hub | `ad_profiles.status = approved` for `user_id` |

Only **one** row in `modules` table: `slug = 'ads'`. Watch vs post are **tabs**, not separate hub cards.

Compare to:

- **Forex** — one hub, tabs: Terminal, Academy, Signals  
- **Casino** — one hub, game lobby inside  
- **Surveys** — one hub, list + detail  

---

## Auth

| Role | Implementation |
|------|----------------|
| Member (watch + post) | `requireAuth('user')` only |
| Admin | `requireAuth('admin')` only |

**Removed from plan:** `advertiser_login`, `user_type = 'advertiser'`, `api/advertiser.php`, `advertiser-portal.js`.

---

## Hub UI integration

| File | Change |
|------|--------|
| `assets/hub-ui.js` | `HUB_COVERS.ads`, `hubOpen('ads')`, `rUAds()` |
| `index.php` | `#us-ads` screen, back bar to Hubs |
| `assets/ads/ads-hub.js` | Tabs: Watch, Post, My Campaigns, My Earnings |
| `assets/hubs/ads-cover.svg` | Hub card image |

```javascript
// hub-ui.js — same as forex, casino
else if (slug === 'ads') uGo('ads');
```

---

## Subscriptions (watch gate)

- Extend `subscription_plans.plan_type` with `'ads'`
- Reuse `userApi('subscribe')`, `userApi('my_subscription')`
- `requireModuleAccess($db, $userId, 'ads')` on `feed`, `start`, `complete` actions

```php
// api/ads.php — earn actions only
requireModuleAccess($db, $uid, 'ads');
```

Post actions check `ad_profiles` instead of subscription:

```php
// api/ads.php — post actions
requireApprovedAdProfile($db, $uid);
```

---

## Wallets & balance

| Action | Pattern |
|--------|---------|
| Viewer reward | `creditWallet($db, $uid, 'main', $amount, 'income', ...)` |
| Fund campaign | Debit `users.balance` in transaction when campaign submitted |
| History | `transactions` type `Ad Reward` / `Ad Campaign Fund` |
| Notify | `notify()` on reward, profile approved, campaign approved |

No `advertiser_accounts.balance` — use existing user balance + campaign `budget_total` / `budget_spent`.

---

## API surface (single file)

**`api/ads.php`** — all member actions:

| Action | Gate |
|--------|------|
| `feed`, `detail`, `start`, `complete`, `my_earnings` | user + Ads subscription |
| `profile_get`, `profile_save` | user |
| `campaigns`, `campaign_create`, `campaign_submit` | user + approved profile |
| `my_campaigns` | user |

Admin stays in `api/includes/admin_extensions.php`.

---

## Admin panel

One sidebar item **Ads** (like Surveys, Casino):

- Profiles pending approval  
- Campaigns pending approval  
- Economics settings  
- Dashboard stats  

No separate “advertiser admin”.

---

## File layout

```
migrations/031-ads-platform.sql
api/ads.php
config/ads_service.php
assets/ads/ads-hub.js
assets/hubs/ads-cover.svg
docs/ads/
```

**Not building:** `api/advertiser.php`, `advertiser-portal.js`, `advertisers` login table.

---

## Database (simplified)

```
ad_profiles        user_id → users.id
ad_campaigns       user_id → users.id
ad_views           user_id → users.id, campaign_id
```

Deposits for ad funding: reuse `deposits` with note `AD-BUDGET` or direct balance debit — no `advertiser_deposits` table.

---

## Settings keys

```
ads_platform_fee_pct
ads_default_cpv
ads_image_min_seconds
ads_video_min_percent
ads_daily_earn_cap
ads_max_completions_per_day
ads_min_campaign_budget
```

---

## Engagement hooks (optional later)

- Mission: “Watch 5 ads today”  
- Leaderboard: top earners this week  
- VIP: higher daily cap  

All via existing `engagement_service.php` — still one user account.
