The wireframes behind the storefront filter layout decisions lived only in .superpowers/brainstorm/, which is gitignored, so they were lost to anyone reading the repo. That directory stays ignored — it also holds a brainstorming-session token, PID files, and absolute local paths, none of which belong in the repo. The mockups themselves are design artifacts, so they are copied into the specs directory and wrapped as standalone pages: the tool serves them as fragments inside its own frame, so its style tokens and toggleSelect helper are inlined to make them open in a browser with no server and no network. Both rejected layouts and the rejected mobile variant are kept alongside the chosen ones — the comparison is the part worth preserving. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Redefined Designs
One-of-a-kind item storefront. React + TypeScript + antd frontend (Vite), Express + TypeScript backend, Postgres, PayPal checkout, customer accounts with GDPR-style consent handling, and an authentik-gated admin panel.
Project layout
backend/ Express + TypeScript API, Postgres access, PayPal integration frontend/ React + TypeScript + antd storefront and admin UI (Vite)
Prerequisites
- Node.js 20+
- Docker (for a local, disposable Postgres instance)
- npm
Clone
git clone https://gitea.bermudalamb.synology.me/bermudalamb/redefined-designs.git
cd redefined-designs
Running locally
Commands below are shown for PowerShell (Windows). A bash equivalent is noted wherever the syntax differs.
1. Start a local Postgres instance
The backend needs Postgres to talk to during local development. backend/docker-compose.test.yml spins up a throwaway, tmpfs-backed instance — no data persists between restarts, which is fine for local dev and tests.
cd backend
npm run db:test:up
This starts Postgres on localhost:55432, database redefined_test.
2. Run migrations
PowerShell / bash (same command, cross-platform via Node):
cd backend $env:PGHOST="localhost"; $env:PGPORT="55432"; $env:PGUSER="redefined_test"; $env:PGPASSWORD="redefined_test"; $env:PGDATABASE="redefined_test" npm install npm run migrate:up
This applies every migration in backend/migrations/ in order, tracked in a pgmigrations table so re-running is always safe (already-applied migrations are skipped).
To add a new migration:
npm run migrate:create -- descriptive-name
This generates a timestamped file in backend/migrations/ with exports.up/exports.down stubs — fill in pgm.sql(...) for both directions.
3. Configure environment variables
PowerShell:
$env:PGHOST = "localhost"
$env:PGPORT = "55432"
$env:PGUSER = "redefined_test"
$env:PGPASSWORD = "redefined_test"
$env:PGDATABASE = "redefined_test"
$env:PORT = "3000"
$env:DEMO_MODE = "true"
$env:UPLOADS_DIR = "$env:TEMP\redefined-uploads"
New-Item -ItemType Directory -Force -Path $env:UPLOADS_DIR | Out-Null
bash:
export PGHOST=localhost
export PGPORT=55432
export PGUSER=redefined_test
export PGPASSWORD=redefined_test
export PGDATABASE=redefined_test
export PORT=3000
export DEMO_MODE=true
export UPLOADS_DIR=/tmp/redefined-uploads
mkdir -p /tmp/redefined-uploads
DEMO_MODE=true enables a "Buy Now (Demo)" button on the storefront that completes a purchase without needing real PayPal credentials — useful for local development and for the Playwright tests below. To exercise real PayPal checkout locally, also set PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET, and PAYPAL_ENV=sandbox.
Note (PowerShell): environment variables set with $env: only last for the current terminal session/tab. If you close and reopen VS Code's terminal, you'll need to re-run step 3 before starting the backend again.
4. Run the backend
npm install
npm run dev
Runs on http://localhost:3000 with hot reload.
5. Run the frontend
Open a second terminal tab/window (the backend needs to keep running in the first one):
cd frontend
npm install
npm run dev
Runs on http://localhost:5173 and proxies /api, /uploads, /webhooks to the backend on port 3000.
6. Open it
- Storefront: http://localhost:5173
- Admin: http://localhost:5173/admin
Note: locally, /admin is directly reachable with no login gate — the authentik SSO protection only exists in the deployed environment (Nginx Proxy Manager + authentik forward-auth), not in local dev.
Running tests
Backend unit tests
No database required.
cd backend
npm run test:unit
Backend integration tests
Exercises the real Express app against a real (disposable) Postgres instance via supertest.
cd backend
npm run db:test:up
npm run test:integration
npm run db:test:down # when finished
Frontend Playwright e2e tests
Needs the backend running against a database with the schema loaded (steps 1–4 above), since these tests drive real registration/login/purchase flows through a live API.
cd frontend
npm install
npx playwright install --with-deps # first time only — installs browser binaries
npm run test:e2e
CI
Gitea Actions runs two workflows on every push to main and on pull requests:
- SonarQube Analysis (
.gitea/workflows/sonarqube.yml) — static analysis scan, plus TypeScript build checks for bothbackendandfrontend - Tests (
.gitea/workflows/tests.yml) — backend unit tests, backend integration tests (against a disposable Postgres service container), and frontend Playwright e2e tests, each posting a results summary to the job's Summary tab in Gitea Actions
Branching and commits
- All changes go on a branch off
main, namedfeature/<short-description>orfix/<short-description>— never commit directly tomain - Commit messages follow Conventional Commits syntax:
feat:,fix:,chore:,docs:,test:,ci:,refactor:, etc. - Branches are automatically deleted after a pull request is merged
Production deployment
Production runs as a single Docker image (multi-stage build — the frontend is built to static files and served directly by the backend), deployed via Portainer behind Nginx Proxy Manager, with authentik forward-auth gating /admin. That infrastructure is homelab-specific and documented separately outside this repo.
The container applies pending migrations before starting the server, so deployed code can never be ahead of the database schema. A failed migration stops the container rather than letting it serve against a schema it doesn't match — check docker logs on the app container if it doesn't come up.