193 lines
8.6 KiB
Markdown
193 lines
8.6 KiB
Markdown
# CoopCredits ($COOP) — Hoboken Chicken Media Rewards
|
||
|
||
A jokey barnyard-themed rewards system for the Hoboken Chicken family and friends. Watch stuff on Plex, earn $COOP credits, request new media through Overseer. Buy extra credits via Ko-fi when the silo runs low.
|
||
|
||
> **Theme:** Everything is chickens, eggs, coops, and corn. Comic Sans / Chalkboard font, thick borders, earthy palette.
|
||
|
||
## Architecture
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
│ coop.hobokenchicken.com │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ Next.js │ │ Express │ │ PostgreSQL │ │
|
||
│ │ Frontend │◄─┤ API │◄─┤ Database │ │
|
||
│ │ (3000) │ │ (3002) │ │ (5432) │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
│ ▲ ▲ ▲ │
|
||
│ │ │ │ │
|
||
│ Plex OAuth Tautulli Webhooks Ko-fi Webhooks │
|
||
│ │ │ │ │
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ Plex Server │ │ Tautulli │ │ Ko-fi │ │
|
||
│ │172.20.1.220 │ │172.20.1.255 │ │ (Payments) │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
│ │
|
||
│ ┌──────────────┐ │
|
||
│ │ Overseer │ (Requests & disk space for dynamic pricing) │
|
||
│ │172.20.1.225 │ │
|
||
│ └──────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Key Features
|
||
|
||
- **Plex OAuth Login** — No passwords, just Plex auth
|
||
- **Watch-to-Earn** — Tautulli webhooks credit $COOP for watched content (30-day backfill on signup)
|
||
- **Request-to-Spend** — Request movies/shows through Overseer, pay $COOP
|
||
- **Dynamic Pricing** — Request costs rise as disk space fills (scarcity multiplier)
|
||
- **TV Episode Tiers** — Long-running shows cost more per episode count
|
||
- **Ko-fi Purchases** — Buy $COOP with real money via Ko-fi store items
|
||
- **Admin Dashboard** — Manage users, view donations, sync request statuses, adjust barn rules
|
||
- **Barnyard Theme** — "Peck for Feed", "Join the Flock", thick borders, earthy palette
|
||
|
||
## Quick Start
|
||
|
||
```bash
|
||
# 1. Clone
|
||
git clone <repository> coop-credits
|
||
cd coop-credits
|
||
|
||
# 2. Install dependencies
|
||
npm run install:all
|
||
|
||
# 3. Configure environment
|
||
cp .env.example .env
|
||
# Edit .env with your API keys (Plex, Tautulli, Overseer, Ko-fi)
|
||
|
||
# 4. Start services
|
||
docker-compose up -d --build
|
||
|
||
# 5. Initialize database (first time only)
|
||
docker exec coop-backend npx prisma db push --accept-data-loss
|
||
|
||
# 6. Configure Caddy (see docs/CADDY-CONFIG.md)
|
||
```
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
coop-credits/
|
||
├── backend/ # Express API server (port 3002)
|
||
│ ├── src/
|
||
│ │ ├── routes/ # API routes (auth, users, wallet, overseer, admin, webhooks)
|
||
│ │ ├── services/ # Tautulli backfill, socket handlers
|
||
│ │ ├── middleware/ # Auth, rate limiting, error handling
|
||
│ │ └── utils/ # Prisma client
|
||
│ └── prisma/
|
||
│ └── schema.prisma # DB schema (User, Transaction, WatchEvent, ContentRequest, KofiPayment, etc.)
|
||
├── frontend/ # Next.js 16 dashboard (port 3000)
|
||
│ └── src/
|
||
│ ├── app/
|
||
│ │ ├── page.tsx # Landing page ("Enter the Coop")
|
||
│ │ ├── login/page.tsx # Plex OAuth login
|
||
│ │ ├── dashboard/page.tsx # User dashboard
|
||
│ │ ├── admin/page.tsx # Admin panel
|
||
│ │ └── dashboard/components/ # WatchHistory, RequestHistory, SearchRequestModal, BuyCreditsModal, etc.
|
||
│ └── lib/
|
||
│ ├── api.ts # API client
|
||
│ ├── store.ts # Zustand auth store
|
||
│ └── socket.ts # Socket.io connection
|
||
├── docs/ # Documentation
|
||
│ ├── CADDY-CONFIG.md # Reverse proxy setup
|
||
│ ├── INFRASTRUCTURE.md # Network architecture
|
||
│ ├── SETUP-INFRASTRUCTURE.md
|
||
│ └── TROUBLESHOOTING.md
|
||
├── docker-compose.yml # Docker orchestration
|
||
└── .env.example # Environment template
|
||
```
|
||
|
||
## User Flow
|
||
|
||
1. **Login** → Visit coop.hobokenchicken.com, click "Join the Flock", authenticate with Plex
|
||
2. **Auto-Backfill** → First login triggers 30-day Tautulli history import (DB-only credits)
|
||
3. **Watch** → Viewing on Plex → Tautulli webhook → $COOP credited to DB balance
|
||
4. **Earn** → Real-time balance updates via Socket.io on dashboard
|
||
5. **Spend** → "Peck for Feed" → Search → Request content → $COOP deducted immediately
|
||
6. **Buy More** → "Buy Feed" → Ko-fi store → Credits auto-delivered via webhook
|
||
|
||
## Admin Features
|
||
|
||
Access `/admin` with an admin account:
|
||
- **The Flock** — User list with search, reward bonuses, manual backfill, promote/demote admins
|
||
- **Barn Rules** — Edit credits per minute, min watch %/minutes, movie/TV costs
|
||
- **Donations** — View all incoming Ko-fi payments with status (CREDITED / UNCLAIMED)
|
||
- **The Feed Queue** — All content requests across users, manual Overseer sync button
|
||
- **Egg Stats** — Analytics cards: flock size, total $COOP, total requests, pending count
|
||
|
||
## Environment Variables
|
||
|
||
See `.env.example` for full configuration. Key vars:
|
||
|
||
```env
|
||
# Database
|
||
DATABASE_URL="postgresql://coop:password@localhost:5432/coop_credits?schema=public"
|
||
|
||
# Server
|
||
PORT=3002
|
||
API_URL=https://coop.hobokenchicken.com
|
||
|
||
# JWT (generate: openssl rand -hex 32)
|
||
JWT_SECRET="..."
|
||
|
||
# Plex OAuth
|
||
PLEX_CLIENT_ID="..."
|
||
PLEX_CLIENT_SECRET="..."
|
||
PLEX_REDIRECT_URI=https://coop.hobokenchicken.com/auth/callback
|
||
|
||
# Tautulli (host network mode required)
|
||
TAUTULLI_URL=http://172.20.1.255:8181
|
||
TAUTULLI_API_KEY="..."
|
||
|
||
# Overseer (host network mode required)
|
||
OVERSEER_URL=http://172.20.1.225:5055
|
||
OVERSEER_API_KEY="..."
|
||
|
||
# Ko-fi
|
||
KOFI_VERIFICATION_TOKEN="..."
|
||
|
||
# Security
|
||
ENCRYPTION_KEY="..." # openssl rand -base64 32
|
||
```
|
||
|
||
## Dynamic Pricing
|
||
|
||
Request costs are adjusted by disk scarcity:
|
||
- **Multiplier** = `1 + (usedPercent × 2)`
|
||
- At 0% disk used → 1× base cost
|
||
- At 50% disk used → 2× base cost
|
||
- At 90% disk used → 2.8× base cost
|
||
|
||
TV shows also have episode tier multipliers on top of scarcity:
|
||
- ≤50 episodes → base
|
||
- 51-100 → 1.3×
|
||
- 101-200 → 1.6×
|
||
- 201-400 → 2.0×
|
||
- 400+ → 2.5×
|
||
|
||
## Theme
|
||
|
||
- **Primary:** Terracotta (`#C06F4A`)
|
||
- **Secondary:** Duck Egg Blue (`#D4E4E0`)
|
||
- **Accent:** Wheat (`#E8D5B5`)
|
||
- **Muted:** Feather Grey (`#C4B5AA`)
|
||
- **Font:** Comic Sans MS / Chalkboard SE (fallback system-ui)
|
||
- **Style:** Thick 4px borders, hard black box shadows, rounded-3xl corners
|
||
|
||
## Tech Stack
|
||
|
||
| Layer | Technology |
|
||
|-------|-----------|
|
||
| Frontend | Next.js 16, React 19, TypeScript, Tailwind CSS, shadcn/ui, Zustand |
|
||
| Backend | Express.js, TypeScript, Prisma ORM, Socket.io |
|
||
| Database | PostgreSQL 16 |
|
||
| Cache | Redis 7 (sessions, Socket.io adapter) |
|
||
| Auth | Plex OAuth 2.0 + JWT |
|
||
| Payments | Ko-fi webhooks |
|
||
| Deployment | Docker Compose, Caddy reverse proxy |
|
||
|
||
## License
|
||
|
||
Private — Hoboken Chicken family use only.
|