Skip to content

ChanMeng666/fanfic-lab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

182 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FanFic Lab

AI-Powered Fanfiction Writing Platform

An innovative AI-powered fanfiction writing platform built with Next.js 16 and LangGraph.js.
Create amazing fanfiction with an AI assistant that understands your characters, respects canon, and helps bring your stories to life.
Featuring smart editing, creative wizard, fandom research, and Human-in-the-Loop approval workflows.

Live Demo · Report Bug · Request Feature


Visit FanFic Lab



Share FanFic Lab

Pioneering the future of AI-assisted creative writing. Built for the fanfiction community.


Tech Stack

Important

FanFic Lab combines cutting-edge AI technology with a deep understanding of fanfiction culture. It features LangGraph.js for intelligent agent workflows with Human-in-the-Loop approval, Tavily for fandom research, and a beautiful "Literary Atelier" design system with Teal + Amber color palette.

Table of Contents

TOC

✨ Overview

FanFic Lab is designed for the fanfiction community, providing:

  • Smart Editor - AI-powered writing assistance with inline suggestions
  • Creative Wizard - Conversational story setup with Human-in-the-Loop (HITL) forms
  • Fandom Research - Tavily-powered research for characters, ships, and world-building
  • Fandom Feed - Discover and filter stories by fandom, ships, and tags
  • Character Management - Track characters and detect out-of-character moments
  • Image Gallery - AI-generated character portraits and scene illustrations (coming soon)
graph TB
    subgraph "User Interface"
        A[Homepage] --> B[Creative Wizard]
        A --> C[Smart Editor]
        A --> D[Fandom Feed]
        B --> C
    end

    subgraph "AI Layer"
        E[CopilotKit Provider]
        F[LangGraph Agent]
        G[OpenAI GPT-4o]
        H[Tavily Search]
    end

    subgraph "Backend"
        I[Next.js API Routes]
        J[Prisma ORM]
        K[Neon PostgreSQL]
        L[Redis Cache]
    end

    C --> E
    B --> E
    E --> I
    I --> F
    F --> G
    F --> H
    I --> J
    J --> K
    I --> L
Loading

🚀 Key Features

1 Smart Editor with AI Assistance

Experience next-generation writing with AI-powered inline suggestions. The Smart Editor integrates CopilotKit for real-time assistance, helping you write better fanfiction faster.

Feature Description
CopilotTextarea Inline AI suggestions while typing
Magic Continue AI writes the next 200-300 words naturally
Expand Text Enhance selected text with more dialogue/description/emotion
Polish Prose Improve writing quality at light/medium/deep levels
Autosave Automatic saving with debounce to localStorage
HITL Approval Review and approve/edit AI-generated content

2 Creative Wizard with Fandom Research

Revolutionary story setup wizard that researches your fandom using Tavily API, understands your characters, and generates story outlines for your approval.

Feature Description
Fandom Selector Browse popular fandoms or enter custom
Source Research Tavily-powered research for characters, ships, world-building
Ship Builder Define romantic pairings with AI suggestions
Character Setup Add characters with AI-enhanced profiles
Outline Generation AI creates story outline for HITL approval
Step Progress Visual progress tracking through wizard

3 Character & OOC System

Intelligent character management with out-of-character detection to keep your characters authentic.

Feature Description
Character Sidebar Add/manage characters with personality traits
OOC Detection AI checks for out-of-character moments
Character Profiles Name, fandom, personality, speech patterns
Original Characters Support for OCs with custom definitions
Dialogue Suggestions In-character dialogue generation

4 Fandom Feed

Discover and filter stories by fandom, ships, tags, rating, and status.

Feature Description
Story Cards Display story info with cover images and metadata
Tag Filtering Filter by relationship, setting, tone, content
Fandom Tabs Quick navigation between fandoms
Rating/Status Filters Filter by age rating and completion status
Sorting Sort by recent, popular, comments, word count
Infinite Scroll Load more stories seamlessly

* Additional Features

  • 💨 Quick Setup: Auto-deploy via git push with Coolify on DigitalOcean
  • 🌐 Responsive Design: Beautiful UI on desktop and mobile
  • 🔒 Authentication: Stack Auth for secure user management
  • 💎 Literary Atelier Design: Teal + Amber color palette with elegant typography
  • 🗣️ Real-time AI: Live AI suggestions and generation
  • 📊 Research Cache: Redis caching for Tavily search results (30-day TTL)
  • 🔌 Extensible: Plugin-ready architecture for custom functionality
  • ☁️ Cloud Storage: Cloudinary integration for image hosting

✨ More features are continuously being added as the project evolves.

🛠️ Tech Stack

Next.js
Next.js 16
React
React 19
TypeScript
TypeScript 5
TailwindCSS
TailwindCSS 4
PostgreSQL
PostgreSQL
Redis
Redis
OpenAI
GPT-4o
Layer Technology Deployment
Framework Next.js 16 (App Router, Turbopack) DigitalOcean + Coolify
UI React 19, TailwindCSS 4, shadcn/ui DigitalOcean + Coolify
AI Agent LangGraph.js 1.0 DigitalOcean + Coolify
Reverse Proxy Traefik (via Coolify) DigitalOcean
SSL / CDN Cloudflare (proxy mode) Cloudflare
LLM OpenAI GPT-4o / GPT-4o-mini OpenAI API
Search Tavily API Tavily
Database Neon PostgreSQL + Prisma 7 Neon
Cache Redis (ioredis) Upstash
Auth Stack Auth Stack Auth Cloud
Storage Cloudinary Cloudinary

🏗️ Architecture

System Architecture

Tip

FanFic Lab runs on a DigitalOcean VPS with Coolify (self-hosted PaaS). Both the Next.js frontend and LangGraph agent are deployed as Docker Compose services, communicating via Docker internal networking. Cloudflare provides SSL and CDN.

graph TB
    subgraph "Cloudflare"
        CF[SSL + CDN + DNS]
    end

    subgraph "DigitalOcean VPS (Coolify)"
        T[Traefik Reverse Proxy]
        subgraph "Docker Compose"
            A[Next.js 16 - Web] --> D[API Routes]
            D --> E[Prisma 7]
            F[LangGraph.js 1.0 - Agent] --> G[chat_node]
            F --> H[research_node]
            F --> I[outline_node]
            F --> J[tool_node]
        end
    end

    subgraph "External Services"
        K[OpenAI API]
        L[Tavily API]
        M[LangSmith]
    end

    subgraph "Data Layer"
        N[Neon PostgreSQL]
        O[Redis Cache]
        P[Cloudinary]
    end

    CF -->|HTTP| T
    T --> A
    D -->|Docker Network| F
    G --> K
    H --> L
    F --> M
    E --> N
    D --> O
    D --> P
Loading

Agent Workflow (LangGraph)

The agent uses dedicated graph nodes for HITL operations instead of tools. This is a workaround for the CopilotKit/LangGraph.js ToolMessage format incompatibility.

graph TD
    A[START] --> B{routeFromStart}
    B -->|Research Request| C[research_node]
    B -->|Outline Request| D[outline_node]
    B -->|Default| E[chat_node]

    C --> F[Tavily Search x4]
    F --> G[LLM Aggregation]
    G --> H[Emit State with researchData]
    H --> I[Return AIMessage]

    D --> J[Generate Outline]
    J --> K[Set pendingContent]
    K --> L[Emit State for HITL]
    L --> I

    E --> M{Has Tool Call?}
    M -->|Yes| N[tool_node]
    M -->|No| I

    N --> O[Execute Tool]
    O --> I

    I --> P[END]
Loading

HITL (Human-in-the-Loop) Pattern

sequenceDiagram
    participant U as User
    participant FE as Frontend
    participant CK as CopilotKit
    participant Agent as LangGraph Agent

    Agent->>CK: copilotkitEmitState(pendingContent)
    CK->>FE: State Update
    FE->>FE: useCoAgentStateRender detects pendingContent
    FE->>U: Render Approval Card
    U->>FE: Approve/Edit/Reject
    FE->>CK: respond({ data })
    CK->>Agent: Continue with user input
Loading

🚀 Getting Started

Prerequisites

Important

Ensure you have the following installed:

  • Node.js 20.9.0+ (required by Prisma 7.2.0)
  • npm/yarn/pnpm package manager
  • Git
  • PostgreSQL database (Neon recommended)
  • OpenAI API key

Quick Installation

1. Clone Repository

git clone https://github.com/ChanMeng666/fanfic-lab.git
cd fanfic-lab

2. Install Dependencies

npm install

3. Environment Setup

cp .env.example .env.local
# Edit .env.local with your values

4. Database Setup

# Generate Prisma client
npx prisma generate

# Run database migrations
npx prisma migrate dev

5. Start Development

# Start both Next.js and LangGraph agent
npm run dev:all

🎉 Success! Open http://localhost:3000 to view the application.

Development Commands

npm run dev        # Start Next.js dev server only
npm run dev:agent  # Start LangGraph agent only
npm run dev:all    # Start both services (recommended)
npm run build      # Build for production
npm run start      # Start production server
npm run lint       # Run ESLint

🔐 Environment Variables

Local Development (.env.local)

# Database (Neon PostgreSQL)
DATABASE_URL=postgresql://user:pass@host.neon.tech/fanficlab?sslmode=require

# Stack Auth
STACK_SECRET_SERVER_KEY=ssk_...
NEXT_PUBLIC_STACK_PROJECT_ID=...
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=pck_...

# OpenAI (required for AI features)
OPENAI_API_KEY=sk-...

# LangGraph (local dev: localhost, production: http://agent:8123 via Docker Compose)
LANGGRAPH_URL=http://localhost:8123

# Redis (for research caching)
REDIS_URL=redis://localhost:6379

# Cloudinary (for image hosting)
CLOUDINARY_CLOUD_NAME=...
CLOUDINARY_API_KEY=...
CLOUDINARY_API_SECRET=...

# Optional: Together AI for image generation (currently disabled)
TOGETHER_API_KEY=...

# Optional: LangSmith for tracing
LANGSMITH_API_KEY=lsv2_...

# Optional: Admin endpoint protection
ADMIN_SECRET=...

Production Environment Variables

Variable Description Required
DATABASE_URL Neon PostgreSQL connection string
STACK_SECRET_SERVER_KEY Stack Auth server key
NEXT_PUBLIC_STACK_PROJECT_ID Stack Auth project ID
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY Stack Auth client key
LANGGRAPH_URL Agent URL (http://agent:8123 in Docker Compose)
OPENAI_API_KEY OpenAI API key
REDIS_URL Redis connection string
CLOUDINARY_* Cloudinary credentials
LANGSMITH_API_KEY LangSmith API key 🔶
TAVILY_API_KEY Tavily API key (agent service)
ADMIN_SECRET Admin endpoint protection 🔶

✅ Required, 🔶 Optional

📊 Database Schema

erDiagram
    User ||--o{ Story : writes
    User ||--o{ Character : creates
    User ||--o{ Draft : has
    User ||--|| UserPreferences : configures
    User ||--o{ Follow : follows
    Story ||--o{ Chapter : contains
    Story ||--o{ StoryCharacter : features
    Story ||--o{ Like : receives
    Story ||--o{ Comment : has
    Character ||--o{ StoryCharacter : appears_in
    Story ||--o{ Image : includes

    User {
        string id PK
        string stackAuthId UK
        string email UK
        string username UK
        string displayName
        string avatarUrl
        string bio
    }

    Story {
        string id PK
        string title
        string summary
        string fandom
        string[] ships
        string[] tags
        enum rating
        enum status
        int wordCount
        string coverImageUrl
    }

    Character {
        string id PK
        string name
        string fandom
        string[] personalityTraits
        string speechPatterns
        boolean isOriginal
        string portraitUrl
    }

    SourceResearchCache {
        string id PK
        string sourceName
        string sourceType
        string normalizedName UK
        json researchData
        int searchCount
        datetime lastAccessedAt
    }
Loading

📁 Project Structure

fanfic-lab/
├── src/
│   ├── app/                          # Next.js App Router
│   │   ├── api/                      # API routes
│   │   │   ├── copilotkit/          # CopilotKit runtime
│   │   │   ├── research-cache/      # Redis caching
│   │   │   ├── health/              # Health check
│   │   │   ├── admin/cache-stats/   # Cache analytics
│   │   │   └── upload/cover/        # Cover upload
│   │   ├── (main)/                   # Main routes
│   │   │   ├── (protected)/         # Auth required
│   │   │   │   ├── editor/          # Smart Editor
│   │   │   │   ├── wizard/          # Creative Wizard
│   │   │   │   └── profile/         # User Profile
│   │   │   └── feed/                # Fandom Feed (public)
│   │   └── handler/[...stack]/      # Stack Auth
│   │
│   ├── components/                   # React components
│   │   ├── ui/                      # shadcn/ui components
│   │   ├── editor/                  # Editor components
│   │   ├── wizard/                  # Wizard components
│   │   ├── feed/                    # Feed components
│   │   ├── hitl/                    # HITL approval cards
│   │   ├── layout/                  # Layout components
│   │   └── providers/               # Context providers
│   │
│   ├── agent/                        # LangGraph agent
│   │   ├── agent.ts                 # Workflow definition
│   │   ├── state.ts                 # State annotation
│   │   └── tools/                   # Agent tools
│   │
│   └── lib/                          # Utilities
│       ├── hooks/                   # Custom hooks
│       ├── actions/                 # Server actions
│       ├── types/                   # TypeScript types
│       ├── db.ts                    # Database client
│       ├── redis.ts                 # Redis client
│       └── cloudinary.ts            # Cloudinary client
│
├── prisma/
│   ├── schema.prisma                # Database schema
│   └── migrations/                  # Migrations
│
├── docs/
│   ├── COPILOTKIT_LANGGRAPH_HITL_GUIDE.md
│   └── MIGRATION_RAILWAY_TO_DIGITALOCEAN.md
│
└── public/                          # Static assets

📡 API Reference

POST /api/copilotkit

CopilotKit runtime endpoint that routes requests to the LangGraph agent.

const runtime = new CopilotRuntime({
  agents: {
    fanfic_agent: new LangGraphAgent({
      deploymentUrl: process.env.LANGGRAPH_URL,
      graphId: "fanfic_agent",
    }),
  },
});

GET/POST /api/research-cache

Research results caching endpoint (Redis).

Method Query/Body Description
GET ?sourceName=X&sourceType=Y Check if cached research exists
POST { sourceName, sourceType, researchData } Save research results (30-day TTL)
DELETE ?sourceName=X Clear cache (requires ADMIN_SECRET)

GET /api/health

Service health check endpoint.

{
  "status": "healthy",
  "services": {
    "redis": { "status": "up", "latency": 5 },
    "database": { "status": "up", "latency": 12 }
  }
}

POST /api/upload/cover

Cover image upload endpoint.

  • Validates user authentication and story ownership
  • Accepts: jpeg, png, webp (max 5MB)
  • Uploads to Cloudinary
  • Returns: URL, publicId, dimensions

🛳 Deployment

Cloud Deployment (DigitalOcean + Coolify)

FanFic Lab runs on a DigitalOcean VPS with Coolify (self-hosted PaaS), using Docker Compose for both services. Cloudflare handles SSL and CDN.

Services:

Service Dockerfile Port Health Check
Web (Next.js) Dockerfile.web 3000 /api/health
Agent (LangGraph) Dockerfile.agent 8123 /info

Deployment Compose: docker-compose.coolify.yml

Production URLs

Service URL
Frontend https://fanfic-lab.tech
www (redirect) https://www.fanfic-lab.techhttps://fanfic-lab.tech
Agent (Internal) http://agent:8123 (Docker Compose network)
Coolify Dashboard http://159.223.173.17:8000

Deployment Methods

Method Command
Auto-deploy git push origin master (GitHub webhook → Coolify)
Manual (API) curl -X POST http://159.223.173.17:8000/api/v1/applications/wea94e791gdrn59xv4tqnxdm/restart -H "Authorization: Bearer <token>"
Dashboard Open Coolify → Deploy button

Architecture Diagram

                    ┌──────────────┐
                    │  Cloudflare  │
                    │  SSL + CDN   │
                    └──────┬───────┘
                           │ HTTP
┌──────────────────────────┼────────────────────────┐
│          DigitalOcean VPS (Coolify)                │
│                  ┌───────┴───────┐                 │
│                  │    Traefik    │                 │
│                  │ Reverse Proxy │                 │
│                  └───────┬───────┘                 │
│  ┌───────────────────────┼───────────────────────┐│
│  │            Docker Compose Network             ││
│  │  ┌─────────────────────┐ ┌──────────────────┐ ││
│  │  │    Web Service      │ │  Agent Service   │ ││
│  │  │    (Next.js 16)     │ │  (LangGraph.js)  │ ││
│  │  │                     │ │                  │ ││
│  │  │  • React 19         │ │  • chat_node     │ ││
│  │  │  • Prisma 7         │ │  • research_node │ ││
│  │  │  • Stack Auth       │ │  • outline_node  │ ││
│  │  │  • Port 3000        │ │  • Port 8123     │ ││
│  │  └──────────┬──────────┘ └────────┬─────────┘ ││
│  │             │  http://agent:8123  │           ││
│  │             └─────────────────────┘           ││
│  └───────────────────────────────────────────────┘│
└──────────────────────────┼────────────────────────┘
                           │
         ┌─────────────────┼─────────────────┐
         ▼                 ▼                 ▼
   ┌──────────┐      ┌──────────┐      ┌──────────┐
   │   Neon   │      │  Upstash │      │Cloudinary│
   │PostgreSQL│      │  Redis   │      │  Images  │
   └──────────┘      └──────────┘      └──────────┘

For detailed migration history and Coolify setup guide, see docs/MIGRATION_RAILWAY_TO_DIGITALOCEAN.md.

🤝 Contributing

We welcome contributions! Here's how you can help improve FanFic Lab:

1. Fork & Clone

git clone https://github.com/ChanMeng666/fanfic-lab.git
cd fanfic-lab

2. Create Branch

git checkout -b feature/your-feature-name

3. Make Changes

  • Follow our coding standards in CLAUDE.md
  • Add tests for new features
  • Update documentation as needed

4. Submit PR

  • Provide clear description
  • Reference related issues
  • Ensure CI passes

👥 Team

Chan Meng
Chan Meng

Creator & Lead Developer

🙋‍♀️ Author

Chan Meng

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Open Source Benefits:

  • ✅ Commercial use allowed
  • ✅ Modification allowed
  • ✅ Distribution allowed
  • ✅ Private use allowed

Built with ❤️ for the fanfiction community

AI-powered, community-driven.


⭐ Star us on GitHub — it helps!

About

AI-powered fanfiction writing platform with CopilotKit + LangGraph.js. Features smart editor, creative wizard, fandom research, and HITL workflows. Deployed on Railway.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors