Oracle3
Open-source trading engine and MCP server for prediction markets. Fee-aware no-arbitrage trading across related contracts, live on Kalshi, Polymarket and Solana or on paper.
Invoices, payments and reminders for small businesses (portfolio demo)
FinanceTypeScript · CSSGitHub @MacSupportPlusOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Invoices, payments and reminders for small businesses: Next.js, Microsoft Entra ID/Graph, Stripe, Twilio, AI
Taken from the repository README
Loading the full README.
Read the full 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