From 163b7bfcdc226d37533d887a58273f14c773ffba Mon Sep 17 00:00:00 2001 From: Ayman Seif Date: Tue, 12 May 2026 23:36:31 +0300 Subject: [PATCH] Merge x-teos-pro into Teos-AI-Engine as pro-extension module --- .env.example | 33 +- .github/workflows/ci.yml | 15 +- README.md | 139 +++-- pro-extension/MIGRATION_NOTES.md | 60 +++ pro-extension/app/dashboard-og.tsx | 615 +++++++++++++++++++++++ pro-extension/app/privacy/page.tsx | 32 ++ pro-extension/app/terms/page.tsx | 15 + pro-extension/components/Providers.tsx | 8 + pro-extension/components/plans.ts | 77 +++ pro-extension/config/next.config.mjs | 6 + pro-extension/config/vercel.json | 5 + pro-extension/config/vercelignore | 5 + pro-extension/docs/AUDIT.md | 30 ++ pro-extension/docs/PRELAUNCH_QA.md | 134 +++++ pro-extension/lib/access.ts | 22 + pro-extension/lib/claude.ts | 28 ++ pro-extension/lib/constants.ts | 4 + pro-extension/lib/origin.ts | 13 + pro-extension/lib/plans.ts | 42 ++ pro-extension/lib/rateLimit.ts | 30 ++ pro-extension/lib/tap.ts | 67 +++ pro-extension/lib/trial.ts | 13 + pro-extension/lib/validation.ts | 10 + pro-extension/proxy.ts | 6 + pro-extension/scripts/git-sync-launch.sh | 35 ++ pro-extension/types/next-auth.d.ts | 30 ++ 26 files changed, 1412 insertions(+), 62 deletions(-) create mode 100644 pro-extension/MIGRATION_NOTES.md create mode 100644 pro-extension/app/dashboard-og.tsx create mode 100644 pro-extension/app/privacy/page.tsx create mode 100644 pro-extension/app/terms/page.tsx create mode 100644 pro-extension/components/Providers.tsx create mode 100644 pro-extension/components/plans.ts create mode 100644 pro-extension/config/next.config.mjs create mode 100644 pro-extension/config/vercel.json create mode 100644 pro-extension/config/vercelignore create mode 100644 pro-extension/docs/AUDIT.md create mode 100644 pro-extension/docs/PRELAUNCH_QA.md create mode 100644 pro-extension/lib/access.ts create mode 100644 pro-extension/lib/claude.ts create mode 100644 pro-extension/lib/constants.ts create mode 100644 pro-extension/lib/origin.ts create mode 100644 pro-extension/lib/plans.ts create mode 100644 pro-extension/lib/rateLimit.ts create mode 100644 pro-extension/lib/tap.ts create mode 100644 pro-extension/lib/trial.ts create mode 100644 pro-extension/lib/validation.ts create mode 100644 pro-extension/proxy.ts create mode 100644 pro-extension/scripts/git-sync-launch.sh create mode 100644 pro-extension/types/next-auth.d.ts diff --git a/.env.example b/.env.example index 726eb93..d91a52d 100644 --- a/.env.example +++ b/.env.example @@ -1,24 +1,38 @@ -# Database +# ────────────────────────────────────────────── +# Teos AI Engine — Unified Environment Config +# Consolidated from Teos-AI-Engine + x-teos-pro +# ────────────────────────────────────────────── + +# ── Database ──────────────────────────────────── DATABASE_URL="postgresql://user:password@localhost:5432/teos?schema=public" -# Session +# ── Session / Auth ────────────────────────────── NEXTAUTH_SECRET="" NEXTAUTH_URL="http://localhost:3000" -# Admin +# Google OAuth (from x-teos-pro) +# GOOGLE_CLIENT_ID="" +# GOOGLE_CLIENT_SECRET="" + +# ── Admin ─────────────────────────────────────── ADMIN_EMAIL="admin@example.com" # ADMIN_EMAILS="admin@example.com,other@example.com" -# AI +# ── AI Providers ──────────────────────────────── +# OpenAI (Teos-AI-Engine) OPENAI_API_KEY="" # OPENAI_MODEL="gpt-4o-mini" # GEMINI_API_KEY="" -# Email (Resend) +# Anthropic / Claude (from x-teos-pro) +# ANTHROPIC_API_KEY="" + +# ── Email (Resend) ────────────────────────────── # RESEND_API_KEY="" # EMAIL_FROM="Teos AI Engine " -# Payments +# ── Payments ──────────────────────────────────── +# Dodo Payments (Teos-AI-Engine) # NEXT_PUBLIC_DODO_PRO_LINK="" # NEXT_PUBLIC_DODO_AGENCY_LINK="" # NEXT_PUBLIC_DODO_LIFETIME_LINK="" @@ -27,5 +41,10 @@ OPENAI_API_KEY="" # NEXT_PUBLIC_PAYPAL_ME="" # DODO_WEBHOOK_SECRET="" -# Founder Login +# Tap Payments (from x-teos-pro) +# TAP_WEBHOOK_SECRET="" +# TAP_PRO_INVOICE_LINK="" +# TAP_AGENCY_INVOICE_LINK="" + +# ── Founder Login ─────────────────────────────── # FOUNDER_SECRET="" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 098f8f3..231663f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: CI - Build Check +name: CI - Build & Deploy on: push: @@ -42,3 +42,16 @@ jobs: NEXTAUTH_URL: "http://localhost:3000" OPENAI_API_KEY: "sk-test-ci" ADMIN_EMAIL: "ci@test.com" + + # Vercel deploy (uncomment and set secrets in GitHub to enable) + # deploy: + # if: github.ref == 'refs/heads/main' && github.event_name == 'push' + # needs: build + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: vercel/action@v34 + # with: + # vercel-token: ${{ secrets.VERCEL_TOKEN }} + # vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} + # vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} diff --git a/README.md b/README.md index 6a9a8b2..79b164c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # 🏺 Teos AI Engine -**AI Content Engine for Builders, Creators, and Agencies** +**AI Content Engine for Builders, Creators, and Agencies** Powered by Elmahrosa International --- @@ -21,22 +21,49 @@ Built for founders, creators, and agencies who want to **automate content creati - ✍️ AI-generated posts (prompt → ready content) - 📊 Daily & lifetime usage tracking -- 🔒 Secure authentication (NextAuth) -- 🧠 Plan-based feature gating +- 🔒 Secure authentication (JWT + NextAuth support in pro-extension) +- 🧠 Plan-based feature gating (Starter / Pro / Agency / Lifetime) - 💾 Persistent database (Prisma + PostgreSQL) - 🛠 Admin dashboard (manual activation + billing control) -- 💳 Payment-ready (Dodo / PayPal / Crypto / Pi) +- 💳 Payment-ready (Dodo, PayPal, Crypto, Pi, Tap) +- 🧩 Pro Extension module for legacy compatibility --- -## 🧠 SaaS Logic (NEW) +## 📦 Repository Structure (Post-Merge) + +This repo consolidates **Teos-AI-Engine** (core) and **x-teos-pro** (legacy MVP). + +``` +Teos-AI-Engine/ +├── app/ # Next.js App Router pages & API routes +├── components/ # Shared React components +├── lib/ # Core library (auth, AI, limits, payments) +├── prisma/ # Schema, migrations, seed +├── public/ # Static assets +├── test/ # Vitest test suite +├── pro-extension/ # x-teos-pro assets (legacy compatibility) +│ ├── lib/ # Legacy lib modules (access, tap, rate-limit, etc.) +│ ├── types/ # NextAuth type extensions +│ ├── components/ # Providers.tsx, plans.ts +│ ├── app/ # Privacy & Terms pages +│ ├── scripts/ # Git sync / dev workflow scripts +│ ├── config/ # Legacy Vercel/Next configs +│ └── docs/ # Audit & QA docs +├── .env.example # Unified env config (all providers) +└── .github/workflows/ # CI + optional Vercel deploy +``` -This version includes a **fully integrated usage engine**: +--- + +## 🧠 SaaS Logic -- Starter → 5 posts lifetime -- Pro → 50 posts/day -- Agency → 200 posts/day -- Lifetime → 100/day (limited offer) +| Plan | Price | Daily Limit | Platforms | +|-----------|-------------|------------------|------------------------------------| +| Starter | Free | 5 posts lifetime | X | +| Pro | $19/mo | 50 posts/day | X, Facebook, Instagram, LinkedIn | +| Agency | $49/mo | 200 posts/day | X, Facebook, Instagram, LinkedIn | +| Lifetime | $149 (once) | 100 posts/day | X, Facebook, Instagram, LinkedIn | Features: - Daily reset system @@ -46,70 +73,76 @@ Features: --- -## 💰 Pricing (Launch Model) - -| Plan | Price | Features | -|----------|------|--------| -| Starter | Free | 5 posts total | -| Pro | $19/mo | 50 posts/day | -| Agency | $49/mo | 200 posts/day + LinkedIn | -| Lifetime | $149 (limited) | 100/day forever | - -🔥 **First 100 users get Lifetime access** - ---- - ## 💳 Payments -Supports: - -- Dodo Payments (primary checkout) -- PayPal (manual approval) -- USDC (Solana) -- Pi Network (discount model) - -Admin dashboard controls: -- Activation -- Plan upgrades -- Billing validation +| Method | Source | +|-----------------|-------------------| +| Dodo Payments | Teos-AI-Engine | +| PayPal | Teos-AI-Engine | +| USDC (Solana) | Teos-AI-Engine | +| Pi Network | Teos-AI-Engine | +| Tap Payments | x-teos-pro (legacy)| --- ## 🧪 Development ```bash +# Install dependencies npm install + +# Generate Prisma client npx prisma generate + +# Run migrations npx prisma migrate dev -npm run dev -- --webpack -```` + +# Start dev server +npm run dev +``` --- ## 🏗️ Architecture -* Next.js 16 (App Router) -* Prisma ORM -* PostgreSQL (Neon recommended) -* NextAuth authentication -* Claude/OpenAI (AI layer) +| Layer | Technology | +|---------------|-------------------------------| +| Framework | Next.js 14 (App Router) | +| Database | PostgreSQL (Neon) + Prisma | +| Auth | JWT (core) / NextAuth (ext) | +| AI Providers | OpenAI, Gemini, Claude | +| Testing | Vitest | +| Styling | Tailwind CSS | +| CI/CD | GitHub Actions | --- -## 🧠 Project Status +## 🔀 Merge History -✅ Core SaaS engine implemented -✅ Usage + billing system integrated -✅ Ready for production testing -🚀 Launch-ready after final payment + UI polish +This repo is the result of consolidating two repositories: ---- +| Repository | Role | Status | +|-----------------|-------------------------|----------| +| Teos-AI-Engine | Primary SaaS engine | Active | +| x-teos-pro | MVP extension layer | Merged → `/pro-extension` | + +**Strategy**: Option B — x-teos-pro rebuilt as a dedicated module (`/pro-extension`) inside Teos-AI-Engine. -## ⚠️ Notes +### What was merged from x-teos-pro: +- **Library modules**: access control, Claude AI client, rate limiting, Tap payments, trial logic, validation schemas, constants, plan config +- **Types**: NextAuth type extensions (`next-auth.d.ts`) +- **Components**: Session Provider wrapper, plan definitions +- **Pages**: Privacy Policy, Terms of Service +- **Scripts**: Git sync/launch workflow +- **Configs**: Vercel deploy config, .vercelignore, legacy next.config +- **Docs**: Audit verdict, pre-launch QA checklist -* This repo is private during stabilization -* Public release will follow after launch validation -* Old version (x-teos-pro) has been deprecated +### What was kept from Teos-AI-Engine (base): +- Full SaaS engine with auth, AI generation, limits, admin dashboard +- Prisma schema, migrations, seed data +- Payment integrations (Dodo, PayPal, Crypto, Pi) +- CI pipeline, test suite +- All existing API routes and pages --- @@ -122,7 +155,5 @@ Vision: Build sovereign AI-powered systems for global scale ## 📜 License -Proprietary – Elmahrosa International +Proprietary — Elmahrosa International Not for redistribution without permission - -```` diff --git a/pro-extension/MIGRATION_NOTES.md b/pro-extension/MIGRATION_NOTES.md new file mode 100644 index 0000000..b0ad0ef --- /dev/null +++ b/pro-extension/MIGRATION_NOTES.md @@ -0,0 +1,60 @@ +# Migration Notes — x-teos-pro → Teos-AI-Engine + +**Date**: 2026-05-12 +**Strategy**: Option B — Dedicated module (`/pro-extension`) + +## What happened + +The `x-teos-pro` repository (124 commits) was rebuilt as a module inside `Teos-AI-Engine` (133 commits). `Teos-AI-Engine` is the primary base; `x-teos-pro` assets live under `/pro-extension/`. + +## File mapping + +| x-teos-pro path | Merged to | +|---|---| +| `lib/access.ts` | `pro-extension/lib/access.ts` | +| `lib/claude.ts` | `pro-extension/lib/claude.ts` | +| `lib/constants.ts` | `pro-extension/lib/constants.ts` | +| `lib/origin.ts` | `pro-extension/lib/origin.ts` | +| `lib/plans.ts` | `pro-extension/lib/plans.ts` | +| `lib/rateLimit.ts` | `pro-extension/lib/rateLimit.ts` | +| `lib/tap.ts` | `pro-extension/lib/tap.ts` | +| `lib/trial.ts` | `pro-extension/lib/trial.ts` | +| `lib/validation.ts` | `pro-extension/lib/validation.ts` | +| `types/next-auth.d.ts` | `pro-extension/types/next-auth.d.ts` | +| `components/Providers.tsx` | `pro-extension/components/Providers.tsx` | +| `components/plans.ts` | `pro-extension/components/plans.ts` | +| `app/privacy/page.tsx` | `pro-extension/app/privacy/page.tsx` | +| `app/terms/page.tsx` | `pro-extension/app/terms/page.tsx` | +| `scripts/git-sync-launch.sh` | `pro-extension/scripts/git-sync-launch.sh` | +| `AUDIT.md` | `pro-extension/docs/AUDIT.md` | +| `PRELAUNCH_QA.md` | `pro-extension/docs/PRELAUNCH_QA.md` | +| `vercel.json` | `pro-extension/config/vercel.json` | +| `.vercelignore` | `pro-extension/config/vercelignore` | +| `next.config.mjs` | `pro-extension/config/next.config.mjs` | +| `page.tsx` (dashboard) | `pro-extension/app/dashboard-og.tsx` | + +## Config alignment + +| Config | Teos-AI-Engine (base) | x-teos-pro (merged) | +|---|---|---| +| TypeScript strict | `true` | `false` (legacy) | +| `allowJs` | `false` | `true` | +| `jsx` | `preserve` | `react-jsx` | +| Next.js version | 14.x | 16.x (legacy config) | +| Test framework | Vitest | None | +| Auth | JWT | NextAuth (legacy) | + +The base `tsconfig.json` already covers `pro-extension/` via `**/*.ts` and `**/*.tsx` globs. + +## Env vars added from x-teos-pro + +- `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` — OAuth +- `ANTHROPIC_API_KEY` — Claude AI +- `TAP_WEBHOOK_SECRET`, `TAP_PRO_INVOICE_LINK`, `TAP_AGENCY_INVOICE_LINK` — Tap Payments + +## Next steps + +1. Migrate any active x-teos-pro deployments to this unified repo +2. Archive the original `x-teos-pro` repo on GitHub +3. Update Vercel project to point to this repo +4. Run `npm install` and verify build diff --git a/pro-extension/app/dashboard-og.tsx b/pro-extension/app/dashboard-og.tsx new file mode 100644 index 0000000..fdfd5a8 --- /dev/null +++ b/pro-extension/app/dashboard-og.tsx @@ -0,0 +1,615 @@ +"use client"; + +import { useSession, signOut } from "next-auth/react"; +import { useState, useEffect, useCallback } from "react"; +import { PLANS, PLATFORM_LABELS, getPlan, trialExpired } from "@/lib/plans"; + +type Platform = "x" | "facebook" | "instagram" | "linkedin"; +type PostStatus = "draft" | "published"; + +interface Post { + id: string; + platform: Platform; + prompt: string; + content: string; + status: PostStatus; + createdAt: string; +} + +const PLATFORM_ICONS: Record = { + x: "𝕏", + facebook: "f", + instagram: "◈", + linkedin: "in", +}; + +const PLATFORM_COLORS: Record = { + x: "bg-black border-gray-700 text-white", + facebook: "bg-[#1877f2]/10 border-[#1877f2]/40 text-[#1877f2]", + instagram: "bg-pink-500/10 border-pink-500/40 text-pink-400", + linkedin: "bg-[#0a66c2]/10 border-[#0a66c2]/40 text-[#0a66c2]", +}; + +const PLATFORM_ACTIVE: Record = { + x: "ring-2 ring-white bg-gray-900", + facebook: "ring-2 ring-[#1877f2] bg-[#1877f2]/20", + instagram: "ring-2 ring-pink-500 bg-pink-500/20", + linkedin: "ring-2 ring-[#0a66c2] bg-[#0a66c2]/20", +}; + +export default function DashboardPage() { + const { data: session } = useSession(); + const [tab, setTab] = useState<"generate" | "saved">("generate"); + + const [platform, setPlatform] = useState("x"); + const [prompt, setPrompt] = useState(""); + const [generated, setGenerated] = useState(""); + const [remaining, setRemaining] = useState(null); + const [generating, setGenerating] = useState(false); + const [genError, setGenError] = useState(""); + const [copied, setCopied] = useState(false); + const [saving, setSaving] = useState(false); + const [saveSuccess, setSaveSuccess] = useState(false); + + const [posts, setPosts] = useState([]); + const [postsLoading, setPostsLoading] = useState(false); + const [filterPlatform, setFilterPlatform] = useState("all"); + const [filterStatus, setFilterStatus] = useState("all"); + + const plan = getPlan(session?.user?.plan ?? "starter"); + const planConfig = PLANS[plan]; + + const trialEnd = session?.user?.trialEndsAt + ? new Date(session.user.trialEndsAt) + : null; + const trialIsExpired = trialExpired(trialEnd); + const trialDaysLeft = trialEnd + ? Math.max(0, Math.ceil((trialEnd.getTime() - Date.now()) / 86400000)) + : null; + + const lockedPlatforms: Platform[] = (["x", "facebook", "instagram", "linkedin"] as Platform[]).filter( + (p) => !planConfig.platforms.includes(p) + ); + + const fetchPosts = useCallback(async () => { + setPostsLoading(true); + const params = new URLSearchParams(); + if (filterPlatform !== "all") params.set("platform", filterPlatform); + if (filterStatus !== "all") params.set("status", filterStatus); + const res = await fetch(`/api/posts?${params}`); + const data = await res.json(); + setPosts(data.posts ?? []); + setPostsLoading(false); + }, [filterPlatform, filterStatus]); + + useEffect(() => { + if (tab === "saved") fetchPosts(); + }, [tab, fetchPosts]); + + async function handleGenerate() { + if (!prompt.trim() || generating) return; + setGenerating(true); + setGenError(""); + setGenerated(""); + setCopied(false); + setSaveSuccess(false); + + try { + const res = await fetch("/api/generate", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ prompt, platform }), + }); + const data = await res.json(); + if (!res.ok) { + setGenError(data.error ?? "Generation failed."); + if (data.limitReached) setRemaining(0); + } else { + setGenerated(data.content); + setRemaining(data.remaining); + } + } catch { + setGenError("Network error. Please try again."); + } finally { + setGenerating(false); + } + } + + async function handleSave() { + if (!generated || saving) return; + setSaving(true); + await fetch("/api/posts", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ platform, prompt, content: generated, status: "draft" }), + }); + setSaving(false); + setSaveSuccess(true); + } + + async function handleCopy() { + await navigator.clipboard.writeText(generated); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + + async function toggleStatus(post: Post) { + const newStatus: PostStatus = post.status === "draft" ? "published" : "draft"; + await fetch(`/api/posts/${post.id}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ status: newStatus }), + }); + setPosts((prev) => + prev.map((p) => (p.id === post.id ? { ...p, status: newStatus } : p)) + ); + } + + async function deletePost(postId: string) { + if (!confirm("Delete this post?")) return; + await fetch(`/api/posts/${postId}`, { method: "DELETE" }); + setPosts((prev) => prev.filter((p) => p.id !== postId)); + } + + return ( +
+ {/* ── Top nav ─────────────────────────────────────────────── */} +
+
+ X‑Teos + + PRO + +
+ +
+ {/* Plan badge */} + + {planConfig.label} plan + + + {/* Admin link — hidden for launch */} + +
+ {session?.user?.image && ( + + )} + +
+
+
+ + {/* ── Trial / upgrade banners ─────────────────────────────── */} + {trialIsExpired && plan === "starter" && ( +
+

+ Your trial has expired. Upgrade to keep generating. +

+ +
+ )} + {!trialIsExpired && trialDaysLeft !== null && trialDaysLeft <= 3 && ( +
+

+ Trial ends in{" "} + {trialDaysLeft === 0 ? "less than 24 hours" : `${trialDaysLeft} day${trialDaysLeft !== 1 ? "s" : ""}`}. +

+ +
+ )} + +
+ {/* ── Tabs ──────────────────────────────────────────────── */} +
+ {(["generate", "saved"] as const).map((t) => ( + + ))} +
+ + {/* ══════════════ GENERATE TAB ══════════════════════════ */} + {tab === "generate" && ( +
+ {/* Platform selector */} +
+ +
+ {(["x", "facebook", "instagram", "linkedin"] as Platform[]).map( + (p) => { + const locked = lockedPlatforms.includes(p); + return ( + + ); + } + )} +
+
+ + {/* Prompt box */} +
+ +