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
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
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.
- 1Introduce contract tests between the NestJS API and the Flutter client earlier — a few breakages were caught only at runtime.
- 2Move long-lived sockets to a dedicated process so API deploys don't drop client connections.
- 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
| Tier | Price | Revenue Stage | Key Features |
|---|---|---|---|
| Starter | $29/mo | Pre-revenue → $10K/mo | Profile, feed, DMs (limited), free events, directory |
| Pro | $79/mo | $10K–$100K/mo | All Starter + opportunities board, resource library, host events |
| Elite | $197/mo | $100K+/mo | All 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:
textimagevideolinkpolldocument - 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_timefreelancepartnershiprevenue_sharejv - 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_urlstored after completion - RSVP with confirmation email + reminder 1h before
##4.8 Resource Library
- Types:
templatesopcourseplaybookswipe_filescripttoolother - 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_eventstable — 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)
| Queue | Jobs |
|---|---|
email | welcome, verify-email, password-reset, notification, event-confirmation, event-reminder |
notifications | dispatch — saves to DB + Socket.io emit |
embeddings | generate (single user), refresh-all (weekly cron) |
media | process-image, process-video, combine-hls |
cleanup | expire-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
| Layer | Technology | Version | Reason |
|---|---|---|---|
| Runtime | Node.js | 20 LTS | Stable, excellent Docker image |
| Language | TypeScript | 5.x | Type safety, better Copilot output |
| Framework | NestJS | 10.x | Modular, opinionated, enterprise DI |
| ORM | TypeORM | 0.3.x | Native NestJS integration, migrations |
| Primary DB | PostgreSQL | 16 | ACID, pgvector, proven at scale |
| Vector Search | pgvector | 0.5+ | AI embeddings co-located with data |
| Cache + Pub/Sub | Redis | 7.2 | Cache, Socket.io adapter, BullMQ |
| Redis Client | ioredis | 5.x | Retry logic, TypeScript types |
| Real-time | Socket.io | 4.x | WebSocket + polling fallback, rooms |
| Job Queue | BullMQ | 5.x | Redis-backed, retries, scheduling |
| Auth | Passport.js | 0.7+ | JWT + Google + Apple strategies |
| OAuth | passport-google-oauth20 + apple-signin-auth | latest | Social login |
| Password | bcrypt | 5.x | 12 rounds |
| Validation | class-validator + class-transformer | latest | Decorator DTOs |
| API Docs | @nestjs/swagger | 7.x | Auto-generated OpenAPI |
| Email (dev) | Mailhog | Docker | Catches all email, no real sends |
| Email (prod) | Nodemailer + SMTP | 6.x | Works with Resend, SendGrid, SES |
| Payments | Stripe | 14.x | Subscriptions, webhooks, portal |
| Proxy | Nginx | 1.25 Alpine | Rate limiting, gzip, WS, files |
| Containers | Docker + Compose | 24+ / 2.x | One-command startup |
| Docker UI | Portainer CE | latest | Free web-based Docker management |
#7. Docker Containers
| Container | Image | Role | Dev Port |
|---|---|---|---|
payday-api | node:20-alpine (multi-stage build) | NestJS API | 3000 |
payday-postgres | pgvector/pgvector:pg16 | Primary database + pgvector | 5432 |
payday-redis | redis:7.2-alpine | Cache + pub/sub + BullMQ | 6379 |
payday-nginx | nginx:1.25-alpine | Reverse proxy + file serving | 80, 443 |
payday-mailhog | mailhog/mailhog | Email catcher (dev only) | 1025, 8025 |
payday-portainer | portainer/portainer-ce | Docker management UI | 9000 |
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)
| Table | Purpose |
|---|---|
users | Auth records — email, password_hash, tier, status |
member_profiles | Rich profiles — skills, niche, embedding vector |
member_connections | Follow/connect relationships |
member_badges | Assigned badges (Connector, Mentor, Deal Maker, etc.) |
channels | Topic rooms for the community feed |
posts | Feed posts + comments (parent_id set = comment) |
post_reactions | Per-user reactions (fire, rocket, clap, money, heart, lightbulb) |
saved_posts | User's saved/bookmarked posts |
conversations | DMs, group chats, deal rooms |
conversation_participants | Members in each conversation |
messages | Individual messages with read receipts |
opportunities | Job board listings |
opportunity_applications | Applications to opportunities |
events | Virtual/in-person events with streaming |
event_attendees | RSVPs |
resources | Templates, SOPs, courses, playbooks |
resource_ratings | Per-user ratings + reviews |
reputation_events | Append-only points log |
notifications | In-app notification records |
notification_preferences | Per-user delivery preferences per notification type |
subscriptions | Stripe subscription state |
moderation_logs | Admin action audit trail |
membership_applications | Pre-signup application queue |
#9. Engineering Roadmap
| Phase | Timeline | Deliverables |
|---|---|---|
| Phase 0 — Foundation | Weeks 1–4 | Docker setup, auth (JWT + Google + Apple), member profiles, admin dashboard, Stripe subscriptions |
| Phase 1 — Core MVP | Weeks 5–10 | Feed, DMs, Socket.io gateway, member directory, opportunities board, notifications |
| Phase 2 — Engagement | Weeks 11–16 | Events + live streaming, resource library, leaderboard, reputation system, mobile app |
| Phase 3 — Intelligence | Weeks 17–22 | AI match engine (pgvector), smart feed ranking, content moderation |
| Phase 4 — Scale | Weeks 23–28 | Deal rooms, mastermind groups, advanced analytics, affiliate program |
| Phase 5 — Growth | Ongoing | API for integrations, international expansion, expanded AI features |