EPITONI SAAS PLATFORM.
A serverless customer-engagement platform that lets local businesses publish promotions, run loyalty programs and reach opted-in customers — matched by interest through a Neo4j graph of tags
THE
ARCHITECTURE
Epitoni is fully serverless on Google Cloud. A React business portal and a customer mobile app call a single API Gateway (OpenAPI 2.0 with Firebase JWT auth), which routes to 77 small Python Cloud Functions grouped by domain — auth, promotions, credits, loyalty, groups, get-notified, check-ins, interest graph and messaging — each deployed and scaled independently.
Persistence is polyglot: Firestore holds transactional data split across 11 domain databases, while Neo4j Aura holds the interest graph that drives targeting. Functions also call each other — a promotion push calls the Credits service to check and deduct its fee, and OTP validation calls the graph service to create the new user's node.
Epitoni's targeting depends on an interest graph. Businesses, promotions and customers are tagged (malls, hobbies, shopping preferences) and linked in Neo4j, so "which offers are relevant to this user?" is a single Cypher traversal instead of an expensive multi-join query.
Main node types: (:User), (:Business), (:Promotion) and (:Tag). Main relationships: FOLLOWS, LOCKED, POSTED and tag links.
Graph writes are idempotent — tags and relationships use Cypher MERGE, so repeated calls never duplicate nodes or edges. A user's graph node is created as soon as their OTP sign-up is validated.
Only relationship-critical data lives in the graph. Profiles, promotions, loyalty points and logs stay in Firestore — keeping queries fast and the schema focused.
Key
Technical Decisions
INTERFACE GALLERY
TECHNICAL
CHALLENGES
01. Service-to-Service Billing
Every promotion push had to be paid for. The push service calls the Credits service to check the business's balance and deduct its fee, handling FREE versus paid credit types and returning clear errors when the balance is insufficient.
02. Consistency Across 77 Functions
Each function verifies the Firebase token, validates input with Pydantic models that reject unknown fields, raises typed errors and writes structured Cloud Logging. That common code was copied into each function — a shared package and a CI/CD pipeline are the next step.
IMPACT & METRICS




