Skip to content
Abdullah Ghonaiem
All projects

Full-Stack Applications · Backend & Integrations

Nany Connect

A two-sided childcare marketplace, taken from a UI prototype to a secured full-stack application.

Company
Fifty Studios Holding Company
My role
Full-Stack Software Engineer
Status
Prepared for production deployment
Key result
82 → 2 database calls to load 40 conversations
  • React 19
  • TypeScript
  • TanStack Start
  • Supabase
  • PostgreSQL
  • Cloudflare Workers

Overview

Nany Connect is a childcare marketplace. Parents search for nannies, send a hire request, and message the nanny once she accepts. Nannies build a profile, upload their documents, and manage incoming requests.

A third group, administrators, verifies nannies before they appear in the marketplace: reviewing uploaded documents, approving or rejecting applications, and managing user accounts.

Problem and context

The project began as a UI prototype: screens with no real data, accounts, or rules behind them. It needed everything that makes a marketplace work, designed to fit an interface that already existed.

Childcare raises the stakes. The application holds identity documents and personal details, and the two sides must see only what they are entitled to. Security could not depend on the interface hiding a button.

My contributions

Designed and developed

My own work

  • The backend and application architecture, independently.
  • The PostgreSQL data model and its migrations.
  • Row-level security policies on every table, plus role-based authorization for parents, nannies, and administrators.
  • Parent and nanny workflows: profiles, search, hire requests, and messaging.
  • The administrative dashboard, including document review and approval.
  • Security hardening: redirect validation, security headers, rate limits, and scrubbing personal data from error reports.
  • Query optimization for conversations and the admin overview.

Integrated

Third-party services I connected

  • Supabase authentication and private file storage.

Built by others

Not my work

  • The original UI prototype that the application was built from.

Technical architecture

Request path and access control

Conceptual diagram

  1. 01

    Parents · Nannies · Admins

    Role-specific experiences

  2. 02

    TanStack Start app

    React 19 · typed routes

  3. 03

    Server functions

    Auth → profile → role

  4. 04

    Supabase Auth

    Sessions and identity

  5. 05

    PostgreSQL

    Row-level security

Simplified architecture using the stack listed above. Not a detailed map of the internal implementation.
The database is the security boundary
Every table has row-level security, so access rules hold even if a request bypasses the application. Helper functions keep cross-table checks fast, and public reads go through restricted views.
Layered server functions
Typed server functions pass through middleware in order: authenticate, load the profile, then check the role. Elevated database access is created only after the administrator check passes.
Requests before messages
A parent sends a hire request to a nanny, and only one can be pending per pair. Messaging between them unlocks when the request is accepted.
Private documents
Uploaded documents live in private storage, scoped to their owner’s folder and served through short-lived signed links. Once an administrator has reviewed a document, it is locked against edits.
Typed application layer
React 19 and TanStack Start, with Cloudflare Workers as the deployment target. Routes and server functions share types end to end.

Engineering challenges

  1. Authorization that holds without the UI

    Challenge
    Three roles see different data, and Supabase exposes the database to the browser directly. Hiding controls in the interface protects nothing.
    Approach
    Row-level security is enabled on every table. Default privileges are revoked and granted back per column, so a user can update only the fields meant for them. Cross-table checks run through dedicated functions to avoid policies evaluating each other recursively.
    Technology
    • PostgreSQL row-level security
    • Column privileges
    • Supabase
    Outcome
    The rules are enforced by the database for every client, including direct API calls.
  2. One query instead of eighty-two

    Challenge
    Loading the conversation list fetched each conversation’s latest message and unread count separately. For 40 conversations that was 82 database calls, growing with every new conversation.
    Approach
    A single SQL function returns each conversation with its newest message and unread count, using a lateral join and an existing index. It runs with the caller’s permissions, so row-level security still applies. The admin overview got the same treatment.
    Technology
    • SQL functions
    • Lateral joins
    • Indexes
    Outcome
    The conversation list loads in 2 calls regardless of how many conversations exist.
  3. Handling identity documents

    Challenge
    Nannies upload sensitive documents that administrators must review, and nobody else should ever be able to open them or swap them after approval.
    Approach
    Files go to private buckets with type and size limits. Storage policies restrict each user to their own folder, and database constraints tie every file path to its owner. Review locks the document and the verified fields, with a controlled way to resubmit after a rejection.
    Technology
    • Supabase Storage
    • Signed URLs
    • Check constraints
    • Triggers
    Outcome
    Documents are readable only by their owner and reviewers, and verified data cannot be changed silently.
  4. From prototype to something deployable

    Challenge
    A prototype has no answer for suspended accounts, abusive message volume, unsafe redirects, or leaking personal data into logs.
    Approach
    A hardening pass added redirect validation with tests, content security and transport headers, a per-user message rate limit enforced in the database, removal of an endpoint that allowed ID enumeration, and error reporting that strips personal data.
    Technology
    • Security headers
    • Rate limiting
    • Database policies
    Outcome
    The application was prepared for production deployment with these protections in place.

Results and impact

Database calls to load 40 conversations
82 → 2
Per-conversation queries replaced by one database function.
  • Backend, data model, and authorization built independently
  • Row-level security on every table
  • Prepared for production deploymentA public launch has not been announced.

Visuals

No product screenshots published

Dashboard screenshots will be added once approved for publication. The cover and the architecture diagram on this page are conceptual illustrations.