Skip to content
Return to Projects
Case Study

Payday Chat

A real-time, members-only network for online business founders.

The Problem

Founders needed a private, high-signal place to network, build teams, and scale revenue — not another noisy public feed. Payday Chat is invite-only and built around real-time collaboration.

My Role

Built solo with AI-assisted development — Flutter client, NestJS API, data model, real-time layer, and deployment.

Highlights

  • Real-time messaging with presence and live events over WebSockets
  • One NestJS API powering both a Flutter mobile app and a web client
  • PostgreSQL domain model with Redis for caching and pub/sub fan-out
  • NGINX gateway, Stripe payments, and OAuth authentication

Stack

FlutterDartNestJSPostgreSQLRedisNGINXStripe

Constraints

  • Invite-only product — auth and access control had to be correct from day one.
  • One backend, two clients (Flutter + web) — schema and contracts had to be shared, not duplicated.
  • Realtime is a feature, not a nice-to-have — presence and live events must survive reconnects.

System Architecture

Clients
Flutter Mobile App
Web App
Gateway
NGINX
API
NestJS REST
WebSocket Gateway
Data
PostgreSQL
Redis (cache + pub/sub)
External
Stripe
OAuth

Key Trade-offs

The decisions worth defending — what I chose, what I turned down, and why.

Realtime transport

Chose

WebSockets with Redis pub/sub fan-out

Rejected

Long-polling or third-party realtime SaaS

Predictable latency, no per-message vendor cost, and Redis already in the stack for caching — one fewer moving part.

Mobile client framework

Chose

Flutter (single codebase for iOS + Android)

Rejected

Native Swift + Kotlin clients

Solo build — two native clients would have doubled the surface area and slowed iteration on the API.

API style

Chose

REST + dedicated WebSocket gateway

Rejected

GraphQL subscriptions

Simpler operational story, easier to cache at the NGINX layer, and the realtime channel stays an explicit, observable component.

What I'd Do Differently

An honest retrospective — the stuff I'd change with more time, more users, or a second pass.

  1. 1Introduce contract tests between the NestJS API and the Flutter client earlier — a few breakages were caught only at runtime.
  2. 2Move long-lived sockets to a dedicated process so API deploys don't drop client connections.
  3. 3Add structured event versioning from day one instead of retrofitting it once the schema started moving.

Technical Deep-Dive

Architecture, specifications, and implementation details.

Payday — Master Specification

Version: 1.0
Stack: NestJS + PostgreSQL + Redis + Docker
Scale Target: 1,000–10,000 members


#1. Product Vision

Payday is a members-only platform for online business owners to network, build teams, and scale revenue. It operates as a private, high-trust environment — every member is vetted before access is granted.

"

"The private operating system for empire builders — where deals get done, teams get built, and empires get scaled."


#2. Who It's For

Primary user: Online business operators generating revenue via e-commerce, agencies, SaaS, content, consulting, or info products.

Core need: Find trusted partners, hire fast, learn from peers, and close deals — without public social media noise.


#3. Membership Tiers

TierPriceRevenue StageKey Features
Starter$29/moPre-revenue → $10K/moProfile, feed, DMs (limited), free events, directory
Pro$79/mo$10K–$100K/moAll Starter + opportunities board, resource library, host events
Elite$197/mo$100K+/moAll Pro + deal rooms, featured profile, priority matching, analytics

#4. The 10 Core Features

##4.1 Member Onboarding & Verification

  • Application-based entry — not public sign-up
  • Admin approval queue with manual review
  • Referral fast-track by existing members
  • Onboarding wizard after approval (profile setup, channel selection)

##4.2 Member Profiles

  • Business snapshot: niche, revenue stage, team size, years in business
  • Skillset tags array (e.g., Paid Ads, Copywriting, Fulfillment, Shopify)
  • Portfolio / case studies with media attachments
  • Availability status: Open to Deals / Hiring / Not Available
  • Verified badges, reputation score, profile views
  • AI-generated match embedding (vector stored in pgvector)

##4.3 Discovery & Networking Engine

  • Member directory with filters: niche, skills, revenue stage, availability, location
  • AI-powered match suggestions (pgvector cosine similarity)
  • "Who to Meet This Week" — weekly algorithmic list, cached per user 24h
  • Mutual connection map
  • Member directory full-text search via pg_trgm

##4.4 Community Feed & Discussions

  • Topic channels: General, Wins, Paid Ads, E-commerce, Agency, Copy, Investing, Hiring, Tech, Mindset, Deal Room
  • Post types: text image video link poll document
  • Reactions: 🔥 🚀 👏 💰 ❤️ 💡 (6 types tracked individually)
  • Comments as posts with parent_id — threaded replies
  • Save posts to personal collections

##4.5 Direct Messaging & Deal Rooms

  • 1:1 DMs with read receipts and typing indicators (real-time via Socket.io)
  • Group chats for teams and masterminds
  • Deal Rooms (Elite tier): structured conversation threads for proposals and contracts
  • File sharing: images, PDF, spreadsheets, video up to 50MB
  • Message requests for non-connections (no unsolicited DMs)

##4.6 Opportunities Board

  • Post types: full_time freelance partnership revenue_share jv
  • In-platform applications with cover letter + portfolio URLs
  • Status tracking: Open / Under Review / Filled / Expired
  • Requires Pro or Elite tier to post
  • Notification alerts for matching opportunities

##4.7 Events & Masterminds

  • Virtual events with live RTMP streaming (self-hosted, see 10_Live_Event_Streaming.md)
  • Mastermind groups: recurring small-group sessions
  • Calendar sync (Google, Apple, Outlook) — frontend responsibility
  • Replay library: events.recording_url stored after completion
  • RSVP with confirmation email + reminder 1h before

##4.8 Resource Library

  • Types: template sop course playbook swipe_file script tool other
  • Member-contributed resources (Pro/Elite only)
  • Rating + review system with auto-calculated avg_rating
  • Admin approval required before a resource is visible

##4.9 Leaderboard & Reputation System

  • Append-only reputation_events table — never update/delete rows
  • Score auto-updated by PostgreSQL trigger on every INSERT
  • Key events: profile_complete (+50), first_post (+25), post_got_10_reactions (+100), opportunity_filled (+150), event_hosted (+200), member_referred (+100)
  • Weekly + all-time leaderboards cached in Redis sorted sets

##4.10 Admin & Moderation Dashboard

  • Membership application review: approve / reject / waitlist
  • Content moderation queue: reported posts and messages
  • Platform analytics: DAU, MAU, revenue, churn, engagement
  • Broadcast announcements (in-app + email, target by segment or tier)
  • Moderation log: all admin actions audited in moderation_logs

#5. System Architecture

##Architecture Style: Modular Monolith

All domain logic lives in one NestJS process. Each domain is a fully isolated module with its own controller, service, entities, and DTOs. Modules communicate through NestJS DI — not HTTP. Designed for clean extraction into microservices at 10K+ members.

##Request Lifecycle

Client → Nginx (rate limit, gzip, proxy) → NestJS HTTP Server
  → Middleware (helmet, cookieParser, compression)
  → Guards (JwtAuthGuard → RolesGuard → TiersGuard)
  → Interceptors (LoggingInterceptor → TransformInterceptor)
  → Pipe (ValidationPipe — whitelist, forbidNonWhitelisted)
  → Controller → Service → Repository → PostgreSQL
  → TransformInterceptor wraps response: { success, data, meta, timestamp }
  → HttpExceptionFilter catches errors: { success: false, statusCode, message }

##NestJS Module Tree

AppModule
├── ConfigModule (global)           ← .env validation via Joi
├── DatabaseModule (global)         ← TypeORM → PostgreSQL
├── RedisModule (global)            ← ioredis + CacheManager
├── ThrottlerModule (global)        ← per-IP + per-user rate limiting
├── BullModule (global)             ← job queues backed by Redis DB 3
├── ScheduleModule                  ← cron jobs (@nestjs/schedule)
├── EventEmitterModule              ← in-process events between modules
├── AuthModule                      ← JWT, Passport, Google, Apple OAuth
├── MembersModule                   ← profiles, connections, discovery
├── FeedModule                      ← posts, comments, reactions, channels
├── MessagingModule                 ← conversations, messages, participants
├── GatewayModule                   ← Socket.io WebSocket gateway
├── OpportunitiesModule             ← job board + applications
├── EventsModule                    ← events + RSVPs + streaming
├── ResourcesModule                 ← library + ratings
├── NotificationsModule             ← dispatch engine (in-app/email/push)
├── ReputationModule                ← points, leaderboard, badges
├── PaymentsModule                  ← Stripe subscriptions + webhooks
├── AdminModule                     ← moderation, analytics, broadcast
└── HealthModule                    ← /health endpoint (terminus)

##Background Jobs (BullMQ)

QueueJobs
emailwelcome, verify-email, password-reset, notification, event-confirmation, event-reminder
notificationsdispatch — saves to DB + Socket.io emit
embeddingsgenerate (single user), refresh-all (weekly cron)
mediaprocess-image, process-video, combine-hls
cleanupexpire-opportunities, archive-events, purge-deleted-messages

##Security Layers

1. Nginx WAF rules + rate limiting (100 req/min global, 10/min auth)
2. NestJS ThrottlerGuard (per-user, tier-based limits)
3. JwtAuthGuard — every request needs valid Bearer JWT
4. RolesGuard — admin/moderator routes
5. TiersGuard — pro/elite feature gating
6. ValidationPipe — strips unknown fields, validates DTOs
7. TypeORM parameterized queries — SQL injection prevention
8. Helmet.js — security headers
9. bcrypt 12 rounds — password hashing
10. Stripe webhook signature verification

#6. Technology Decisions

LayerTechnologyVersionReason
RuntimeNode.js20 LTSStable, excellent Docker image
LanguageTypeScript5.xType safety, better Copilot output
FrameworkNestJS10.xModular, opinionated, enterprise DI
ORMTypeORM0.3.xNative NestJS integration, migrations
Primary DBPostgreSQL16ACID, pgvector, proven at scale
Vector Searchpgvector0.5+AI embeddings co-located with data
Cache + Pub/SubRedis7.2Cache, Socket.io adapter, BullMQ
Redis Clientioredis5.xRetry logic, TypeScript types
Real-timeSocket.io4.xWebSocket + polling fallback, rooms
Job QueueBullMQ5.xRedis-backed, retries, scheduling
AuthPassport.js0.7+JWT + Google + Apple strategies
OAuthpassport-google-oauth20 + apple-signin-authlatestSocial login
Passwordbcrypt5.x12 rounds
Validationclass-validator + class-transformerlatestDecorator DTOs
API Docs@nestjs/swagger7.xAuto-generated OpenAPI
Email (dev)MailhogDockerCatches all email, no real sends
Email (prod)Nodemailer + SMTP6.xWorks with Resend, SendGrid, SES
PaymentsStripe14.xSubscriptions, webhooks, portal
ProxyNginx1.25 AlpineRate limiting, gzip, WS, files
ContainersDocker + Compose24+ / 2.xOne-command startup
Docker UIPortainer CElatestFree web-based Docker management

#7. Docker Containers

ContainerImageRoleDev Port
payday-apinode:20-alpine (multi-stage build)NestJS API3000
payday-postgrespgvector/pgvector:pg16Primary database + pgvector5432
payday-redisredis:7.2-alpineCache + pub/sub + BullMQ6379
payday-nginxnginx:1.25-alpineReverse proxy + file serving80, 443
payday-mailhogmailhog/mailhogEmail catcher (dev only)1025, 8025
payday-portainerportainer/portainer-ceDocker management UI9000

All containers on bridge network payday-network, subnet 172.20.0.0/24. API connects to other services by Docker hostname: postgres, redis, mailhog.


#8. Data Models (Summary)

TablePurpose
usersAuth records — email, password_hash, tier, status
member_profilesRich profiles — skills, niche, embedding vector
member_connectionsFollow/connect relationships
member_badgesAssigned badges (Connector, Mentor, Deal Maker, etc.)
channelsTopic rooms for the community feed
postsFeed posts + comments (parent_id set = comment)
post_reactionsPer-user reactions (fire, rocket, clap, money, heart, lightbulb)
saved_postsUser's saved/bookmarked posts
conversationsDMs, group chats, deal rooms
conversation_participantsMembers in each conversation
messagesIndividual messages with read receipts
opportunitiesJob board listings
opportunity_applicationsApplications to opportunities
eventsVirtual/in-person events with streaming
event_attendeesRSVPs
resourcesTemplates, SOPs, courses, playbooks
resource_ratingsPer-user ratings + reviews
reputation_eventsAppend-only points log
notificationsIn-app notification records
notification_preferencesPer-user delivery preferences per notification type
subscriptionsStripe subscription state
moderation_logsAdmin action audit trail
membership_applicationsPre-signup application queue

#9. Engineering Roadmap

PhaseTimelineDeliverables
Phase 0 — FoundationWeeks 1–4Docker setup, auth (JWT + Google + Apple), member profiles, admin dashboard, Stripe subscriptions
Phase 1 — Core MVPWeeks 5–10Feed, DMs, Socket.io gateway, member directory, opportunities board, notifications
Phase 2 — EngagementWeeks 11–16Events + live streaming, resource library, leaderboard, reputation system, mobile app
Phase 3 — IntelligenceWeeks 17–22AI match engine (pgvector), smart feed ranking, content moderation
Phase 4 — ScaleWeeks 23–28Deal rooms, mastermind groups, advanced analytics, affiliate program
Phase 5 — GrowthOngoingAPI for integrations, international expansion, expanded AI features
~ End of Document ~