# Platform integration review (PostSync Pro)

Reviewed against code under `src/lib/social/` and OAuth routes. Credentials are OAuth **app** secrets in env; publish tokens are per-project Connected Accounts.

| Platform | Code Status | API Integration | Posting | ENV Config | Account / Profile | Page / Org / Channel | Notes |
| -------- | ----------- | --------------- | ------- | ---------- | ----------------- | -------------------- | ----- |
| Facebook | Complete | Meta Graph Page APIs | Text + image | `FACEBOOK_ENABLED` + Meta app id/secret | **Not supported** (Meta API) | **Page** via OAuth | Working path: `facebook-publish.ts` |
| Instagram | Complete | Meta IG Content Publish | Image (+ caption) | `INSTAGRAM_ENABLED` + Meta app | N/A | IG Business linked to Page | Same Meta OAuth as Facebook |
| LinkedIn | Complete (member) | UGC Posts API | Text + image | `LINKEDIN_ENABLED` + client id/secret | **Member** via OAuth | Organization **not implemented** | Needs `w_organization_social` for Company Pages |
| YouTube | Complete (video) | YouTube Data API upload | Video only | `YOUTUBE_ENABLED` + Google OAuth | N/A | **Channel** | Requires `VIDEO_PROVIDER=ffmpeg` + MP4 |
| Threads | Complete | Threads Graph API | Text + image | `THREADS_ENABLED` + Threads/Meta app | **Profile** | N/A | Default off; public image URL for photos |
| Pinterest | Complete | Pinterest API v5 | Image pin | `PINTEREST_ENABLED` | N/A | **Board** | Image required |
| TikTok | Complete (inbox) | Content Posting API | Video | `TIKTOK_ENABLED` | **Profile** | N/A | Blocked in IN by default; may require finish-in-app |
| X / Twitter | Not implemented | — | — | `TWITTER_ENABLED` (default false) | — | — | No provider; enable flag alone does nothing |

## Integration status summary

| Status | Platforms |
| ------ | --------- |
| Fully working (with OAuth + connected account) | Facebook Page, Instagram Business, LinkedIn member, YouTube channel (with video), Threads, Pinterest, TikTok (inbox upload) |
| Requires credentials | Any of the above when `*_ENABLED=true` but app secrets missing → `missing_credentials` |
| Disabled via env | Any when `{PLATFORM}_ENABLED=false` or `SOCIAL_MEDIA_ENABLED=false` |
| Country blocked | e.g. TikTok when project countries include `IN` (overridable) |
| API limitation | Facebook personal profile; LinkedIn organization pages |
| Not implemented | Twitter/X |

## Architecture gates

- Config: `src/lib/social/config/social-config.ts`
- Publish hub: `src/lib/social/publish-post.ts` (skips disabled platforms; no API call)
- OAuth connect: LinkedIn / Meta / YouTube connect routes return 403 + `code`/`action` when blocked
- UI: Connected Accounts loads `/api/social/platforms-status`

See also: [04-ENV-CONFIGURATION.md](./04-ENV-CONFIGURATION.md), [02-FACEBOOK.md](./02-FACEBOOK.md), [03-LINKEDIN.md](./03-LINKEDIN.md).

## Agent-side test results (2026-09-01)

Command: `npm run test:social-config` → **24/24 passed**.

| Scenario | Result |
| -------- | ------ |
| Platform disabled (`FACEBOOK_ENABLED=false`) | `disabled`, `PLATFORM_DISABLED`, no publish |
| Enabled without credentials | `missing_credentials`, `MISSING_CREDENTIALS`, publish blocked |
| Valid OAuth app credentials (FB/IG/LI/YT) | `enabled`, publish allowed |
| Global kill-switch (`SOCIAL_MEDIA_ENABLED=false`) | All platforms blocked |
| Destinations | FB=`page`; LI=`profile` only; Twitter stays `not_implemented` |
| Legacy `FACEBOOK_CLIENT_*` aliases | Accepted |

Live network posting (Facebook Page / LinkedIn member) was **not** executed in this pass — no app UI session and tests intentionally avoid calling Meta/LinkedIn with project tokens. Those paths remain the existing `facebook-publish.ts` / `linkedin-publish.ts` implementations, gated by the env layer above.

`npm run typecheck` — passed after config comment fix.
