# Easy RFP — Social Engine v1.0 (FREE)

**Date:** 2026-05-03
**Cost to run:** €0 — runs entirely on your existing Supabase + Cloudflare + Resend stack.
**Networks supported:** Facebook (Page), Instagram (Business), LinkedIn (Company Page), TikTok (Business)
**Status:** Auto-publish for FB+IG+LinkedIn from day 1. TikTok runs in UPLOAD/reminder mode until TikTok approves `video.publish` scope (4-8 weeks); flips to direct-post automatically after.

This bundle ships the complete plumbing to:

1. Schedule posts for all 4 networks from one admin dashboard
2. Auto-publish on the schedule via a Supabase edge function
3. Pull engagement metrics back daily
4. Attribute every signup → paid customer back to the specific post that drove it

The killer feature is the attribution chain: post slug → click → cookie → signup → Stripe paid event → MRR. No third-party tool sees your Stripe; no SaaS recurring fee; you own the data.

---

## What's in the bundle

```
social-engine-v1.0/
├── README.md                                     ← you are here
├── 04-DEPLOY-CHECKLIST.md                        ← step-by-step deploy guide
├── docs/
│   ├── 00-SETUP-PLAYBOOK.md                      ← create the 4 business accounts properly
│   ├── 01-BRAND-KIT.md                           ← visual identity, post templates, hashtag pools
│   └── 02-UTM-SCHEME.md                          ← attribution params, anti-patterns, queries
├── migrations/
│   └── 66_social_engine_foundation.sql           ← 5 tables + 5 RPCs + 2 views + RLS
├── edge-functions/
│   ├── social-publisher/index.ts                 ← cron-triggered, posts to FB/IG/LI/TT
│   ├── social-metrics-pull/index.ts              ← daily metrics pull
│   └── social-attribute-signup/index.ts          ← Supabase auth hook + Stripe webhook
├── admin-dashboard/
│   ├── index.html                                ← /app/admin/social/
│   ├── calendar.html                             ← /app/admin/social/calendar.html
│   ├── compose.html                              ← /app/admin/social/compose.html
│   ├── analytics.html                            ← /app/admin/social/analytics.html
│   └── utm-track.js                              ← drop in public site <head>
└── content/
    └── 03-CONTENT-CALENDAR.csv                   ← 35 posts EN/ES/DE ready to import
```

---

## How it fits into the Easy RFP stack

```
                  ┌────────────────────────────────────────────┐
                  │  Cloudflare Pages (static site)            │
                  │  - utm-track.js stamps cookies on landing  │
                  │  - signup form passes UTMs to auth.signUp  │
                  └────────────────┬───────────────────────────┘
                                   │
                                   ▼
                  ┌────────────────────────────────────────────┐
                  │  Supabase (existing)                       │
                  │  - auth.users (existing)                   │
                  │  - Mig 66 NEW: social_* tables             │
                  │  - pg_cron: trigger publisher every 5 min  │
                  │  - pg_cron: trigger metrics-pull daily 6am │
                  │  - Auth hook → social-attribute-signup     │
                  └────────────────┬───────────────────────────┘
                                   │ service-role
                                   ▼
                  ┌────────────────────────────────────────────┐
                  │  Edge functions (existing platform)        │
                  │  - social-publisher    ← FB/IG/LI/TT APIs  │
                  │  - social-metrics-pull ← FB/IG/LI/TT APIs  │
                  │  - social-attribute-signup  ← UTM stamp    │
                  └────────────────┬───────────────────────────┘
                                   │
                                   ▼
                  ┌────────────────────────────────────────────┐
                  │  Stripe (existing) → webhook → stamp paid  │
                  └────────────────────────────────────────────┘
```

---

## Deploy in 8 steps (~3 hours total)

See `04-DEPLOY-CHECKLIST.md` for the granular version. High level:

1. **Apply Mig 66** in Supabase SQL Editor (project `jhihwzfikvndybbyaoul`). Smoke test runs at the end of the migration; you'll see a NOTICE if it passed.

2. **Create the 4 business accounts** following `docs/00-SETUP-PLAYBOOK.md`. ~90 min.

3. **Get API tokens** following the same playbook §6. Save as Supabase secrets:
   - `META_GRAPH_PAGE_TOKEN`, `META_FB_PAGE_ID`, `META_IG_BUSINESS_ID`
   - `LINKEDIN_TOKEN`, `LINKEDIN_ORG_URN`
   - `TIKTOK_ACCESS_TOKEN`
   - `RESEND_API_KEY` (you already have this)
   - `SOCIAL_TEST_MODE=true` ← keeps publisher in dry-run until you're ready

4. **Deploy the 3 edge functions** (`supabase functions deploy social-publisher` etc).

5. **Schedule pg_cron** jobs:
   ```sql
   SELECT cron.schedule('social-publisher-tick', '*/5 * * * *',
     $$SELECT net.http_post('https://<project>.functions.supabase.co/social-publisher',
        '{}'::jsonb,
        '{"Authorization":"Bearer <service_role>"}'::jsonb)$$);

   SELECT cron.schedule('social-metrics-pull-daily', '0 6 * * *',
     $$SELECT net.http_post('https://<project>.functions.supabase.co/social-metrics-pull',
        '{}'::jsonb,
        '{"Authorization":"Bearer <service_role>"}'::jsonb)$$);
   ```

6. **Insert your 4 social_accounts rows** in Supabase (one per network) with `publish_enabled=false` initially.

7. **Drop the admin dashboard** into `/app/admin/social/` of your Cloudflare Pages site (4 HTML files + `utm-track.js` to public assets).

8. **Smoke test**: keep `SOCIAL_TEST_MODE=true`, import the CSV, schedule one post for 2 minutes from now, watch the cron pick it up and "publish" (logs only). Verify no errors. Then flip `SOCIAL_TEST_MODE=false` and `publish_enabled=true` per account, schedule a real post, watch it go live.

---

## What this gives you that SaaS tools (Buffer, Metricool, Publer) don't

| Capability | SaaS tools | This engine |
|---|---|---|
| Auto-post FB/IG/LI | ✅ | ✅ |
| TikTok direct-post | ✅ (after their approval) | ✅ (after your TikTok approval) |
| Network engagement metrics | ✅ | ✅ |
| Attribution to signup | ❌ | ✅ |
| **Attribution to PAID customer** | ❌ | ✅ |
| **MRR per post slug** | ❌ | ✅ |
| Recurring cost | $15-50/mo | **€0** |
| Owns the data | ❌ | ✅ |
| GDPR audit trail | partial | full (Supabase EU region) |
| Fits the existing stack | new vendor | extends what you have |

---

## What this v1.0 does NOT yet do (intentional scope cuts)

- **No image generation.** You bring images via Canva or generate elsewhere; the publisher only consumes URLs/storage paths. Auto-generation is a v1.1 feature.
- **No A/B testing.** Each post has one variant. Multi-variant ships in v1.1 once you have baseline data.
- **No comment/DM monitoring.** Replies on FB/IG/LI/TT don't flow back to the engine. v1.2.
- **No Twitter/X support.** Their API is paid + chaotic. Skipped on purpose.
- **No native LinkedIn image upload** (v1.0 LI is text + link preview). LinkedIn's 3-step upload flow is in v1.1.
- **No threaded posts / TikTok carousels.** Single-post per slug.

These are not blockers — the goal of v1.0 is to ship the attribution loop and prove ROI per post. Everything else is incremental.

---

## SOCIAL_TEST_MODE = the kill switch you want

Just like `EMAIL_TEST_MODE` in the outbound engine, `SOCIAL_TEST_MODE` is the master safety toggle.

- Defaults to `true`.
- When `true`, the publisher claims posts but only LOGS what it would have done. No network calls.
- Flip to `false` ONLY when you've smoke-tested every account.
- Each account also has its own `publish_enabled` boolean — flip those one at a time.

---

## Cost projection at scale

| Volume | Supabase cost | Edge fn cost | Storage | Total |
|---|---|---|---|---|
| 10 posts/day, 4 networks | free tier | free tier | <100MB | **€0** |
| 50 posts/day, 4 networks | free tier (500MB DB OK) | free tier (200K invocations) | <500MB | **€0** |
| 200 posts/day, 4 networks | might hit Pro €25/mo | possibly Pro €25 | 2GB → free still | €25-50 |

Even at 200 posts/day across 4 networks, you'd be at €50/mo total — roughly Buffer's price for a single user, with full attribution and zero vendor lock-in.

---

## Next sprints

Once v1.0 is live and you've collected 30 days of data:

- **v1.1** — image generation via Canva API or Bannerbear Free, A/B testing, LinkedIn image uploads, more languages.
- **v1.2** — comment/DM ingest (DM-to-Slack-via-Resend pipeline), reply classification.
- **v1.3** — auto-suggest post times based on per-network audience timezone (you have hotel timezones in `hotels.timezone`; add the same for organizers).
- **v2.0** — content engine that drafts posts from product changelog + recent customer wins via Claude API (when ANTHROPIC_API_KEY is wired).

---

## License & reuse

Internal Easy RFP tool, but the structure is generic. If you ever want to spin this out as a standalone SaaS, the patterns are clean (compare Outbound Engine sprint 2.x for proof — same shape).

Built with the Easy RFP plugin patterns and Supabase + Cloudflare-native conventions. No third-party dependencies beyond the platform APIs themselves.
