lugbulk-labels-web
LUGBulk 주문서에서 라벨·포장 체크리스트·보고서를 브라우저에서 바로 인쇄, 설치 필요 없음
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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.