HomeCase studiesA Community Business Directory and Digital Publication...

Case study · Atlanta, United States

A Community Business Directory and Digital Publication Platform

Local business directory and community media

Directories face a harder cold-start problem than most marketplaces: consumers will not use a directory with few listings, and businesses will not pay to join one with few consumers. Our team built a platform that solves both sides — listings can exist before their owners engage and be claimed later, while editorial content and issue-based digital editions give consumers a reason to return regardless of directory depth. Tiered subscriptions monetise listings, delivered through a native mobile application over an API and full administrative back office.

Industry
Local business directory and community media
Solution
A REST API and administrative platform with a native iOS application, combining a searchable business directory, a subscription listing model, an editorial blog and issue-based digital publications.
Platforms
iOS · Web & API
Stack
Laravel · PHP · MySQL · Swift · Google Maps · Passport
Location
Atlanta, United States · delivered remotely
Role
Engineering, with the team behind for mobile and QA

Delivered remotely for a business based in Atlanta, United States. Names withheld by agreement.

Project Overview

Industry: Local business directory and community media.

Type of solution: A REST API and administrative platform with a native iOS application, combining a searchable business directory, a subscription listing model, an editorial blog and issue-based digital publications.

Business context: A directory's value to a consumer is proportional to how complete it is, and its value to a business is proportional to how many consumers use it. Neither condition is true at launch. Most directories try to solve this with sales effort, recruiting businesses one at a time into a product that cannot yet demonstrate an audience. That is slow, expensive, and frequently fails before the flywheel starts turning.

General users: Consumers browsing and reviewing local businesses and reading published content; business owners creating or claiming and then managing their listings; and the operator's administrative and editorial team.

General purpose: To make local businesses discoverable, to give business owners a controllable presence with paid enhancement options, and to sustain consumer engagement through regular editorial and published content.

The Business Challenge

The directory cold-start problem. An empty directory is worthless to consumers, and a directory with no consumers is worthless to businesses. Something has to break the deadlock before either side has a reason to participate.

Businesses will not do the data entry. Asking a business owner to register, complete a profile, upload images and enter opening hours before they have seen any benefit is a conversion path with a very low completion rate.

Consumers need a reason to return. Directory use is episodic — people visit when they need something specific. Between those moments there is no reason to open the app, and an app that is not opened is eventually deleted.

Listing data is inherently messy. Opening hours vary by day, include multiple periods, and have exceptions. Addresses arrive inconsistently. Categories overlap. All of it has to be structured enough to search and display reliably.

Monetisation must not gate discovery. If only paying businesses appear, the directory is incomplete and consumers lose trust in it. Paid tiers have to enhance visibility rather than control existence.

Two products, one platform. A directory and a digital publication have almost nothing in common technically, but they had to share users, navigation, administration and a single mobile application.

Listing ownership is a trust boundary. If listings can be claimed, then who gets to claim them is the most security-sensitive question in the product.

Our Approach

Design for pre-population from the start. We made the unclaimed listing a first-class concept rather than a workaround. A listing exists as a record in its own right, with or without an owner, and carries an explicit unclaimed state. The directory can therefore be populated ahead of demand and become useful to consumers immediately, with business owners taking ownership afterwards through a dedicated claim flow.

Give consumers a non-directory reason to open the app. Editorial content and issue-based digital editions were built into the same product, so the platform has recurring content value between the occasional moments when someone actually needs to find a business.

Model listing data properly, and iterate when the model is wrong. Opening hours went through successive representations before settling on a structured JSON format capable of expressing real-world schedules. Changing a data representation in a live product is unglamorous work that most teams avoid — and avoiding it is how directories end up with unsearchable, unreliable listing data.

Make subscription tiers data, not code. Plans and their feature details are stored as records, so what a tier includes can be changed by the operator without a development cycle — which matters, because directory pricing and packaging get revised frequently in the first years.

Cache what is read constantly and changes rarely. Categories, plans and content pages are read on almost every request and change occasionally, so model-level caching was applied to keep those reads off the database.

Build the mobile app modularly. The native client was structured with a clear separation between an application core — configuration, base classes, utilities, localisation, logging, deep link handling — and self-contained feature modules, so the app remains maintainable as features accumulate.

Support sharing and deep linking. A dedicated URL handling module means a listing or article shared externally opens in the right place in the app, which is essential for a product whose growth depends on content being passed around.

The Solution

Rich business listings. Each listing carries the business name, contact details, website, full address with geographic coordinates, category, profile and banner imagery, a photo gallery, descriptive text, structured opening hours and social media links — enough for a consumer to decide whether to visit without leaving the app.

Claimable listings. Listings can exist before their owners do. A business owner claims their listing through a dedicated flow and thereafter controls its content, which removes the registration barrier that would otherwise block directory growth.

Hierarchical categorisation. A two-level category structure with descriptive content per category supports both browsing and discovery, giving consumers a navigable path into the directory rather than only a search box.

Location-based discovery. Coordinates on each listing power map display and proximity-based browsing, so the directory answers the question consumers actually have — what is near me.

Reviews and ratings. Consumers rate and review businesses, adding the social proof that makes a directory credible and giving business owners a reason to maintain their presence.

Subscription listing tiers. Plans with monthly and annual pricing and per-plan feature detail determine listing prominence and capability, with an upgrade path and payment capture in the mobile app. Discovery is never gated — paid tiers enhance rather than enable.

Promotional mechanics. Listings can offer coupon codes and accept quote requests, giving businesses a measurable reason to maintain and pay for their presence.

Digital editions. Issue-based digital publications are delivered in the app, giving consumers a recurring content reason to return that is independent of whether they currently need a business.

Editorial blog. Categorised articles with an in-app reader, supporting community content and search discoverability.

Support centre. Structured question-and-answer content, reducing support load from a user base spanning consumers and business owners with very different questions.

Administrative platform. Full management of listings, categories, plans, editorial content, digital editions, support material, CMS pages and users, with server-side data grids for working at directory scale.

Key Features

Claimable unclaimed listings Listings exist independently of their owners and carry an explicit unclaimed state, so the directory can be populated ahead of demand and businesses can take ownership later through a dedicated claim flow.

Structured opening hours Opening hours stored in a structured format capable of expressing real-world schedules — variable days, multiple periods and exceptions — rather than as free text that cannot be searched or reliably displayed.

Two-level category hierarchy Parent and child categories with descriptive content, supporting browsing, discovery and category-level content.

Location-based discovery with mapping Geographic coordinates on every listing driving map display and proximity browsing.

Reviews and ratings Consumer ratings and written reviews providing the social proof that makes a directory trustworthy.

Data-driven subscription tiers Plans and their features stored as records with monthly and annual pricing, so packaging can change without a release, with an in-app upgrade and payment path.

Coupons and quote requests Promotional mechanics attached to listings, giving businesses measurable return from their presence.

Issue-based digital editions Digital publication delivery inside the app, creating recurring engagement independent of directory need.

Editorial blog with categories Categorised articles with an in-app reader supporting community content and discovery.

Deep linking into listings and articles A dedicated URL handling layer so shared content opens in the right place in the app, supporting organic growth through sharing.

Technical Architecture

Mobile client. A native iOS application separated into an application core — configuration, base view controllers, utilities, localisation, logging and URL handling — and self-contained feature modules each owning its own interface, views and models. Networking, remote image loading and caching, map display, media capture with cropping and gallery browsing are handled through dedicated components.

API layer. A token-authenticated JSON API serving the mobile client, with cross-origin controls and a controller tree kept separate from administrative code.

Administrative platform. A server-rendered back office with server-side processed data grids covering listings, categories, plans, editorial content, digital editions, support material, CMS pages and users.

Application layer. Controllers partitioned by audience over shared base classes, with domain models covering businesses, categories and their hierarchy, plans and plan details, editorial content, digital editions, support content and platform settings.

Data layer. A relational database with structured storage for complex listing attributes, incremental non-destructive schema evolution, and model-level caching applied to high-read catalogue entities.

Media handling. Image upload with server-side processing, supporting profile imagery, banners and galleries per listing.

Supporting services. Mapping for location display, payment handling for subscription upgrades, and email delivery for verification and notification.

Flow: iOS app → Token-authenticated API → Controllers & domain models → Relational database (cached catalogue reads) → Image processing & storage → Map, payment and email services → Administrative back office

Technology Stack

Category Technology
Backend language PHP
Backend framework Laravel
Database MySQL with Doctrine DBAL
API authentication Laravel Passport (OAuth2) and Sanctum
Query caching Model-level caching layer
Administrative grids Yajra DataTables (server-side processing)
Image processing Intervention Image
Admin forms Laravel Collective HTML
Diagnostics Log viewer
Mobile platform Native iOS (Swift), modular application architecture
Mobile networking Alamofire with remote image loading and caching
Mapping Google Maps
Media capture Multi-select image picker with crop view controller
Media viewing Photo browser with gallery support
Ratings Star rating component
Mobile UI Collapsible table views, rich interactive labels, progress indicators, keyboard management, custom collection layouts
Connectivity Reachability handling
Localisation Built-in localisation support
Testing PHPUnit, Faker factories, Mockery

Technical Challenges & Solutions

Challenge Our Approach
Directory cold start — no listings means no consumers, no consumers means no listings The unclaimed listing built as a first-class concept: listings exist as records independent of owners, with an explicit unclaimed state and a dedicated claim flow, so the directory can be useful before businesses engage.
Business owners unwilling to complete registration before seeing value Claiming an existing, already-populated listing replaces creating one from scratch, converting a lengthy onboarding into a verification step.
Consumers having no reason to open a directory between needs Editorial content and issue-based digital editions built into the same product, creating recurring engagement independent of directory use.
Opening hours that free text cannot express and search cannot use The representation was iterated deliberately — through successive schema changes in a live product — to a structured format capable of expressing variable days, multiple periods and exceptions.
Subscription packaging changing faster than release cycles Plans and their feature details stored as data rather than encoded in application logic, so the operator can change what a tier includes without a deployment.
Catalogue data read on nearly every request Model-level query caching applied to categories, plans and content pages — high-read, low-change entities — reducing database load on the busiest paths.
A native app accumulating features without becoming unmaintainable A modular structure separating application core concerns from self-contained feature modules, each owning its own interface, views and models.
Shared content needing to open in the right place A dedicated URL handling module supporting deep links into listings and articles, so content shared externally converts into app engagement.
Media-heavy listings uploaded from mobile devices Client-side image selection and cropping before upload, with server-side processing and remote image caching in the app for consistent, efficient presentation.

Security & Reliability

Authentication. Token-based OAuth2 authentication with email verification and password recovery for consumer and business accounts.

Listing ownership control. Claiming an existing listing runs through an explicit flow rather than being an automatic association, so control of a business's public presence is a deliberate, verifiable transition.

Surface separation. Consumer API endpoints and administrative functionality are held in separate controller trees, so administrative capability is not reachable from the public API.

Cross-origin controls. Explicit policy over which clients may call the API.

Non-destructive data evolution. Schema changes were applied incrementally with additive migrations, preserving existing listing and content data throughout the product's evolution.

Content moderation capability. Administrative control over listings, reviews and editorial content allows inaccurate or inappropriate material to be managed.

Operational visibility. Administrative dashboards and log inspection tooling support day-to-day operation and issue investigation.

Connectivity resilience. The mobile client detects connectivity state so behaviour on poor networks is predictable rather than silently failing.

Scalability & Performance

Cached catalogue reads. Categories, plans and content pages are cached at the model layer, keeping the most frequent reads off the database.

Server-side administrative grids. Administrative listings page, sort and filter at the database level, so the back office remains usable as the directory grows.

Paginated consumer endpoints. Listing and content endpoints return bounded result sets rather than growing with the directory.

Efficient media handling. Images are cropped and sized on the device before upload, processed server-side once, and cached on the client for repeat viewing.

Stateless API tier. Token authentication keeps application instances free of session state, supporting horizontal scaling.

Modular client architecture. Feature isolation in the mobile app means new sections can be added without increasing the cost of the existing ones.

Business Outcomes

  • The directory could launch useful, because listings existed before businesses engaged rather than after.
  • Business onboarding became a claim rather than a registration, converting a high-abandonment data entry task into a short verification step.
  • Consumers have a reason to return between needs, through editorial content and regular digital editions.
  • Listing data is structured and searchable, particularly opening hours, which most directories leave as unusable free text.
  • Discovery is never gated by payment, preserving directory completeness and consumer trust while paid tiers add prominence and capability.
  • Packaging can change without engineering, because plans and their features are data.
  • Businesses can measure their return, through coupons and quote requests attached to their listing.
  • Shared content converts to engagement, because deep links open directly to the listing or article that was shared.
  • The operator runs the platform independently, with full administrative control over listings, categories, plans, content and users.

Why it worked

Directory products fail in the first six months, and they fail for a structural reason rather than a technical one: they launch empty and ask businesses to fill them. The engineering answer — making listings exist independently of owners, with claiming as a separate flow — has to be designed in at the data model level. Retrofitted later, it is a rewrite.

Our team designs for the launch condition, not just the mature one. We build the mechanics that let a two-sided product be useful before either side has arrived. We model messy real-world data properly, and we change the model when it turns out to be wrong rather than leaving unsearchable data in place for years. We make commercial packaging data rather than code, because pricing changes far more often than software gets rewritten. And we structure native applications modularly, so the tenth feature costs roughly what the third one did.

Our teams work across Laravel and modern PHP, token-secured API design, native iOS development, mapping and location data, media pipelines and subscription commerce — with the product judgement to know which of those decisions will still be constraining the business in three years.

Final Summary

A local business directory has an awkward launch condition. Consumers judge it by completeness, businesses judge it by audience, and on day one it has neither. Most directories try to sell their way out of that, recruiting businesses individually into a product that cannot yet demonstrate value — which is slow, expensive, and frequently fatal.

Our team built a platform designed around the launch condition. Listings exist as records in their own right, complete with imagery, structured opening hours, categorisation and location, whether or not their owner has ever heard of the platform. Business owners claim their listing rather than creating it, turning a high-abandonment registration into a short verification. Meanwhile, editorial content and issue-based digital editions give consumers a recurring reason to open the app that has nothing to do with whether they currently need a plumber — which is what keeps a directory installed between the occasional moments it is genuinely needed.

On top of that sits a subscription model where tiers and their features are configurable data rather than code, promotional mechanics that let businesses measure their return, reviews that build consumer trust, and a full administrative platform for running listings, content and publications. The engineering choices — structured listing data, cached catalogue reads, deep-link handling, a modular native client — are the ones that determine whether a directory is still maintainable and still fast once it holds the volume of content that finally makes it valuable.

01 — Questions

asked about this kind of project

How do you solve the cold-start problem for a business directory?

Make listings exist independently of their owners. Populate the directory from available data so it is genuinely useful to consumers on day one, mark those listings as unclaimed, and give business owners a claim flow to take ownership later. This inverts the onboarding problem: instead of asking a business to build a presence for an audience that does not exist yet, you show them a presence that already exists and ask them to take control of it.

How does listing claiming work, and how do you keep it secure?

The claimant proves they represent the business before gaining control — typically through verification against the contact details already held on the listing, such as a code sent to the business phone number or email. This is the most security-sensitive flow in a directory product, because control of a listing means control of how a real business appears in public. It deserves the same care as a password reset, and for the same reason.

How should opening hours be stored in a directory?

As structured data, not free text. Real schedules vary by day, include multiple periods, and have exceptions and closures. Free text cannot be searched, filtered by "open now", or displayed consistently. A structured format — typically JSON per day with period entries — costs more to build and is the difference between a directory that can answer "what is open near me right now" and one that cannot.

How do you monetise a directory without damaging it?

Never gate existence. If only paying businesses appear, the directory is incomplete, consumers notice, and its value collapses — taking the paying businesses' return with it. Monetise prominence, enhanced content, promotional mechanics and analytics instead. Paid tiers should make a listing better, not make it exist.

Should subscription plans be configured in code or in the database?

In the database, with plan features as their own records. Pricing and packaging in a young directory business change repeatedly in the first years, and every change that requires a deployment slows the commercial team down and adds risk. Making tiers data lets the operator experiment with packaging without engineering involvement.

How do you keep users engaged with a directory between visits?

Add content value that does not depend on directory need. People search a directory occasionally and by necessity; they read content habitually. Editorial articles, published editions or community news give the app a reason to be opened in the weeks when nobody needs to find a business — and an app that gets opened is an app that is still installed when someone finally does.

Why does deep linking matter for a directory app?

Because directories grow through sharing. Someone recommends a business, sends the link, and that link must open the listing itself — not a home screen, and not a web page asking the recipient to install an app and then search manually. A dedicated URL handling layer turns each shared listing into a direct entry point, which compounds over time.

How long does it take to build a directory platform?

Scope determines it, but the sequencing is consistent: listings, categories and search first, then claiming and business management, then reviews and location features, then monetisation, then content and publishing. Getting a populated, searchable directory into consumers' hands early matters more than feature breadth, because the directory's value to businesses — the thing you will eventually charge for — is entirely a function of consumer usage.

03 — Similar project?

describe what is different about yours

Build yours.

Tell me what exists, what you need and the deadline. Fixed price for a defined scope, or hourly from $10 with a written estimate first.

Ahmedabad, India · IST (UTC+5:30) · --:-- IST · Mon–Fri 09:00–18:00 IST · US & EU overlap daily

No newsletter, no CRM. Just a reply.