cd ../projects

Project 8 // _orbyt

Orbyt

A community network where the members decide what reaches their feed.

client

private client — confirm before publishing

timeline

19 months · Jan 2025 → Jul 2026 · ongoing

role

full-stack developer · web, mobile and admin

scope

web appReact Native appadmin consolesubscriptions & billingcontent filtering

## the-problem

Mainstream social networks are all-or-nothing. For a community with its own content standards, joining one means accepting a feed that ignores those standards — and leaving means losing the local businesses, events and word-of-mouth that live there.

The businesses had the mirror problem. They needed somewhere to be found, post, run events and take subscriptions, but the platforms that offered reach came with an audience and a feed they couldn't align with.

## the-approach

  • made the filter a first-class primitive, not a setting: members allow or block whole content categories, and the Explore feed, search and recommendations all respect that choice
  • built the directory around business profiles — posts, details, hours, locations, tagged content — so a business is a destination rather than just an account
  • one composer, three destinations: a post can be boosted onto the sales tab or the events tab at publish time
  • gave every business its own dashboard: engagement over time, top-performing content, follower counts and Instagram sync
  • card subscriptions through a card gateway, with per-business transaction history and downloadable receipts
  • an operator console for the long tail: business moderation (active/paused/suspended), users, posts, categories, locations, coupons, staff roles and permissions
  • shipped web, React Native and admin off one API, with Socket.IO for live notifications and messaging

// the feed — the member's filter runs before any post is matched

// The filter isn't applied to a page of results. It decides which
// businesses are eligible at all, so nothing downstream — search,
// recommendations, the events tab — can forget to honour it.
const filter = currentUser?.filter;
const userMatch: Record<string, unknown> = {
_id: { $in: following },
accountType: "business",
"businessProfile.status": "active",
suspendedTill: { $in: [null, undefined] },
};
const category = "businessProfile.category";
const and: Record<string, unknown>[] = [];
if (filter?.interests?.length)
and.push({ [category]: { $in: filter.interests } });
if (filter?.excludeInterests?.length)
and.push({ [category]: { $nin: filter.excludeInterests } });
if (and.length) userMatch.$and = and;
// Posts are matched against the survivors — never the other way round.
const eligibleUserIds = await User.find(userMatch).distinct("_id");
if (!eligibleUserIds.length) return toPlainObject(empty);

## the-architecture

// architecture — three surfaces, one filtered feed

client

web app

Next.js · directory + feed

  • Explore, Directory, Sales, Events
  • business dashboards
client

mobile app

React Native

  • feed, search, profiles
  • push notifications
client

admin console

moderation · billing

  • business + user moderation
  • staff roles & permissions
backend

API

Node · REST

  • one backend for all three
  • role-scoped permissions
backend

content filter

per-member categories

  • applied to feed, search, recs
  • allow/block by category
backend

realtime

Socket.IO

  • messaging
  • live notifications
data

MongoDB

businesses · posts · users

  • category + location indexes
  • engagement counters
data

media

AWS S3

  • post carousels
  • profile + cover art
external

Cardknox

card subscriptions

  • hosted card fields
  • recurring billing + receipts
external

Instagram

account sync

  • per-business connection
  • connect / disconnect states
external

WhatsApp

messaging reach

  • business contact channel
clientbackenddataexternal

## the-results

19 mo

of continuous development

3

surfaces, one API

v2

rebuilt, still shipping

  • web app, mobile app and admin console shipped from a single backend
  • carried through a full second-generation build without losing the product
  • still under active development 19 months in
nextreactmongodbrealtimetypescriptaws

// want something like this built for you?

start-a-project