Open-Source Cold Email & Warmup Platform
Warmbly is the open-source platform for cold email: warm your mailboxes, send campaigns, and triage every reply. Run it on our cloud or self-host the whole thing.
Digital stamp cards for coffee shops, delivered to Apple Wallet and Google Wallet.
MarketingTypeScript · CSSGitHub @prasanthsasikumarOnlineOwner 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
☕ Digital loyalty stamp cards for coffee shops — Apple Wallet & Google Wallet. One poster, one tap, no app.
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Digital loyalty stamp cards for coffee shops — delivered to Apple Wallet and Google Wallet.
Live app → perk.junadesign.co.nz · Watch the 50-second teaserRead the full README ↗Digital loyalty stamp cards for coffee shops — delivered to Apple Wallet and Google Wallet.
Live app → perk.junadesign.co.nz · Watch the 50-second teaser
A shop signs up with a magic link, configures its card (logo, colour, stamps, reward, stamping mode), and gets a URL like perk.junadesign.co.nz/your-shop. Customers open that link, tap once, and the card is in their wallet — no app, no account. Baristas scan the pass to stamp and redeem; passes update live on the customer's phone via APNs and the Google Wallet API. Owners get a dashboard with counters, a customer list with manual adjustments, an activity ledger, and printable counter posters.
Built for a real café in New Zealand — and free for any shop to use. If there's enough interest it stays free and keeps growing.
| Customer landing | Web card | Staff scanner |
|---|---|---|
| Marketing site | Owner dashboard | Printable poster |
|---|---|---|
Next.js 16 (App Router) · React 19 · Tailwind 4 · Drizzle ORM + Postgres (Supabase in prod, @electric-sql/pglite in tests) · Auth.js v5 magic links via Resend · passkit-generator + APNs for Apple Wallet · Google Wallet Objects API · Supabase Storage for logos · Vitest · Playwright.
docs/brand/BRAND_IDENTITY.md — palette, type scale, the mark, and the rules that keep Perk out of a shop's own branding. Tokens live in app/globals.css.docs/superpowers/specs/2026-08-31-perk-v1-design.mddocs/superpowers/plans/2026-08-31-perk-v1.mddocs/manual-testing.mdnpm install
cp .env.example .env # fill in DATABASE_URL at minimum
npm run db:migrate # applies drizzle/ migrations
npm run dev # http://localhost:3000
brew install postgresql@17 && brew services start postgresql@17 && createdb perk). For Supabase use the Transaction pooler URL (port 6543); the client already sets prepare: false.AUTH_RESEND_KEY empty and magic links / card-backup links are printed to the dev server console.WALLET_DRY_RUN=1 locally. Apple routes return the unsigned pass.json, Google/APNs calls are logged instead of sent. The web card works fully.SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY and a public bucket named logos.npm test # Vitest — domain, queries, security, wallet builders (in-memory Postgres via pglite)
npm run typecheck # next typegen && tsc
npm run e2e:seed && npm run e2e # Playwright smoke test against the dev server
pass.app.perk.card) and a certificate for it. Export the cert + private key as PEM; download Apple's WWDR G4 intermediate..p8) — used to tell devices a pass changed.APPLE_PASS_CERT_PEM, APPLE_PASS_KEY_PEM, APPLE_WWDR_PEM, APNS_KEY_PEM. Set APPLE_TEAM_ID, APPLE_PASS_TYPE_ID, APNS_KEY_ID, APNS_TEAM_ID.NEXT_PUBLIC_APP_URL must be public HTTPS — passes embed ${APP_URL}/api/wallet/apple as their web service.GOOGLE_WALLET_ISSUER_ID, GOOGLE_WALLET_SA_EMAIL, GOOGLE_WALLET_SA_KEY_PEM (base64 of the key's private_key field).Import the repo, set every variable from .env.example (unset WALLET_DRY_RUN), and point DATABASE_URL at Supabase's transaction pooler. Run migrations against the production database once. Native modules (sharp, @resvg/resvg-js, passkit-generator) are already marked as server externals in next.config.ts.
app/ routes — (marketing), login, onboarding, dashboard/*, [slug]/{card,scan,staff}, api/*
lib/db Drizzle schema, client, queries (every function takes shopId first)
lib/domain card lifecycle: create / stamp / redeem / adjust — transactional, event-sourced
lib/wallet WalletProvider interface; apple.ts (+ apns.ts), google.ts, strip-image.ts
lib/security HMAC scan tokens, staff cookie signing, DB-backed rate limits, short codes
components/ UI primitives, StampGrid, QR, wallet buttons
drizzle/ SQL migrations · tests/ Vitest · e2e/ Playwright