Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Invoices, payments and reminders for small businesses: Next.js, Microsoft Entra ID/Graph, Stripe, Twilio, AI
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Invoices, payments and reminders for small businesses: a portfolio project by Jason McElvain, built in public one weekend at a time.
Live demo: https://macplussupport-office.vercel.app (sign in with any Microsoft account; you get a private sandbox business with fictional clients)
| Sign in | New invoice | Invoice |
|---|---|---|
| Weekend | Feature | Status |
|---|---|---|
| 1 | Microsoft sign-in (Entra ID, MSAL, PKCE), per-user demo business, race-safe invoice numbers | ✅ |
| 2 | PDF invoices, searchable history, send through Outlook with Microsoft Graph | ⏳ |
| 3 | Stripe "Pay this invoice", webhooks, care-plan subscriptions | ⏳ |
| 4 | Twilio SMS / WhatsApp reminders with delivery status | ⏳ |
| 5 | AI assistant that answers only from the business's own documents | ⏳ |
| 6 | Hardening: rate limits, tests in CI, demo reset | ⏳ |
| 7 | Google Wallet membership pass | ⏳ |
| 8 | Shopify app on a dev store | ⏳ |
Invoice numbers look like INV-2026-0042, restart each year, and must never repeat or skip, even when two people save at the same moment.
The common approach, select max(seq) + 1, fails under load: two requests read the same max and both try to use it. This repo includes a test that fires 50 invoice creations at once:
$ npm run test:race -- 50 --naive
50 concurrent creates (NAIVE max+1) in 1348 ms (pool size 5)
succeeded: 16
failed: 34 ← duplicate key errors
FAIL
$ npm run test:race -- 300
300 concurrent creates (locked counter) in 24805 ms (pool size 5)
succeeded: 300
duplicates: 0
gaps: 0
range: INV-2026-0001 … INV-2026-0300
PASS: every number used exactly once
Real output from a run against Neon Postgres (AWS us-east-1, pooled connection): docs/race-test-output.txt. The locked run is slower because requests deliberately wait their turn for the counter row; correctness, not speed, is the point.
The fix is one statement (src/lib/invoices.ts): an upsert on a per-business, per-year counter row, run in the same transaction as the invoice insert. Postgres locks that row until the transaction commits, so requests take turns, and a failed insert rolls the counter back, so there are no gaps. A unique (business_id, number) constraint backs it up.
@azure/msal-node (no wrapper library), plus a state check against CSRF.User.Read; Mail.Send is requested later through incremental consent, the first time a user sends an invoice./common authority).business_id in the signed session cookie, never by an id from a form or URL. Another business's invoice id returns a plain 404.Next.js 16 (App Router, server actions) · TypeScript · Postgres on Neon · pg · @azure/msal-node · iron-session · zod · Tailwind · Vercel
Prerequisites: Node 20.6+, a free Neon database, and a Microsoft Entra app registration (steps below).
git clone https://github.com/MacSupportPlus/macplussupport-office.git
cd macplussupport-office
npm install
cp .env.example .env.local # then fill in the values
npm run db:migrate
npm run test:race # optional: prove the numbering
npm run dev # http://localhost:3000
http://localhost:3000/api/auth/callback. Add your Vercel URL + /api/auth/callback later.AZURE_CLIENT_SECRET.User.Read (already there by default). No admin consent needed.Personal Microsoft account with no directory? Signing in to Entra fails with "Selected user account does not exist in tenant 'Microsoft Services'". Personal accounts need their own tenant to register apps: create a free Azure account with the same login, which gives you a "Default Directory", then register the app there.
Hosted on Vercel and connected to this repo, so every push to main deploys to production.
.env.example under Vercel → Project → Settings → Environment Variables, with APP_URL set to the production URL. Generate fresh SESSION_SECRET and TOKEN_CACHE_KEY values for production.https://<your-project>.vercel.app/api/auth/callback.APP_URL (for example localhost, not 127.0.0.1), or the sign-in cookie won't match and you'll see "Sign-in expired".INV-<year>-0001 and 0002.0001.npm run test:race -- 50 --naive failing and npm run test:race -- 300 passing..env.local is git-ignored; .env.example documents every variable.MIT