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.
Build Shopify chargeback evidence packs in minutes: review queue, completeness scoring, immutable audit trail, predictable pricing. Install free from the Shopify App Store.
FinanceTypeScript · JavaScriptGitHub @Johan-JoOnlineOwner 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
DisputeDesk — AI-powered chargeback dispute management platform built with Next.js 15, Supabase, and Tailwind CSS
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Branding note: The name "DisputeDesk" may overlap with disputedesk.co.
Consider using DisputeDesk.app or an alternative for public branding.
This is non-blocking for development.
DisputeDesk is an automation-first Shopify chargeback evidence app.
Connect once, and DisputeDesk handles the rest:Read the full README ↗Branding note: The name "DisputeDesk" may overlap with disputedesk.co. Consider using DisputeDesk.app or an alternative for public branding. This is non-blocking for development.
DisputeDesk is an automation-first Shopify chargeback evidence app. Connect once, and DisputeDesk handles the rest:
Merchants control the automation with per-store settings:
Important: DisputeDesk saves evidence to Shopify — it does NOT programmatically submit dispute responses to card networks.
DisputeDesk ships as two web surfaces from one codebase:
| Surface | URL | Auth | Description |
|---|---|---|---|
| Marketing | / (en), /de, /es, /fr, /pt, /sv | Public | Localized landing (SEO paths; messages use BCP-47 files) |
| Portal Auth | /auth/* | Public | Sign in, sign up, password reset |
| Portal App | /portal/* | Supabase Auth | SaaS web: disputes, packs, settings |
| Internal Admin | /admin/* | Supabase Auth + DB grant | Operator dashboard (shops, jobs, billing, Resources Hub CMS); same login as portal, authorized via internal_admin_grants |
| Embedded App | /app/* | Shopify session | Inside Shopify Admin (Polaris) |
| API | /api/* | Mixed | Backend routes |
/admin) uses the same Supabase credentials as the portal; access is gated by a row in internal_admin_grants (see Internal Admin Panel in docs/technical.md). First grant: npm run add:admin-user -- <email> (user must already exist in auth.users), or insert in SQL; additional operators: Admin → Team while signed in.components/ui/ — Button, Badge, AuthCard, TextField, PasswordField, KPICard, InfoBanner, etc. (CVA + lucide-react)New SQL lives under supabase/migrations/. Any machine or deploy target that uses the app database (local dev, CI, preview, production) must apply pending migrations or the app and cron jobs will fail in inconsistent ways.
AI / Cursor agents: When you add or change migration files, you run npm run db:migrate in this repo in the same session before closing out the task; do not ask the human to apply migrations on your behalf unless the environment truly cannot run the CLI (then use npm run db:migrate:script and document it). See CLAUDE.md (Non-negotiables) and .cursor/rules/supabase-migrations.mdc.
npx supabase) and log in: npx supabase login.npx supabase link --project-ref <your-ref> (password from Supabase dashboard).npm run db:migrate (same as npx supabase db push).npx supabase db push --include-all so it is not skipped.If you cannot use the CLI, use npm run db:migrate:script with direct Postgres credentials (see .env.example).
npx supabase)npx shopify)# 1. Clone and install
cd DisputeDesk
npm install
# 2. Configure environment
cp .env.example .env.local
# Fill in all values (see .env.example for descriptions)
# 3. Apply Supabase migrations (Supabase CLI — same as in docs/technical.md)
npx supabase login # one-time
npx supabase link --project-ref aokhplydttxtebvbeuzc # prod ref; one-time per clone (database password from dashboard). Dev project is vrpkgudqmpyunekrkpnc.
npm run db:migrate # alias for `npx supabase db push`
# Edge case without CLI link: `npm run db:migrate:script` (needs Postgres URI in .env.local — see .env.example)
# 4. Start dev server
npm run dev
# 5. Start Shopify tunnel (separate terminal)
npx shopify app dev
If the browser shows ChunkLoadError or 400 on /_next/static/chunks/... after switching branches or a bad build: stop the dev server, clear .next (or run npm run dev:clean, which removes .next and starts next dev), then open the page again with a hard refresh so HTML matches the new chunk names. See docs/technical.md (Next.js middleware & local dev) for why /_next/* must bypass middleware.
See .env.example for the full list. Key variables:
| Variable | Purpose |
|---|---|
SHOPIFY_API_KEY | App API key from Shopify Partners |
SHOPIFY_API_SECRET | App secret for webhook verification + OAuth |
SHOPIFY_API_VERSION | Pinned GraphQL API version (default: 2026-01) |
SUPABASE_URL | Supabase project URL |
SUPABASE_ANON_KEY | Public anon key (used for portal auth only) |
SUPABASE_SERVICE_ROLE_KEY | Server-only key (never expose to client) |
TOKEN_ENCRYPTION_KEY_V1 | AES-256-GCM key for token encryption (64 hex chars) |
CRON_SECRET | Shared secret for cron → worker endpoint auth |
ADMIN_SMOKE_EMAIL / ADMIN_SMOKE_PASSWORD | Optional — portal user with internal_admin_grants for Puppeteer/smoke scripts and admin E2E (see .env.example) |
read_orders
read_shopify_payments_disputes
write_shopify_payments_dispute_evidences
Saving evidence requires the merchant user to have "Manage orders information" permission in Shopify Admin (Settings → Plan and permissions). This is a Shopify Admin permission, not an OAuth scope.
Troubleshooting "Access denied" on save:
write_shopify_payments_dispute_evidences scope.Troubleshooting blank Embedded Packs page:
Embedded UI vs full-page mocks: Designs that show the entire Shopify Admin (top bar, merchant sidebar, Apps nav) include chrome that Shopify renders. Under /app/*, DisputeDesk controls the iframe body, including EmbeddedAppChrome (brand row + dismissible feedback) in app/(embedded)/app/layout.tsx, then each route’s content. See docs/technical.md (Embedded app troubleshooting) and docs/shopify-app-review-checklist.md (Design vs production).
app/
(marketing)/ → Public landing page (Tailwind)
(auth)/auth/ → Sign in, sign up, forgot/reset password, magic link
(portal)/portal/ → SaaS dashboard, disputes, packs, rules, billing, team
(embedded)/app/ → Shopify Admin embedded UI (Polaris)
(embedded)/app/setup/[step]/ → Setup wizard pages (Polaris)
api/ → Backend routes (auth, webhooks, jobs, packs, disputes)
api/setup/ → Setup wizard state management routes
api/integrations/ → Third-party integration routes (Gorgias, etc.)
api/files/ → Evidence sample file management routes
globals.css → Tailwind imports + design tokens
components/ui/ → Shared design system components
components/setup/ → Setup wizard components (shell, steps, modals, progress ring)
lib/
shopify/ → GraphQL client, throttle, session helpers, queries
supabase/ → Server client, portal auth helpers
portal/ → Active shop cookie + linked shop queries
automation/ → Pipeline, completeness engine, auto-save gate, settings
packs/ → Pack builder orchestrator + source collectors
jobs/ → Job dispatcher + handlers (sync, build, save, render)
disputes/ → Dispute sync service
setup/ → Setup wizard types, constants, event logging
security/ → AES-256-GCM encryption (sessions + integration secrets)
help/ → Help articles, categories, guide configs, analytics
scripts/ → Migration runner + smoke test
supabase/migrations/ → SQL migrations (001–023)
content/policy-templates/ → Markdown policy templates (refund, shipping, terms)
tests/ → Unit tests + API route handler tests + test helpers
docs/ → Architecture, technical spec, epics, roadmap
See docs/architecture.md for the full system
design, two-surface architecture, auth models, async job architecture,
and data flow.
See docs/technical.md for the design system
reference, component catalog, API surface, and CI pipeline.
Published articles at /resources (and localized paths) use a BlogView-style hub UI: Figma Make–aligned hero (same --dd-hero-* gradient + blobs as the marketing home), shared marketing footer, featured slots, topic row with counts, card thumbnails, and a full-width article hero when a featured image is set. In the admin content editor (Metadata), set Featured image URL and Featured image alt (stored on content_items; migration featured_image_alt). URLs may be absolute (https://…, e.g. Supabase Storage) or site paths such as /images/... under public/. Details: docs/technical.md (Resources Hub, code-first hub articles). To assign default Pexels hero images to published articles that still lack a URL, set PEXELS_API_KEY and run npm run backfill:resources-images:dry then npm run backfill:resources-images (service role in .env.local). The script varies images per article (pools per pillar; assignment order follows sorted id within each pillar so the grid cycles through the pool). To overwrite existing URLs (e.g. after expanding the pool), run node scripts/backfill-resources-featured-images.mjs --force.
# Unit + API route handler tests
npx vitest run
# E2E smoke test (requires .env.local with SUPABASE_URL_POSTGRES)
node scripts/smoke-test.mjs
# E2E browser tests (Playwright) — portal Setup Checklist, etc.
npm run test:e2e
E2E tests require E2E_TEST_EMAIL and E2E_TEST_PASSWORD in .env.local. The
test user must have at least one connected shop (via Connect Shopify). Add these
to .env.local:
[email protected]
E2E_TEST_PASSWORD=your-test-password
With the dev server already running (e.g. on port 3001), run:
$env:PLAYWRIGHT_BASE_URL="http://localhost:3001"; npm run test:e2e
Otherwise Playwright will start the app on port 3099 (ensure that port is free).
Tests include:
To create Shopify-backed test data (orders, fulfillments, and real test disputes), follow docs/testing-store-mirror.md. Mirroring means data exists in Shopify first and is synced into Supabase.
To test the pipeline and UI with many dispute rows without creating them in Shopify, use the synthetic dispute seed script. It inserts rows into Supabase only; these disputes do not exist in Shopify and are for UI/dev only.
# Seed 20 synthetic disputes for dev shop (requires SUPABASE_URL_POSTGRES in .env.local)
npm run seed:synthetic-disputes
# Or with options:
node scripts/seed-synthetic-disputes.mjs --shop dev-store.myshopify.com --count 30
node scripts/seed-synthetic-disputes.mjs --shop-id <uuid> --count 20
node scripts/seed-synthetic-disputes.mjs --shop dev-store.myshopify.com --cleanup
Synthetic disputes use dispute_gid like gid://shopify/ShopifyPaymentsDispute/seed-1 and are shown with a Synthetic badge in the app.
To create real test chargebacks in Shopify Payments, use the real-dispute generator. It places orders through storefront checkout using Shopify's disputed-transaction test card; those orders appear in Shopify Payments → Disputes. Requires Shopify Payments in test mode, a product (handle or variant ID), and an Admin API token for tagging. See docs/real-disputes.md for details, options, and limitations.
# One order (requires test-mode ack and SHOPIFY_ADMIN_TOKEN)
npm run seed:real-disputes -- --shop surasvenne.myshopify.com --product-handle my-product --i-know-this-is-test-mode
The script scripts/test-dispute-evidence.mjs verifies against a real Shopify Payments dispute in your dev/test store:
submitEvidence: true and reports whether the dispute moved to submitted.Env vars: SHOPIFY_SHOP_DOMAIN, SHOPIFY_ADMIN_TOKEN; optional SHOPIFY_API_VERSION (default 2026-01).
Run:
# Use first eligible dispute from the store
node scripts/test-dispute-evidence.mjs
# Use a specific dispute (dispute GID, not evidence GID)
node scripts/test-dispute-evidence.mjs --dispute-gid "gid://shopify/ShopifyPaymentsDispute/123456"
Required scopes: read_shopify_payments_disputes, read_shopify_payments_dispute_evidences, write_shopify_payments_dispute_evidences. The merchant user must have Manage orders information in Shopify Admin.
GitHub Actions runs on push/PR to main:
npm audit