01 What Partner Nook is
A Shopify affiliate & influencer-marketing app, modelled on GoAffPro and built to the client PRD (§4.1–4.10).
Brands invite creators as affiliates. Each affiliate gets a personal coupon code and referral link. When a shopper checks out with that code on the brand's real Shopify store, the sale is attributed to the affiliate, commission is calculated automatically, and the brand pays the affiliate out — as store credit (a real Shopify coupon) or PayPal. It is a complete working loop, not a mock-up.
02 How we built it — the journey
Each phase shipped working software before the next began, following your "research → plan → approve → build" rhythm.
Research & plan
Studied GoAffPro's full product (docs + a live video walkthrough of your installed app), mapped it to the PRD, and designed the database and architecture before writing feature code.
Foundation & data model
Set up the monorepo, PostgreSQL, and the Prisma schema — Merchant, Affiliate, Commission groups, Orders, Payouts and more. The commission engine (default → group → tiered → per-affiliate) was built here.
Admin CRM + Affiliate Portal
Rebuilt both surfaces into a professional CRM look with a shared design system — data tables, modals, toasts, charts, collapsible sidebars — and full affiliate CRUD, sales, payouts, leaderboard and analytics.
Real Shopify connection
Wired the store via a custom-app Admin API token. Real discount codes are created in Shopify; real orders are synced and attributed; store-credit payouts issue real coupons.
Gap-fill against GoAffPro
Custom signup fields, editable referral code, profile photo, payout invoices, coupon usage-limits pushed to Shopify — closing the differences found in the live walkthrough.
Branding, settings & deeper coupon/commission logic
Brand colours & logo now apply everywhere (admin, portal, signup, login); tabbed settings with Integrations; Automatic Coupons, auto-apply, personal coupons, and product-level commissions.
03 Architecture & tech stack
One repository, two apps, a Postgres database, talking to Shopify's Admin API.
- Next.js 16 (App Router)
- React 19 + TypeScript
- Tailwind v4 design system
- Runs on
:3000 - Admin CRM + Affiliate Portal + public signup/store
- NestJS 11 (TypeScript)
- Prisma 6 ORM
- REST under
/api, on:4000 - Controllers: admin · affiliates · shopify · tracking
- Commission engine + Shopify service
- PostgreSQL (via Prisma)
- Shopify Admin API (GraphQL)
- Custom-app token
shpat_… - Secrets in
apps/api/.env - Scopes: read_orders · write_discounts · read_products
04 Data model — where everything lives
Eleven Prisma models. A Merchant (the brand) owns everything; an Affiliate is the heart of the system.
| Model | Holds | Key fields |
|---|---|---|
| Merchant | The brand / store & all program config | programName, autoApprove, commission defaults, minPayout, branding (logo/colours), signupDefaults, autoCoupon, payoutMethods |
| Affiliate | A creator + their coupon & balance | name, email, status, couponCode, discount config, balance, referralLink, signupData |
| CommissionGroup | Tiers / group rates & signup bonus | name, type, value, tiers, signupBonus |
| ProductCommission | Per-product / per-tag rate overrides | matchType, matchValue, affiliateId, commissionType, value |
| ReferralOrder | An attributed sale + its commission | shopifyOrderId, subtotal, total, commission, status |
| Click | Referral-link clicks (attribution) | affiliateId, ip, createdAt |
| Payout | A payout request / paid record | amount, method, status, reference (coupon/txn) |
| SignupFieldDef | Merchant-defined custom signup fields | label, type, required |
| FraudFlag | Self-referral / same-IP flags | affiliateId, reason, ip, resolved |
| EmailLog | Every notification event (logged) | toEmail, type, subject |
| Asset | Marketing creatives / banners / links | type, url, title |
05 How data flows — the affiliate loop
The one journey that makes the whole product real, end to end.
06 How it connects to Shopify
Through a Shopify custom app — installed on the store, giving a private Admin API access token. No public-app OAuth needed for a single-store install.
- Shopify admin → Settings → Apps → Develop apps
- Create app → set Admin API scopes
- Install → copy the Admin API token (shpat_…)
- Put shop domain + token in
apps/api/.env - Manage from Settings → Integrations in the admin
- Discount codes created in the store (GraphQL discountCodeBasicCreate)
- Orders read & attributed (GraphQL orders + line items + tags)
- Store-credit payouts issue a real coupon
- Limits, min-order, expiry & combine-rules pushed onto the discount
07 PRD coverage — section by section
Against the client PRD §4.1–4.10. Bars show how complete each area is today.
08 What's built & working
Grouped by area — everything below is live in the app today.
- Overview with KPIs, important links & new registrations
- Affiliates: list, profile, approve/reject, edit, delete, bulk, tags, search
- Commission groups + product-level commissions
- Coupons: create/edit/delete, limits, automatic, auto-apply, personal
- Payouts: totals, method breakdown, invoices, bulk pay
- Sales, leaderboard, fraud flags, digital assets, marketing
- Tabbed settings: General · Payments · Notifications · Signup fields · Integrations · Branding
- Home: referral link + coupon + 6 performance metrics
- Editable referral code & profile photo
- Marketing: product-link generator + creative assets
- Payments: balance, request payout, store-credit / PayPal
- Payout history with downloadable invoices
- Settings: profile, password, notification preferences
- Branded (logo + colours) collapsible-sidebar layout
- Commission: default → group → tiered → per-affiliate → product
- Signup bonus on approval
- Real Shopify discount creation with all limits
- Real order sync & coupon attribution
- Store-credit payout = real Shopify coupon
- Logo upload + brand colours applied everywhere
- Custom + default signup fields (show/required toggles)
- Terms & Conditions on signup
- Public signup / login / store all branded
09 What's pending — and why
Mostly external-service integrations and a few production hardening items. Prioritised.
| Item | PRD | Needs | Status |
|---|---|---|---|
| Real email sending (welcome, sale, payout) | 4.9 | SMTP service (SendGrid / Mailgun) | Logged, not sent |
| Real-time webhooks (auto order & refund sync) | 4.4 | Shopify webhooks + public URL | Manual sync now |
| Storefront click-tracking script | 4.4 | Theme script on the live store | Not built |
| PayPal auto-payout | 4.8 | PayPal Payouts API keys | Manual mark-paid |
| Secure affiliate auth (JWT) | — | Token hardening | Demo login |
| Custom portal domain & signup templates | 4.10 | Hosting / DNS | Field only |
| Gift-card store credit option | 4.8 | Shopify gift-card API | Coupon only |
10 How to present this to the client
A 10-minute demo that shows the whole loop as a real product. Do it in this order.
11 How to publish & go live
From laptop to the internet. Two paths: host it as a hosted web app now, or turn it into a listed Shopify App later.
- Database → Neon / Supabase / Railway Postgres
- API (NestJS) → Railway or Render
- Web (Next.js) → Vercel
- Set env:
DATABASE_URL,SHOPIFY_SHOP,SHOPIFY_ADMIN_TOKEN,WEB_URL - Run
prisma migrate deployon the live DB - Point the web app's API URL at the deployed API
- Shopify Partner account
- Convert custom-app token → public app OAuth
- Add billing API (subscription pricing)
- App listing, privacy policy, review submission
- Register webhooks for orders/refunds