https://github.com/notsoocool/worktowords
✍️ Turn daily work into posts with AI (Clerk auth + Supabase history + settings).
https://github.com/notsoocool/worktowords
clerk linkedin nextjs openai react saas shadcn-ui supabase tailwindcss typescript
Last synced: 20 days ago
JSON representation
✍️ Turn daily work into posts with AI (Clerk auth + Supabase history + settings).
- Host: GitHub
- URL: https://github.com/notsoocool/worktowords
- Owner: notsoocool
- License: mit
- Created: 2026-04-13T12:27:29.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-05-19T19:04:39.000Z (about 2 months ago)
- Last Synced: 2026-05-19T22:07:35.836Z (about 2 months ago)
- Topics: clerk, linkedin, nextjs, openai, react, saas, shadcn-ui, supabase, tailwindcss, typescript
- Language: TypeScript
- Homepage: https://worktowords.in
- Size: 1.5 MB
- Stars: 2
- Watchers: 0
- Forks: 4
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# ✍️ WorktoWords
Turn your daily work into **social-ready content** — LinkedIn posts, Instagram captions, and YouTube scripts — fast, clean, and on-brand.
## ✨ Features
- 🔐 **Auth** with [Clerk](https://clerk.com) (Google sign-in supported)
- 🧠 **AI generation** via OpenAI — **Help Me Write** and **Write For Me** modes
- 📱 **Multi-platform output** — LinkedIn, Instagram, and YouTube (select one or more per run)
- 🎯 **Goals** — `job` · `growth` · `authority` (per post or default in settings)
- 💳 **Pro upgrade** via Razorpay (₹149 / 30 days, UPI-friendly checkout)
- 📅 **Pro expiry** — auto-downgrades to Free after 30 days
- 📊 **Usage limits**
- Free: **5** generations/day
- Pro: **100** generations/day
- 🧾 **History** — saved posts, filter by goal, reopen on the dashboard
- ⚙️ **Settings** — default goal + tone (`casual` · `professional` · `storytelling`)
- 🎛️ **Regenerate** — per-platform refresh; adjust length, tone, technical level, storytelling
- 🔔 **Live toasts** during generation
- 🌓 **Light / dark** theme
## 🧰 Tech Stack
- **Next.js 16** (App Router) + **TypeScript**
- **Tailwind CSS** + **shadcn/ui**
- **Clerk** — authentication
- **Supabase Postgres** — posts, settings, usage, subscriptions
- **OpenAI** — content generation
- **Razorpay** — payments
## ✅ Prerequisites
- **Node.js 20+**
- **pnpm 9+**
## 🚀 Getting Started
```bash
git clone https://github.com/notsoocool/worktowords.git
cd worktowords
pnpm install
```
Create `.env.local`:
```bash
# Clerk
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
# OpenAI
OPENAI_API_KEY=
# Supabase (server routes use the service role key)
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Razorpay — use test keys locally
NEXT_PUBLIC_RAZORPAY_KEY_ID=
RAZORPAY_KEY_ID=
RAZORPAY_KEY_SECRET=
```
Optional:
```bash
# Bypass daily limits for admin/testing (comma-separated Clerk user IDs)
ROOT_USER_ID=
# ROOT_USER_IDS=
# Custom Clerk domains (production)
# NEXT_PUBLIC_CLERK_FRONTEND_API=
# NEXT_PUBLIC_CLERK_ACCOUNTS_ORIGIN=
```
### Database
In the [Supabase](https://supabase.com) SQL editor, run the full schema:
```text
supabase/posts.sql
```
This creates tables, indexes, RLS policies, and `check_and_increment_usage()` (required for generation limits).
### Run locally
```bash
pnpm dev
```
Open [http://localhost:3000](http://localhost:3000).
### Scripts
| Command | Description |
|---------|-------------|
| `pnpm dev` | Development server |
| `pnpm build` | Production build |
| `pnpm start` | Run production build |
| `pnpm lint` | ESLint |
| `pnpm typecheck` | TypeScript (`tsc --noEmit`) |
## 🗄️ Database (Supabase)
| Table | Purpose |
|-------|---------|
| `posts` | Generated content (`content`, `hashtags`, `goal`, `type`, `linkedin`, `instagram`, `youtube`) |
| `user_settings` | Default goal + writing tone |
| `user_usage` | Daily usage, plan, expiry |
| `user_subscriptions` | Razorpay order/payment refs, plan status |
**Function:** `check_and_increment_usage(user_id)` — atomic daily limit check + Pro expiry downgrade.
## 🔌 API Routes
| Method | Route | Description |
|--------|-------|-------------|
| `GET` | `/api/health` | Liveness check |
| `POST` | `/api/generate` | Generate + save post(s) |
| `GET` | `/api/posts` | List history (`?goal=` optional) |
| `GET` | `/api/posts/[id]` | Single post |
| `GET` | `/api/settings` | User settings |
| `PATCH` | `/api/settings` | Update settings |
| `GET` | `/api/usage` | Remaining generations + plan |
| `POST` | `/api/razorpay/create-order` | Create Pro order (₹149) |
| `POST` | `/api/razorpay/verify` | Verify payment + activate Pro |
## 💳 Razorpay (Standard Checkout)
Flow ([Razorpay docs](https://razorpay.com/docs/payments/payment-gateway/web-integration/standard/integration-steps/)):
1. **Server** — `POST /api/razorpay/create-order` creates an order (14900 paise, INR) and stores a pending row in `user_subscriptions`.
2. **Client** — Opens Checkout with `key`, `order_id`, `amount`, `currency`, `prefill`.
3. **Success** — Client receives `razorpay_payment_id`, `razorpay_order_id`, `razorpay_signature`.
4. **Server** — `POST /api/razorpay/verify` validates the signature and upgrades the user to Pro for 30 days.
Use **test** keys in development; **live** keys in production. Enable **automatic capture** for orders in the Razorpay Dashboard.
## 🚢 Deployment
Set the same environment variables on your host (e.g. Vercel). **Required for core features:**
- Clerk keys
- `OPENAI_API_KEY`
- `NEXT_PUBLIC_SUPABASE_URL` + `SUPABASE_SERVICE_ROLE_KEY` (usage, posts, payments)
- Razorpay keys
After deploy:
1. Confirm `supabase/posts.sql` has been applied to your production project.
2. Hit `GET /api/health` to confirm the app is up.
3. Run a test generation and (optionally) a Razorpay test checkout.
## 🤝 Contributing
We welcome contributions — especially for [open issues](https://github.com/notsoocool/worktowords/issues).
- Read **[CONTRIBUTING.md](./CONTRIBUTING.md)** for setup, conventions, and PR expectations.
- Every PR runs **lint**, **typecheck**, and **build** in GitHub Actions.
- Comment on an issue before starting large changes.
## 📁 Project layout
```text
app/ Pages and API routes
components/ UI (dashboard, history, settings, …)
lib/services/ Business logic (generate, payments, usage, posts)
lib/ai/ Platform-specific AI prompts (LinkedIn, Instagram, YouTube)
supabase/ SQL schema
proxy.ts Auth (Clerk) + security headers
```
## 🧪 Notes
- Secrets live in `.env.local` (gitignored).
- `/dashboard`, `/history`, and `/settings` require sign-in (Clerk).
- Server-side Supabase access uses the **service role** key — never expose it to the client.
## 📄 License
MIT