lugbulk-labels-web
Print labels, packing checklists and reports for a LUG's LUGBulk order, straight from the order sheet. In the browser, no install.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Full-stack auction marketplace: proxy bidding serialized per lot, worker settlement, order state machine, outbox notifications, SSE. React, Express, PostgreSQL.
翻譯準備中
正在載入完整 README。
檢視完整 README ↗An online auction site for collectibles: proxy bidding, auctions that close on their own, orders, live prices and notifications. Built with React, Express and PostgreSQL.
Live demo: https://online-auction-1-a3t4.onrender.com (free Render tier, the first load after idle takes about a minute)
API reference: https://online-auction-1-a3t4.onrender.com/api-docs.html (OpenAPI 3.1, try requests against the live API)
Log in as demo_buyer1, demo_buyer2 or demo_seller with password Passw0rd!demo. Open the same lot as two
buyers in two browsers to see proxy bidding and live price updates.
Payments are a manual receipt upload, a mock gateway, or card checkout through Stripe in test mode (card 4242 4242 4242 4242). No real money is involved.
node:test against a real PostgreSQL, Vitest, Playwrightflowchart LR
B[React SPA] -- REST --> A[Express API]
B -- SSE per lot --> A
A -- one transaction per command --> DB[(PostgreSQL)]
W[Worker] -- FOR UPDATE SKIP LOCKED --> DB
DB -- outbox --> W
W --> E[Email and in-app notifications]
PostgreSQL holds everything: state, idempotency keys, the outbox and the audit log. There is no Redis or message broker.
The parts that took the most care:
SELECT ... FOR UPDATE) and checks the deadline against the
database clock after taking the lock. A test fires 50 concurrent bids at one lot and checks the result equals a
serial replay.Idempotency-Key that is stored in the same transaction, so a retried request returns
the original result instead of bidding twice.FOR UPDATE SKIP LOCKED, so several workers can run at
once, and a unique constraint guarantees one order per auction. Tests kill the worker mid-settlement.numeric(15,0) and handled as BigInt, never as floats.On a laptop, 50 bidders on a single lot got p95 549 ms with no errors; spread over 20 lots it reached 146 req/s
(backend/scripts/loadtest.js).
More detail, including the design decisions and the alternatives I rejected: docs/architecture.md. API reference: docs/api.md. Security notes: docs/security.md.
With Docker only:
docker compose up
Open http://localhost:5173 once the api container is healthy. The seed also creates demo_admin (same password)
locally.
Or with Node 22.18+ and Docker for the database:
docker compose up -d db
cd backend
cp .env.example .env
npm ci
npm run db:migrate && npm run db:seed
npm run dev # API on :3000
npm run worker # second terminal
cd ../frontend
cp .env.example .env
npm ci
npm run dev # http://localhost:5173
cd backend && npm run lint && npm run test:unit && npm run test:integration # needs the db container
cd frontend && npm run lint && npm test && npm run build
cd frontend && npx playwright test # needs API, worker and Vite running
Integration tests only run against a database whose name ends in _test.