Key Decision Timeline
Project Inception & Core Concept
Decision: Build gamified QR code campaign "Where Has Benny Been?"
- Goal: Email list growth through physical-to-digital engagement
- Mechanism: QR codes on business cards distributed at venues
- Incentive: Monthly contest for free tee-shirt
- Technology: Self-hosted FOSS stack (n8n, PostgreSQL, Listmonk, Shlink)
Rationale: More engaging than traditional "sign up for newsletter" - creates story and interaction
Technology Stack Selection
Decision: Use n8n for workflow automation instead of custom code
- Custom Node.js/Express API
- Zapier (SaaS, monthly cost)
- Make.com (limited free tier)
- n8n (SELECTED) - Self-hosted, visual, extensible
Database Selection: PostgreSQL 16
Decision: Use PostgreSQL as single shared database for all services
- MySQL/MariaDB
- MongoDB (document store)
- SQLite (too limited for production)
- PostgreSQL 16 (SELECTED)
Short URL Domain Selection
Decision: Register mmlnk.us for short URLs
- Short and memorable
- Recognizable brand connection (MM = Mad Monkey)
- .us TLD for geographic association
- Available domain
Card Type Strategy: Nest vs Traveler
Decision: Create two card types with different behaviors
| Type | Quantity | Behavior | Move Code |
|---|---|---|---|
| Nest Cards | 200-300 | Stationary at venues | No |
| Traveler Cards | 50-100 | Mobile, passed person-to-person | Yes |
Rationale: Nest cards provide consistent local engagement, travelers create viral spread and storytelling opportunities
Email Platform: Listmonk
Decision: Self-host Listmonk instead of using SaaS email provider
- Mailchimp (expensive at scale, $20-300/mo)
- SendGrid (complex pricing)
- Brevo (300 emails/day free limit)
- Listmonk (SELECTED) - Self-hosted, unlimited
- Listmonk: $0/mo (self-hosted) + SMTP relay costs
- Mailchimp: $20-60/mo for 500-2,500 subscribers
Domain Consolidation Strategy
Decision: Abandon multi-subdomain approach under mmc.fit
list.mmc.fit- Listmonk UIbenny.mmc.fit- Landing pagemmlnk.us- Short URLs
mmlnk.us- Short URLs only (public)mad-monkey-creations.com/benny- Landing page (subpath)hooks.mad-monkey-creations.com- n8n webhooks (internal)mail.mad-monkey-creations.com- Email server
Email Provider Switch: Brevo to ForwardMail.net
Decision: Use ForwardMail.net instead of Brevo for SMTP relay
| Feature | Brevo | ForwardMail.net |
|---|---|---|
| Free Tier | 300 emails/day | More generous |
| Deliverability | Good | Excellent |
| Setup | Moderate | Simple |
Landing Page Hosting Decision
Decision: Host at /benny subpath instead of separate container
- Separate Docker container on 10.0.0.154
- Subpath on main site (SELECTED)
QR Code Format: Dual SVG + PNG
Decision: Generate both SVG and PNG formats
- SVG: Primary for print (infinite scaling)
- PNG: Backup at 300 DPI (universal compatibility)
Card Design Differentiation
Decision: Create distinct back designs for nest vs traveler cards
- QR code
- Short URL
- Simple CTA: "Scan. Tell us where. Confirm email. Monthly winner!"
- QR code
- Short URL
- CTA + move instructions
- Prominent move code section
Port 25 Blocked - SMTP Relay Decision
Discovery: Comcast ISP blocks outbound port 25 (SMTP)
Decision: Accept SMTP relay as permanent solution
- Use relay (SELECTED): ForwardMail.net on port 587/465
- Upgrade to business ISP (expensive, $80-150/mo)
- Move to VPS/cloud (adds complexity)
- Request port unblock from ISP (rarely successful)
Privacy & Data Minimization
Decision: Implement strict data minimization policies
- IP Anonymization: Remove last octet before storage
- No PII: Only collect email, name, city (user-reported)
- Double opt-in: Required for all entries
- Easy unsubscribe: One-click in every email
- Data retention: 24 months for inactive subscribers
Rate Limiting & Abuse Prevention
Decision: Multi-layer rate limiting strategy
| Endpoint | Limit | Window | Key |
|---|---|---|---|
| /scan | 10 requests | 1 minute | IP address |
| /entry | 3 submissions | 1 hour | |
| /entry | 1 entry | 30 days | Email + month |
- CAPTCHA for suspicious patterns
- VPN/proxy detection
- Device fingerprinting (optional)
Deployment Phase Strategy
Decision: Six-phase gradual rollout
- Phase 1: Infrastructure (DNS, databases, containers)
- Phase 2: n8n workflows and testing
- Phase 3: QR production (10 test cards)
- Phase 4: End-to-end testing
- Phase 5: Pilot launch (20-50 cards)
- Phase 6: Full deployment (200-300 cards)
Consolidation to Single Docker Host
Decision: Move from multi-server architecture to single Docker host
| Component | Old IP | New Location |
|---|---|---|
| PostgreSQL | 10.0.0.151 | 10.0.0.250:5432 |
| n8n | 10.0.0.198 | 10.0.0.250:5678 |
| Shlink | 10.0.0.152 | 10.0.0.250:8081 |
| Listmonk | 10.0.0.153 | 10.0.0.250:9000 |
- Single Docker host: bennybeen (10.0.0.250)
- External IP: 76.150.65.61 (dynamic)
- User: bennybeen (not indigoadmin)
- Project path: /home/bennybeen/mad-monkey/
- Admin whitelist: 10.0.0.157
- Added: n8n.janness.com
- Added: traefik.janness.com
- Kept: hooks.mad-monkey-creations.com, mmlnk.us, admin.mmlnk.us, list.mad-monkey-creations.com
- Removed: All Brevo (Sendinblue) references
- Kept: ForwardMail.net as ONLY email provider
- Reason: Better deliverability, PostgreSQL integration, webhooks, API
- Use deploy.sh script for automated deployments
- n8n workflows available for deployment automation
- DNS-UPDATE-PROCESS.md for handling dynamic IP changes
SSL Proxy Migration to New Host
Decision: Migrate NGINX Proxy Manager from 10.0.0.3 to 10.0.0.251 (dockerhost-02)
- Old Host: 10.0.0.3 (decommissioned)
- New Host: 10.0.0.251 (dockerhost-02)
- Container Image: jlesage/nginx-proxy-manager:latest
- Config Preserved: 27 proxy hosts, 5 redirection hosts
- Admin UI: http://10.0.0.251:81
- Admin Login: indigoproductions@yahoo.com
ssh -i /root/.ssh/id_ed25519_to_250 indigoadmin@10.0.0.251Rationale: Consolidate infrastructure on dedicated docker hosts, improve manageability
Listmonk API Integration for n8n
Decision: Create dedicated API user for n8n-Listmonk integration
Listmonk v6 API authentication differs from web login:
- API users have
type='api'in database - API tokens stored as plaintext (not bcrypt hashed)
- Format:
api_user:plaintext_token
- API Username: n8n_api
- API Token: madmonkey-api-token-2026
- User Role: Super Admin (role_id=1)
n8n Workflows Activated
Decision: All core Mad Monkey workflows now active
| Workflow | Endpoint | Status |
|---|---|---|
| Scan Intake | /webhook/scan | Active |
| Email Capture | /webhook/entry | Active |
| Confirmation | /webhook/listmonk/confirm | Active |
| Story & Reward Drip | Schedule | Active |
| Monthly Winner Selection | Cron | Active |
Updated T01-T05 short URLs to point to /webhook/scan path
Database Schema Migration & Workflow Updates
Achievement: Complete system overhaul to new schema and all 5 workflows verified
| New Table | Purpose | Replaces |
|---|---|---|
subscribers |
Primary subscriber data with email verification | entries, users |
contest_entries |
Monthly contest participation tracking | Part of entries |
scan_tokens |
One-time tokens for QR scan validation | New |
- Fixed Drip Campaign node connections
- Updated Monthly Winner SQL to use new tables
- Template 10 deployed for community-focused opt-in emails
Duplicate Opt-in Email Issue Discovered
Problem: Users receiving TWO opt-in emails on form submission
- n8n workflow sends Template 10 via Listmonk transactional API
- Listmonk setting
app.send_optin_confirmation=truesends default opt-in - Custom email opt-in URL is BROKEN (Invalid UUID error)
- Default Listmonk email opt-in URL WORKS correctly
- Delete "Send Welcome Email" node from n8n workflow
- Rely on Listmonk's built-in opt-in system
- Style Listmonk's default opt-in template via admin UI
Landing Page JavaScript Fix
Fix: Added missing qrIdInput variable to landing page form
/home/bennybeen/mad-monkey/landing-page/e/index.html
Impact: Form submissions now work correctly
n8n Webhook Caching Issue Resolved
Achievement: Fixed critical blocker preventing auto-drip trigger
- Temporarily changed webhook path to force re-registration
- Discovered n8n API PUT requires only
{name, nodes, connections, settings} - Full confirmation flow now works: Verify → Contest Entry → Trigger Drip
Full E2E Tests Passing
Achievement: Complete end-to-end tests verified with real emails
| Result | Drip Wait Until | |
|---|---|---|
| bjindigo@gmail.com | PASS | 2026-01-21 01:35 UTC |
| indigoproductions@yahoo.com | PASS | 2026-01-21 01:35 UTC |
- Updated expired ForwardEmail SMTP password
- Cleared test data from all systems
- Manually triggered confirmation webhook (auto-registration issue)
Architecture Evolution
Version 1.0: Initial Concept (November 2024)
- QR codes to Direct landing page
- Form submission to Email capture
- Manual monthly drawing
Version 2.0: n8n Integration (December 1-10, 2024)
- n8n for workflow automation
- PostgreSQL for data persistence
- Shlink for URL shortening and tracking
- Listmonk for email marketing
Version 3.0: Current Architecture (December 15-Present)
- Consolidated domain strategy
- SMTP relay via ForwardMail.net
- Enhanced privacy protections
- Multi-layer rate limiting
- Drip email campaigns
- Traveler vs Nest card differentiation
Domain Strategy Evolution
| Version | Date | Strategy | Status |
|---|---|---|---|
| V1 | Nov 2024 | Multiple subdomains under mmc.fit (list., benny.) | Abandoned |
| V2 | Dec 10, 2024 | Hybrid: mmlnk.us + mmc.fit subdomains | Abandoned |
| V3 (Current) | Dec 15, 2024 | Two domains: mmlnk.us + mad-monkey-creations.com subpaths | Active |
Final Domain Map
mmlnk.us- Apex domain for short URLswww.mmlnk.us- Redirects to apexadmin.mmlnk.us- Admin interface (IP-restricted)
mad-monkey-creations.com- Main websitewww.mad-monkey-creations.com- Canonical versionmad-monkey-creations.com/benny- Landing pagehooks.mad-monkey-creations.com- n8n webhooksmail.mad-monkey-creations.com- Email server
Security Decision Timeline
HTTPS Everywhere
Decision: All services require SSL/TLS via Let's Encrypt
- Traefik handles automatic certificate renewal
- HTTP requests redirect to HTTPS
- 90-day certificates, auto-renew at 60 days
Admin Endpoint Restrictions
Decision: IP whitelist for admin endpoints
admin.mmlnk.us/rest- Shlink API (IP-restricted)- Listmonk admin UI on internal network only
- PostgreSQL not exposed externally
API Key Rotation Policy
Decision: Rotate API keys every 90 days
- Shlink API keys
- Listmonk credentials
- n8n webhook secrets
- External API keys (Printify, Etsy)
Database Backup Strategy
Decision: Daily automated backups with encryption
- Daily PostgreSQL dumps at 3 AM
- Encrypted with GPG
- 30-day retention
- Off-site backup to cloud storage
- Monthly backup restoration tests
Card Design Evolution
Design Iteration History
| Version | Date | Changes | Reason |
|---|---|---|---|
| V1 | Nov 2024 | Single card type, QR + URL only | Initial concept |
| V2 | Dec 5, 2024 | Added move code to all cards | Enable traveler tracking |
| V3 | Dec 10, 2024 | Split into Nest vs Traveler types | Different use cases require different features |
| V4 (Final) | Dec 21, 2024 | Distinct back designs, clear CTAs | Reduce user confusion, improve clarity |
Final Card Specifications
- Size: 3.5" x 2" (standard business card)
- Material: PVC (durable, weather-resistant)
- Finish: Matte or glossy (TBD based on test batch)
- Thickness: 30 mil (credit card thickness)
- Front: Big Benny graphic + "Track My Monkey" tagline
- Back: QR code + instructions + move code (travelers only)
- Colors: Brand colors (TBD - Mad Monkey palette)
- Fonts: Bold, readable from distance
Deployment Phase Timeline
Phase 1: Infrastructure Setup
COMPLETETimeline: December 26, 2024 - January 11, 2026
Status: 100% complete
- DNS strategy finalized
- Architecture documented
- PostgreSQL container deployment
- Shlink deployment and URL configuration
- Listmonk deployment
- Listmonk API credentials configured
- SSL Proxy migrated to 10.0.0.251
- All 5 n8n workflows active and tested
- Database schema migration complete (subscribers, contest_entries, scan_tokens)
- Landing page deployed at adventure.mad-monkey-creations.com
Phase 2: n8n Workflow Creation & Testing
98% COMPLETETimeline: January 8-20, 2026
Status: E2E tests passing - one workaround required
- ✓ Scan intake workflow (active)
- ✓ Email capture workflow (active)
- ⚠ Confirmation handler workflow (active - needs manual toggle after n8n restart)
- ✓ Story & Reward drip campaign workflow (active)
- ✓ Monthly winner selection workflow (active)
- Card health monitoring workflow (pending)
Phase 3: QR Card Production (Test Batch)
PLANNEDTimeline: January 21-31, 2025 (estimated)
- Generate 10 test QR codes (5 nest, 5 traveler)
- Finalize card design
- Print test batch
- Verify QR code scannability
- Test durability
Phase 4: End-to-End Testing
PLANNEDTimeline: February 1-7, 2025 (estimated)
- Test complete user journey (scan to entry to confirmation)
- Verify all database records created correctly
- Test email deliverability (all providers)
- Test rate limiting and abuse prevention
- Test error handling and edge cases
- Load testing (simulate 100+ concurrent users)
Phase 5: Pilot Launch
PLANNEDTimeline: February 8-28, 2025 (estimated)
Scale: 20-50 cards at 10-15 local venues
- Deploy pilot cards to friendly venues
- Daily monitoring for first week
- Collect feedback from participants and venue owners
- Track conversion metrics
- Optimize workflows based on data
- Prepare for full launch
Phase 6: Full Deployment
PLANNEDTimeline: March 1, 2025+ (estimated)
Scale: 200-300 cards across region
- Print full card inventory
- Deploy to 50-100 venues
- Distribute traveler cards
- Launch marketing campaign
- Run first monthly drawing
- Establish ongoing operational processes
Changes in Approach
Major Pivots & Course Corrections
1. From Custom Code to n8n
Original Plan: Build custom Node.js API with Express
Change: Use n8n for visual workflow automation
Impact: Faster development, easier debugging, more maintainable
2. From Multiple Subdomains to Two-Domain Strategy
Original Plan: list.mmc.fit, benny.mmc.fit, mmlnk.us
Change: mmlnk.us + mad-monkey-creations.com subpaths
Impact: Simplified DNS, better UX, clearer branding
3. From Self-Hosted SMTP to SMTP Relay
Original Plan: Direct email delivery from self-hosted server
Change: Relay through ForwardMail.net
Impact: Better deliverability, workaround ISP port blocking
4. From Single Card Type to Nest + Traveler
Original Plan: One card design for all use cases
Change: Separate designs optimized for stationary vs mobile
Impact: Clearer user instructions, better tracking, richer story
5. From Big Bang Launch to Phased Rollout
Original Plan: Print 300 cards and deploy all at once
Change: Six-phase gradual rollout starting with 10 test cards
Impact: Lower risk, catch issues early, validate assumptions