Skip to content

Networking Platform

Re-platformed an undocumented Laravel networking app onto Frappe, then added what it never had.

A membership platform for a business-networking community. Guests join, become members, attend coffee meets, events and Zoom sessions, and earn points and badges for taking part. One backend serves a mobile app, a web portal and an admin desk.

  • Android and iOS app
  • Web portal
  • Admin desk
  • Python
  • Frappe
  • MariaDB
  • Flutter
  • Vue
  • Zoom
  • Firebase
In production · client work
Networking Platform
~300
API endpoints behind three front ends
10
modules, from sign-in to notifications
2
versions in use, a third in development

What it does

A member's whole journey

Guest, member, dormant, ex-member. Payments and nightly attendance checks move people along, and renewal reminders go out by email, SMS and push.

Online payments and invoices

Gateway payments are reconciled, and invoices are generated once, with the right tax split. Admins can also record manual payments.

Points and badges

Taking part earns points. Nightly jobs turn rolling averages into ranked badges and decide who may host.

Coffee meets

Location-aware meets with check-in only when you are actually there, and ratings for hosts.

Events and Zoom

Paid events with GPS attendance and ID cards, and Zoom attendance that turns into points.

Notifications that respect you

Push, SMS, email and in-app alerts, with a per-member opt-out. Push history doubles as an inbox.

Files, handled properly

Uploads go to cloud storage, private files get short-lived links, and ID cards and flyers are rendered on demand.

One backend, three front ends

A Flutter app, a Vue web portal and an admin desk all call the same API, next to a public website.

Under the hood, briefly

  • Business rules live in one place. A single app owns every rule. The apps for messaging, Zoom and storage only send, store or fetch.
  • Ledgers you can audit. Points are an append-only ledger, so scores and badges can always be explained.
  • Safe to retry. Invoice generation is idempotent, so a repeated payment callback never creates a second invoice.
  • A handbook of the system. A full reverse-engineered guide covers rules, flows, endpoints and settings, with a traceability matrix generated from the code.

Problems worth telling

  • Double payments from late callbacks. The payment gateway’s callback sometimes arrived about 15 minutes late, so a paid order still looked unpaid and people paid again. Now a new attempt first fetches the live status of any existing order for the same purchase: never attempted, it’s cancelled and replaced; in flight, the user waits 30 minutes; captured, the record is synced. Five layers (callback, return to portal, next attempt, a 30-minute check and a nightly sync of unclear orders only) make every order’s status converge, and each one fetches the live status from the gateway.
  • A full disk from cloud storage. Files were offloaded to S3, but the local copies were never deleted and the server’s disk filled up, with some files not linked to any record at all. I turned on S3 versioning first as a safety net, then built a maintenance job that removed local copies already in S3 and cleaned up the orphans, with no production data lost.
  • Images from templates. Zoom backgrounds, flyers and testimonial cards started on Pillow and moved to HTML/CSS templates rendered in headless Chromium with Playwright, trading some generation time for print-quality output.

Next project

Expense Tracker →