sherpa-marketing

●live active dev

Simultaneous Posts to Social Networks for businesses

README

# Sherpa Marketing

Multi-tenant social media publishing platform. Connect social accounts and publish content to Facebook, Instagram, and LinkedIn (TikTok coming soon) — publish now or schedule for later.

## Stack

- **Next.js 15** (App Router, TypeScript, server mode)
- **Tailwind CSS** for styling
- **Prisma + PostgreSQL** for data
- **Redis + BullMQ** for job queue (scheduled & immediate publishing)
- **NextAuth** for authentication (Google OAuth + email magic link)
- **Zod** for validation
- Provider tokens encrypted at rest with AES-256-GCM

## Quick Start (Local Development)

### Prerequisites

- Node.js 18+
- PostgreSQL running locally
- Redis running locally

### Setup

```bash
# Install dependencies
npm install

# Copy env file and fill in values
cp .env.example .env

# Generate Prisma client
npx prisma generate

# Run migrations
npx prisma migrate dev

# Seed database (creates "The Tax Shelter" org + owner user)
npm run seed

# Start dev server
npm run dev

# In a separate terminal, start the worker
npm run worker:dev
```

Visit http://localhost:3000

## NPM Scripts

| Script | Description |
|--------|-------------|
| `dev` | Start Next.js dev server |
| `build` | Build for production |
| `start` | Start production server |
| `worker` | Start BullMQ publish worker |
| `worker:dev` | Start worker with file watching |
| `migrate` | Run Prisma migrations (deploy) |
| `migrate:dev` | Run Prisma migrations (dev) |
| `seed` | Seed database |
| `generate` | Generate Prisma client |

## Deploy to Render

### Option A: Blueprint (recommended)

1. Push this repo to GitHub
2. In Render dashboard, click **New > Blueprint**
3. Connect your repo and select the `render.yaml`
4. Render will create: Web Service, Background Worker, Postgres, Redis
5. **Set these env vars manually** in Render dashboard:
   - `NEXTAUTH_URL` = `https://sherpa-marketing.onrender.com` (your Render URL)
   - `APP_ENCRYPTION_KEY` = generate with: `node -e "console.log(require('crypto').randomByt

…(truncated for upload size)

STATUS

---
type: project-status
project: sherpa-marketing
last_updated: 2026-06-04
---

# STATUS — sherpa-marketing

*The freshest file. Answers "where am I on this project?" Updated at the end of every substantive session.*

---

## Current state

Early MVP, recently picked back up after a ~10-day post-tax-season pause. CC is doing a robustness pass on the existing code (auth, encryption, error handling) ahead of onboarding the first real customer. App is deployed on Render and functional for Facebook, Instagram, and personal-profile LinkedIn posting. Two prospective users now driving the roadmap: Steph (waiting customer) and The Tax Shelter (Ken's own firm, used as the guiding light for prioritization).

## In progress

- [ ] **Phase 1A publishing verification (steps 2–8)** — still outstanding (text/image/video/scheduled posts + worker log scan). Decoupled from 1A.1 on 2026-06-04 (publishing logic unchanged); will be verified organically when Stephanie/OFC connect accounts on the deployed app. No longer gates anything.
- [ ] CC's robustness pass (ongoing scope)
- [ ] Awaiting Steph's confirmation on scope email sent 2026-05-07 (LinkedIn personal vs Company Page; TikTok timeline acceptance; anything else missing)

## Next up

1. **Google Business Profile integration (Phase 1C)** — posts + review reading + review replies. Highest single value-add for a local CPA firm. Build with multi-location support from day one.
3. **LinkedIn Company Page support** — different OAuth scope and posting endpoint than the existing personal-profile flow.
4. **Worker hardening (Phase 1B)** — graceful shutdown, smarter retry classification (don't blanket-retry 4xx the same as 5xx), and fix IG publish to use the Page token instead of the user token (see Known issues). Needed before either Tax Shelter or Steph generates real load.
5. **X (Twitter) posting** — pay-per-use API (~$0.015/post text-only, $0.20/post with URL). Doable with ongoing cost.
6. **TikTok integration (Phase 1D)** — code work 

…(truncated for upload size)

DECISIONS

---
type: project-decisions
project: sherpa-marketing
last_updated: 2026-04-27
---

# DECISIONS — sherpa-marketing

*Architectural and scope choices. Append-only log. Each entry is a decision that shouldn't be re-litigated without new information. If you find yourself reopening a decision, either add a new entry that overrides the old (and say why) or leave both so the history is visible.*

---

## How to use this file

Each decision gets a dated entry with: what was decided, why, what was considered instead, and what would change our mind. Never delete entries — if a decision is reversed, add a new one that supersedes it.

---

## 2026-04-27 — <Short decision title>

**Decision:** <what we chose>

**Context:** <the problem or question that forced a choice>

**Alternatives considered:** <what else was on the table and why we passed>

**Reasoning:** <why this option won>

**Would reconsider if:** <what new information would flip this>

---

## 2026-04-27 — <Short decision title>

**Decision:**

**Context:**

**Alternatives considered:**

**Reasoning:**

**Would reconsider if:**

---

<!-- Append new entries at the top. Older decisions remain below. -->

MEMORY

---
type: project-memory
project: sherpa-marketing
last_updated: 2026-04-27
---

# MEMORY — sherpa-marketing

*Standing facts, preferences, and accumulated context. Long-lived — not "what I did yesterday" (that's STATUS.md). Update when you learn something worth keeping.*

---

## Purpose and scope

<Why this app exists, who uses it, what problem it solves. 2-3 sentences max.>

## Domain knowledge

<Rules of the domain that Claude should know before making changes. For tax apps: the specific IRS rules this module implements, state conformity notes, edge cases. For non-tax apps: business rules, workflows, naming conventions specific to this app's world.>

## User preferences discovered

<Things Ken has said he prefers, or patterns that work / don't work. Example: "Ken prefers server-rendered HTML over SPAs for internal tools." "Don't auto-format tax return numbers with commas on input, only on display.">

## Integrations and external systems

<APIs, webhooks, third-party services this app talks to. Auth patterns, rate limits, quirks.>

## Gotchas and lessons learned

<The things that have bitten us. Non-obvious behavior, debugging dead-ends, environment quirks. Write these when they happen so the next session doesn't repeat the mistake.>

## Data model highlights

<Key tables/models and what's non-obvious about them. Don't duplicate the schema — reference it. Focus on the things you'd warn someone about.>

CLAUDE.md

# Sherpa Marketing - CLAUDE.md

## Project Overview
**Name:** Sherpa Marketing (Social Media Publishing Platform)
**Port:** 3000 (Next.js default)
**Stack:** Next.js 15, React 19, TypeScript, PostgreSQL, Prisma, BullMQ, Redis, Tailwind CSS 4
**GitHub:** https://github.com/klill6506/sherpa-marketing
**Production URL:** Deployed on Render.com
**Status:** In Development (Early MVP)

## What This App Does
A multi-tenant social media publishing platform for scheduling and publishing posts across Facebook, Instagram, LinkedIn, and TikTok. Built for The Tax Shelter to manage firm marketing.

- **Social Account Connection** -- OAuth integration with Meta (Facebook Pages + Instagram Business) and LinkedIn personal profiles
- **Post Composer** -- Write posts with shared captions, hashtags, media uploads (images/video up to 100MB), and per-platform overrides
- **Publish Modes** -- Publish Now, Schedule for later (with timezone), or Save as Draft
- **Background Worker** -- BullMQ processes publish jobs with retry logic (3 attempts, exponential backoff)
- **Dashboard** -- Aggregate stats (total/scheduled/published/failed) and recent post history
- **Multi-Tenant** -- Organizations as the tenant boundary; all data scoped to `orgId`
- **Token Encryption** -- Social account tokens encrypted at rest with AES-256-GCM

## Current State / What I Was Working On
<!-- UPDATE THIS SECTION BEFORE CLOSING CLAUDE CODE -->
**Last session:** [Date]
**Working on:** [Brief description]

### What's Working:
- Google OAuth + email magic link authentication (NextAuth)
- Organization creation and membership
- Meta OAuth (Facebook Pages + Instagram Business) -- fully implemented
- LinkedIn OAuth -- fully implemented
- Post composer with media upload and per-platform toggles
- Publish Now and Schedule modes via BullMQ
- Background publish worker with retry logic
- Dashboard with stats and recent posts
- Post detail page with per-platform attempt history
- Connection management (validate, reconnect, dis

…(truncated for upload size)

Diary mentions

No recent diary mentions for this app.

Render