AD-Archer/the-anime-stock-market
A play money stock market based app with built in chat features for anime sourced from anilist. Built with appwrite and nextjs
Anime Stock Market
Lightweight Next.js app that simulates anime-themed stock trading with real-time price updates, player portfolios, messaging, and community features.


Key features โจ
- Real-time trading: buy/sell flows, live price updates, market ticker
- Character & anime pages with per-item metadata and Open Graph tags
- Transactions & price history with full activity tracking
- User portfolios, leaderboards, and notifications
- Admin tools: reports, moderation, buyback workflows
- Lightweight analytics integration (Plausible)
Quick start โ Development (recommended)
Requirements:
- Node.js 18+
- pnpm
Get started locally:
# clone and install
git clone https://github.com/AD-Archer/the-anime-stock-market.git
cd the-anime-stock-market
pnpm install
# copy example env and edit .env.local with Appwrite credentials
cp .env.example .env.local
# Required (at minimum):
# NEXT_PUBLIC_APPWRITE_ENDPOINT, NEXT_PUBLIC_APPWRITE_PROJECT_ID
# APPWRITE_API_KEY (server-only, for setup/seed), APPWRITE_DATABASE_ID
# start dev server
pnpm devDeployment
Build & Start
- Build:
pnpm build - Start (production):
pnpm start
Notes:
- Set server-side environment variables (for example,
APPWRITE_API_KEY,APPWRITE_DATABASE_ID) in your production environment; do not commit secrets. - Client-visible env vars (prefixed with
NEXT_PUBLIC_) must be set at build time so they can be inlined into the client bundle.
Analytics (Plausible) ๐
This project includes a lightweight client-side Plausible initializer (components/analytics/plausible-init.tsx). Configure the following env vars in .env.local:
# domain used by Plausible (optional - derived from NEXT_PUBLIC_SITE_URL if not set)
NEXT_PUBLIC_PLAUSIBLE_DOMAIN=www.animestockmarket.tech
# optional Plausible proxy/API host
NEXT_PUBLIC_PLAUSIBLE_API_HOST=https://plausible.adarcher.appNotes:
- The tracker is only loaded on the client. The initializer will derive the Plausible domain from
NEXT_PUBLIC_SITE_URLifNEXT_PUBLIC_PLAUSIBLE_DOMAINis not set. - If you self-host Plausible behind a proxy, set
NEXT_PUBLIC_PLAUSIBLE_API_HOSTto the proxy endpoint. - For local dev, you can set
captureOnLocalhostinside the tracker options if you want to capture events from localhost (not recommended for production).
Adding a Database
When you're ready to add a database, follow the Appwrite setup below or configure your preferred database and provide the necessary environment variables.
Appwrite Database Setup
This app uses Appwrite as the backend database for storing users, stocks, transactions, and other data.
Prerequisites
- An Appwrite instance (cloud or self-hosted)
- Appwrite project created
Authentication Setup
The app now uses Appwrite authentication instead of Stack Auth. Users can sign up and sign in using their email and password.
Database Setup
You can create the database + tables either manually in the Console, or automatically using the included setup script.
Option A: Automatic setup (recommended for dev)
- Create an Appwrite API key in the Appwrite Console (Project Settings โ API Keys).
- Set the env vars:
NEXT_PUBLIC_APPWRITE_ENDPOINTNEXT_PUBLIC_APPWRITE_PROJECT_IDNEXT_PUBLIC_APPWRITE_DATABASE_IDAPPWRITE_API_KEY(server-side only)
- Run:
pnpm appwrite:setup- Then seed:
pnpm seedOption B: Manual setup (Console)
-
Create Database: In your Appwrite console, create a new database with ID
6949af2400329e3595cc(or updateNEXT_PUBLIC_APPWRITE_DATABASE_IDin.env.localif you choose a different name). -
Create Collections: Create the following collections in your database:
-
Create Collections: Create the following collections in your database:
Users Collection
- Collection ID:
users - Permissions: Read:
role:all, Write:role:all(adjust for production) - Attributes:
username(string, required)email(string, required)balance(number, required, default: 1000)isAdmin(boolean, required, default: false)createdAt(string, required)isBanned(boolean, required, default: false)
Stocks Collection
- Collection ID:
stocks - Permissions: Read:
role:all, Write:role:all - Attributes:
characterName(string, required)anime(string, required)currentPrice(number, required)createdBy(string, required)createdAt(string, required)imageUrl(string, required)description(string, required)totalShares(number, required)availableShares(number, required)
Transactions Collection
- Collection ID:
transactions - Permissions: Read:
role:all, Write:role:all - Attributes:
userId(string, required)stockId(string, required)type(string, required) - enum: "buy", "sell"shares(number, required)pricePerShare(number, required)totalAmount(number, required)timestamp(string, required)
Portfolios Collection
- Collection ID:
portfolios - Permissions: Read:
role:all, Write:role:all - Attributes:
userId(string, required)stockId(string, required)shares(number, required)averageBuyPrice(number, required)
Price History Collection
- Collection ID:
price_history - Permissions: Read:
role:all, Write:role:all - Attributes:
stockId(string, required)price(number, required)timestamp(string, required)
Comments Collection
- Collection ID:
comments - Permissions: Read:
role:all, Write:role:all - Attributes:
userId(string, required)animeId(string, required)characterId(string, optional)content(string, required)timestamp(string, required)
Buyback Offers Collection
- Collection ID:
buyback_offers - Permissions: Read:
role:all, Write:role:all - Attributes:
stockId(string, required)offeredPrice(number, required)offeredBy(string, required)targetUsers(string array, optional)expiresAt(string, required)status(string, required) - enum: "active", "expired", "accepted", "declined"acceptedBy(string, optional)acceptedShares(number, optional)
Notifications Collection
- Collection ID:
notifications - Permissions: Read:
role:all, Write:role:all - Attributes:
userId(string, required)type(string, required) - enum: "buyback_offer", "admin_message", "system"title(string, required)message(string, required)data(string, optional) - JSON stringread(boolean, required, default: false)createdAt(string, required)
- Collection ID:
-
Seed Initial Data: After creating all collections, run the seeding script:
pnpm seed
This will populate your database with initial users, stocks, and sample data.
Safety note: Seeding is blocked in production by default. To intentionally run the seeder in production set
CONFIRM_PROD_SEED=truein your environment and re-run the command. By default the seeder will also skip creating users in production unlessALLOW_SEED_USERS_IN_PROD=trueis set. In addition, in production the seeder only allows stocks that include a verified Anilist reference (anilistIdorsource='anilist'); to override this check setALLOW_UNVERIFIED_STOCKS=true. These guards help prevent accidentally adding unverified anime or test users to a live database.
Environment variables
Set your local variables in .env.local. Common variables used by the app:
# client-visible (must be present at build-time)
NEXT_PUBLIC_APPWRITE_ENDPOINT=
NEXT_PUBLIC_APPWRITE_PROJECT_ID=
NEXT_PUBLIC_SITE_URL=
# server-only
APPWRITE_API_KEY=
APPWRITE_DATABASE_ID=
# optional: schema mismatch production alerts
SCHEMA_ALERT_EMAILS=
SCHEMA_HEALTH_ALERTS_ENABLED=true
SCHEMA_ALERT_DEDUPE_HOURS=24Notes:
- Keep server secrets out of source control and secure them in your deployment platform.
NEXT_PUBLIC_variables are inlined at build time and are visible to the client.
Debugging & troubleshooting
- If pages show missing data, verify
.env.localand theNEXT_PUBLIC_*values. - To inspect runtime env presence in dev, enable
ENABLE_ENV_DEBUG=trueand visit/api/_internal/env-check. - If activity counters look out of sync, run the backfill script:
pnpm run backfill:activity- Use
pnpm lintandpnpm run typecheckwhen diagnosing TypeScript or linting issues.
Contributing
- Create an issue for bugs or proposals.
- Open a PR from a feature branch to
main. Include a brief description and test steps. - Run
pnpm lint,pnpm run typecheck, and add tests where appropriate.
License
MIT
If you'd like, I can add a CONTRIBUTING.md with a development checklist or a short troubleshooting snippet for Appwrite CLI commands โ say the word and I'll add it.
