Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .dev.vars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Direct Postgres connection, used by `next dev`/`next build` and as the
# Hyperdrive local connection in `wrangler dev`
DATABASE_URL=postgres://user:pass@pgbouncer-host:6432/left4craft
CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE=postgres://user:pass@pgbouncer-host:6432/left4craft

# better-auth
BETTER_AUTH_SECRET=generate-with-openssl-rand-base64-32

# Discord OAuth (same app as before; callback path is unchanged:
# /api/auth/callback/discord — but add preview/localhost origins in Discord dev portal)
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=

# Stripe (use test keys locally)
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
NEXT_PUBLIC_STRIPE_KEY=

# SES (IAM user scoped to ses:SendEmail only)
SES_ACCESS_KEY_ID=
SES_SECRET_ACCESS_KEY=
SES_REGION=us-east-1
EMAIL_FROM="Left4Craft <noreply@left4craft.org>"

NEXT_PUBLIC_URL=http://localhost:3000
Binary file removed .env.gpg
Binary file not shown.
28 changes: 0 additions & 28 deletions .env.template

This file was deleted.

198 changes: 0 additions & 198 deletions .eslintrc.js

This file was deleted.

28 changes: 13 additions & 15 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: Lint

on:
# Trigger the workflow on push or pull request
push:
branches:
- '*'
Expand All @@ -10,30 +9,29 @@ on:
- '*'

jobs:
run-linters:
name: Run linters and build project
lint-and-build:
name: Lint and build project
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: 23
node-version: 22
cache: npm

# ESLint and Prettier must be in `package.json`
- name: Install Node.js dependencies
run: npm install
run: npm ci

- name: Run linters
uses: wearerequired/lint-action@v1
with:
eslint: true
- name: Run Biome
run: npx biome ci .

# DATABASE_URL lets the punishments pages pre-render at build time.
# If it is unavailable the pages build empty and ISR fills them in at runtime.
- name: Build project
env:
LITEBANS_API: ${{ secrets.LITEBANS_API }}
LITEBANS_API_KEY: ${{ secrets.LITEBANS_API_KEY }}
run: npm run build
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: npm run build
14 changes: 8 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ yarn-error.log*
# vercel
.vercel

# serverless files
/.serverless/
/.serverless_nextjs/

# aws environment setup stript
aws.sh
# cloudflare
/.open-next/
/.wrangler/
.dev.vars

# one-off local artifacts from the AWS -> Cloudflare migration
zone.json
left4craft.org.zone

56 changes: 33 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
# left4web

## Getting Started
The [left4craft.org](https://www.left4craft.org) website: [Next.js](https://nextjs.org/) (pages router), deployed to
**Cloudflare Workers** via [OpenNext](https://opennext.js.org/cloudflare).

First, run the development server:
## Architecture

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
- **Hosting**: Cloudflare Workers (`@opennextjs/cloudflare` + `wrangler`). ISR pages (`/shop`, `/punishments/*`)
are cached in the `left4web-inc-cache` R2 bucket.
- **Database**: PlanetScale Postgres, reached through pgbouncer via a **Hyperdrive** binding. Holds
better-auth tables, Stripe customer/trial/event tables, the `job_queue` table, and the LiteBans data.
- **Auth**: [better-auth](https://better-auth.com) — Discord OAuth + email magic links (sent with SES v2 over
HTTP via `aws4fetch`). Routes live under `/api/auth/*`.
- **Shop**: Stripe Checkout. The webhook (`/api/stripe/webhook`) records events idempotently in
`stripe_events` and enqueues rank commands into `job_queue`, which the Left4Hub plugin polls with
`FOR UPDATE SKIP LOCKED`.
- **Punishments**: LiteBans tables queried directly (`utils/litebans.js`); `/api/punishments/check`
serves the client-side ban search.

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Development

## Learn More
```bash
cp .dev.vars.example .dev.vars # fill in secrets
npm install
npm run dev # next dev with wrangler's local binding proxy
```

To learn more about Next.js, take a look at the following resources:
`next build` needs `DATABASE_URL`, `STRIPE_SECRET_KEY`, and `NEXT_PUBLIC_*` set to fully pre-render;
without them the ISR pages build empty and self-heal at runtime.

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
## Deploy

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
```bash
npm run preview # build + run the real worker locally
npm run deploy # build + deploy to Cloudflare
```

## Deploy on Vercel
One-time setup: create the R2 bucket (`npx wrangler r2 bucket create left4web-inc-cache`), apply
`migrations/*.sql` to Postgres, and set secrets with `npx wrangler secret put` (see `.dev.vars.example`
for the list).

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
## Linting

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
[Biome](https://biomejs.dev) handles linting and formatting: `npm run lint` / `npm run lint:fix`.
Loading
Loading