Cloning a mvp of sakugabooru but with mainly typescript and good libs
- better style Video (fix tailwind class not working)
- add shortcut keys to navigate to /user /tag /post toggle filters / seek next/previous frame / next/previous post / focus search
- advanced post search filters (server-side numeric filters for dimensions and likes)
- consolidate post schemas and server functions around Effect services
- passkey / TOTP
- github login
- google login
- add test to this login, make it undependant of each service if possible
- google login
- captcha ?
- better auth sentinel?
- auto video duplication finder or vvv
- video duplication vote or vvv
- report video system (low quality, duplicate, ???)
- video duplication vote or vvv
- support manga images share beautiful pannels
- detailed episode informations (when upload, put episode / season info)
- user roles, uploader, verified
- WASM (or not) browser client side image upscaler
- accessibility check
- advance filter (exclude words, post with minimum of likes, width, height)
- ? add post ranking
git clone https://github.com/ozakione/vitesakuga
cd vitesakuga
nub install
cp .env.example .env
# setup infra buckets api tokens etc
nub run infra:deployNub loads and validates the environment with Varlock before running scripts or
Node files. The committed .env.schema documents the stages and required
variables; keep actual credentials in the ignored stage files (.env,
.env.test, or .env.production).
# inspect the resolved, redacted environment
nub exec varlock load --format jsonnub run dev
Three stages, each with its own gitignored env file:
| Stage | Env file | DB / storage | Command |
|---|---|---|---|
| local | .env.test |
Docker Postgres + rustfs | nub run dev:local |
| dev | .env |
Neon dev branch + R2 dev | nub run dev |
| prod | .env.production |
Neon prod + R2 prod | nub run dev:prod |
The DB CLI is stage-aware: STAGE=prod nub run db migrate loads
.env.production (shortcuts: nub run db:local <command>, nub run db:dev <command>, nub run db:prod <command>).
Every stage-specific script follows verb:stage. The unsuffixed script is the
shortcut for its most common stage. Three independent axes are pinned per
script: app stage, APP_ENV (which env file nub loads), NODE_ENV (the
React/bundle runtime), and Vite --mode (bakes import.meta.env.MODE).
| Script | Runs | Stage | APP_ENV / NODE_ENV / env file |
Vite --mode |
|---|---|---|---|---|
dev |
dev server | dev | development / development / .env |
development |
dev:local |
dev server (Docker Postgres + rustfs) | local | test / test / .env.test |
test |
dev:prod |
dev server against prod infra | prod | production / production / .env.production |
production |
build |
production build | prod | production / production / .env.production |
production |
build:dev |
dev-site build (production React runtime + dev-stage .env, decoupled via APP_ENV) |
dev | development / production / .env |
development |
start |
run built Node server | prod | — | — |
server |
preview built Worker (wrangler, generates .dev.vars from .env) |
dev | production |
— |
wrangler:dev / wrangler:preview |
dev / preview through Wrangler Pages | dev | development / .env |
development / — |
db / db:dev / db:local / db:prod |
drizzle-kit CLI (stage via STAGE=) |
dev / local / prod | .env / .env / .env.test / .env.production |
— |
infra:dev |
Alchemy dev | dev (alchemy dev) |
.env |
— |
infra:deploy |
builds (dev) → guard → Alchemy deploy | dev (alchemy dev) |
.env |
— |
infra:deploy:prod |
builds (prod) → guard → Alchemy deploy | prod (alchemy production) |
.env.production |
— |
infra:destroy / infra:destroy:prod |
Alchemy destroy | dev / prod | .env / .env.production |
— |
docker:up / docker:down (aliases dcu / dcd) |
local Docker stack (Postgres, rustfs, lightpanda, otelite) | local | .env.test |
— |
Note: app stages are
local/dev/prod, but Alchemy stages aredev/production— the Alchemy stack derives bucket names (vitesakuga-media-production), domains, and CORS from those exact strings, so the infra scripts keep them. Seedocs/build-environment.mdfor whyAPP_ENV,NODE_ENV, and--modeare set the way they are.
This project uses Alchemy to automate the creation of Cloudflare R2 buckets.
- A Cloudflare Account
- Node.js installed
- Cloudflare Account ID (found on your dashboard)
- Cloudflare API Token with
R2 Editpermissions
Set your Account ID and deploy from the project root:
# Authenticate with Cloudflare
nub exec alchemy login
# Set your Cloudflare Account ID
export CLOUDFLARE_ACCOUNT_ID="YOUR_ACCOUNT_ID"
# Deploy the resources (dev stage keeps the existing vitesakuga-media bucket)
nub run infra:deploy
# Deploy the production bucket (creates vitesakuga-media-production)
nub run infra:deploy:prodFollow the console output from the deploy script to manually update the matching env file (.env for dev, .env.production for prod) with the newly created bucket name and your account ID.
You also need to manually add the S3 API Token from the Cloudflare R2 dashboard to your .env file to set CLOUDFLARE_ACCESS_KEY and CLOUDFLARE_SECRET_KEY:
CLOUDFLARE_ACCESS_KEY="your-access-key"
CLOUDFLARE_SECRET_KEY="your-secret-key"