Skip to content
WS

Product engineering case study

Helping traveling boxers decide where to train before they show up.

JabNGo is a boxer-first gym directory that turns scattered, inconsistent gym information into searchable, comparable listings. I designed and built the first release end-to-end, beginning with three source-checked boxing-gym profiles in Playa del Carmen.

Role
Solo product engineer
Responsibilities
Product strategy, UX, data modeling, frontend, backend and deployment
Stack
Next.js, TypeScript, React, Tailwind CSS, Prisma, Neon Postgres, Vercel
Status
Live V1
Initial market
Playa del Carmen
Initial scope
3 source-checked profiles
Team
Solo
Timeline
Built and launched August 2026

V1 constraints

  • One live city
  • Manually sourced gym information
  • Partial, inconsistently maintained source data
  • No established marketplace liquidity
  • No accounts, booking or payments

V1 launched August 2026 · Product captured September 2026

JabNGo directory for Playa del Carmen: the heading Boxing gyms in Playa del Carmen, a full-width search field, six filter buttons, a 3 gyms count with a toggle whose List tab is active and whose Map tab reads “Map · soon”, and three image-led gym cards for Olympus Boxing Gym, Pool Boxing Playa del Carmen and Academia y Club de Boxeo 15 Rounds, each showing drop-in price, status and verification age.Enlarge
jabngo.com/gyms/playa-del-carmen
Product captured September 2026. Live information may have changed.

01 / Problem

Five tabs before one workout.

A fighter landing in a new city has to answer a specific set of questions before committing to a gym — and the answers live in five different places, in different languages, at different levels of freshness.

  • Is this a legitimate boxing gym or primarily a fitness class?
  • Can I drop in?
  • How much does it cost?
  • Is it open now?
  • Is it beginner-friendly?
  • Does it offer sparring?
  • Does it have the right equipment?
  • How do I contact it?

Evidence before building

  • The problem came from my firsthand experience looking for serious boxing training while traveling or entering a new city.
  • Gym information was distributed across Google Maps, Instagram, websites, WhatsApp and word of mouth.
  • The initial release is still a product hypothesis. It has not yet proven repeat use or broad demand.

The product’s job is not merely to list businesses. It is to make the “Should I train here?” decision faster and more trustworthy.

02 / Product decision

Starting with discovery instead of the marketplace.

The original idea was a marketplace matching fighters looking for sparring partners. That version introduced identity, safety, scheduling, trust and marketplace-liquidity problems before the basic discovery need had been validated. The first release deliberately solves the earlier problem in the journey.

Original concept

Sparring marketplace

  • Requires active supply and demand
  • User accounts and profiles
  • Identity and trust concerns
  • Scheduling and coordination
  • Difficult cold start
  • Safety and moderation requirements

V1 decision

Gym discovery

  • Useful with structured public gym data
  • Lower-friction validation
  • Public, indexable city and gym pages
  • City-by-city launch
  • Useful without active marketplace participation
  • Creates the data foundation for future features

Gym discovery became the first wedge because it offered a direct path to utility while creating the dataset future features would need.

03 / Deliberate V1 scope

The smallest version worth testing.

Included

  • City-based gym discovery
  • Search by gym or neighborhood
  • Six decision-oriented filters
  • Gym detail pages
  • Pricing and explicit schedule verification status
  • Opening status
  • Amenities and training types
  • Verification freshness
  • WhatsApp, phone, Instagram and directions
  • Explicit unknown states

Deliberately deferred

  • Booking and payments
  • User accounts
  • Reviews
  • Gym ownership claims
  • Sparring matching
  • Interactive map
  • Multiple live cities
  • Gym self-service dashboard

Each item was cut on purpose — parked, not forgotten.

Reducing scope made it possible to validate the information model and discovery workflow before building marketplace infrastructure.

04 / Data and trust

Unknown is a real data state.

Real gym information is often partial, inconsistent or outdated. JabNGo avoids converting uncertainty into false confidence. Missing facts are shown as unknown or ask gym instead of being guessed.

On JabNGo, “verified” means the information was checked against available gym sources, with owner or coach input when available. It does not mean the gym has claimed or endorsed the profile.

Conceptual information model

Conceptual. This shows the information the product must represent, not a one-to-one map of database tables — the real schema is in Engineering.

The interface distinguishes between confirmed, unknown, “ask gym,” unavailable and potentially stale information:

  • Confirmed
  • Unknown
  • Ask gym
  • Not offered
  • Previously verified · may be stale

Quick decision

Olympus Boxing Gym

✓ Recently source-checked

Drop-in$50 MXN

Monthly$600 MXN

HoursUnknown

ScheduleNot verified yet

  1. Partial truth is allowed. Price can be known while the schedule remains unknown — one doesn’t block the other.
  2. Verification has a visible age. Profiles show when information was last source-checked instead of displaying a permanent checkmark.
  3. Unknown never passes a filter. A gym with unknown hours does not appear under “Open now.”
  4. There is always a recovery path. Direct contact links cover the cases where information is incomplete.

05 / Product walkthrough

From city search to a training decision.

Step 1

Enter through a city

The first release avoids a broad empty search experience by directing users toward the city with useful inventory.

JabNGo homepage: the label Combat-sports gym finder, the headline Find the right combat-sports gym before you show up, a city search field, a red Browse Playa del Carmen gyms button, a What you can compare panel listing drop-in policy, pricing, class schedule, open now, amenities and sparring, and a Playa del Carmen city card marked Now live.Enlarge
jabngo.com
Product captured September 2026. Live information may have changed.

Step 2

Narrow the options

Search and filters work together so users can narrow gyms by both identity and practical training requirements.

The Playa del Carmen directory with olympus typed into the search field. The count reads 1 of 3 gyms beside a Clear filters control, and only the Olympus Boxing Gym card remains, showing 50 MXN drop-in and unknown status.Enlarge
jabngo.com/gyms/playa-del-carmen
Product captured September 2026. Live information may have changed.

Step 3

Handle zero results honestly

The empty state helps the user recover instead of presenting a dead end.

The Playa del Carmen directory with Open now, Sparring and Under 200 drop-in active. The count reads 0 of 3 gyms and an empty state reads No gyms match these filters, suggesting that removing a filter would return more results, with a Clear all filters button.Enlarge
jabngo.com/gyms/playa-del-carmen
Product captured September 2026. Live information may have changed.

Step 4

Make the final decision

High-intent information appears before descriptive content and media.

The full Olympus Boxing Gym profile: a no-photos-yet cover, the gym name, neighborhood and address, Boxing / Drop-in friendly / Verified badges, a black Quick Decision panel with a red top edge showing Hours unknown, Ask gym for schedule, $50 MXN drop-in and $600 MXN monthly with WhatsApp and Directions buttons, followed by numbered sections for today’s classes, pricing, amenities, about, video, photos, hours and contact links.Enlarge
jabngo.com/gyms/playa-del-carmen/olympus-boxing-gym
Product captured September 2026. Live information may have changed.

Step 5

The whole decision in one panel

Everything a fighter needs to commit sits above the descriptive content: what it costs, whether the hours are known, and two ways to reach the gym directly. Unknown hours are stated rather than hidden, and the contact buttons are the recovery path when the data is incomplete.

The Quick Decision panel from the Olympus Boxing Gym profile: a black card with a red top edge, the label QUICK DECISION, Hours unknown, Ask gym for schedule, drop-in $50 MXN, monthly $600 MXN, and red WhatsApp and outlined Directions buttons.Enlarge
/gyms/playa-del-carmen/olympus-boxing-gym
Product captured September 2026. Live information may have changed.

06 / Engineering

Designing the system behind the interface.

Three decisions shaped the system: how gym facts are stored when most of them are partially known, how weekly opening hours become a single user-facing verdict, and how search and filters combine without overwriting each other.

Story 01

A schema built for partial truth

Gym facts change independently, so JabNGo does not treat a gym profile as one complete-or-incomplete record. Hours, pricing, classes, media, disciplines, amenities and contact channels are modeled separately. One category can remain unknown without preventing the rest of the profile from being useful.

Explicit states such as YES, NO and UNKNOWN, combined with last_verified_at, allow the interface to communicate uncertainty instead of replacing missing information with assumptions.

View complete schema

Complete JabNGo schema · generated from Prisma

100%

Generated from the current JabNGo Prisma schema. Scroll to pan, use − and + to zoom, Escape to close.

Simplified from the generated Prisma ERD. Timestamps and implementation-only fields omitted.

Three schema decisions, read from the generated ERD

amount_minor is a nullable Int
Prices are held in minor units as an integer, so no float rounding enters a price, and currency travels alongside it per row. Nullable is the point: a gym can have a named pricing option whose amount is not yet known.
Recurring times are String
opens_at, closes_at, starts_at and ends_at are strings, not DateTime. A weekly schedule is wall-clock time, not an instant: “opens 18:00 on Tuesdays” has no date attached, and storing it as a timestamp would force a fictional one.
Time zone lives on the city
The city record stores the time zone needed to interpret recurring local schedules, and gyms inherit it through city_id. That pairing is what lets a weekly wall-clock schedule mean the same thing to a visitor reading the page from another country.

Story 02

Time-zone-aware opening status

The city record stores the time zone needed to interpret recurring local schedules. The interface uses the available schedule information to present a user-facing opening state while preserving “hours unknown” when the source data is incomplete.

Because opens_at and closes_at are nullable and is_closed is explicit, the derivation has to distinguish “closed today” from “we do not know the hours” — and a gym with unknown hours must never satisfy an Open now filter.

Story 03

Composable search and filters

The discovery interface combines the user’s search query and active filters to calculate the visible gym results. Search and filters can be applied simultaneously without erasing one another, which is what makes the result count read “1 of 3 gyms” rather than silently resetting.

Unknown values are treated as failing a filter rather than passing it, so an incomplete profile is never presented as though it met a requirement.

Search-friendly routes

Descriptive city and gym routes create public, indexable pages that support discoverability today and city expansion later. Each new city is a new branch, not a new architecture.

/gyms/playa-del-carmen/gyms/playa-del-carmen/olympus-boxing-gym

Architecture

07 / What shipped

What shipped.

  • Production applicationLive and public
  • 1 live cityPlaya del Carmen
  • 3 source-checked profilesInitial launch scope, August 2026
  • 6 decision filtersIdentity and practical requirements
  • SearchAcross gym names and neighborhoods
  • Structured informationPricing, amenities and hours where known
  • Verification freshnessVisible age on gym profiles
  • Direct contact pathsWhatsApp, phone and directions
  • Responsive pagesDiscovery and gym-detail experiences

What I have not proven yet.

V1 makes the remaining product questions concrete and measurable. These are the open questions:

  • Repeat usage
  • Whether travelers prefer search or filters
  • Which gym attributes drive the final decision
  • Whether gyms will maintain their own information
  • Whether manual verification scales across cities
  • Whether the model can support a marketplace later

How I’ll evaluate V1.

Instrumentation is planned, not yet collecting. These are the measures the first release was designed to make answerable — none of them have results yet.

  • Search-to-profile conversion
  • Search and filter usage
  • WhatsApp clicks
  • Directions clicks
  • Zero-result rate
  • Returning visitors
  • Gym information corrections or updates

Planned measurement, not collected results. No figures appear on this page because none exist yet.

08 / Lessons and next steps

What I learned.

1

Solve the earlier problem first

Fighter matching was not the first problem in the user journey. Finding the right gym came before finding a sparring partner.

2

Data quality is part of the interface

Trust is affected not only by whether information exists, but by whether users can tell what is current, missing or uncertain.

3

Scope creates momentum

Launching one city with a complete decision path made the core discovery workflow testable without first building marketplace infrastructure.

Next, not everything next.

  1. Instrument search, filter and contact behavior
  2. Conduct lightweight usability testing with traveling fighters
  3. Improve the gym-data verification workflow
  4. Expand inventory within Playa del Carmen
  5. Validate the operational cost of launching a second city
  6. Add maps only after the core discovery workflow proves useful