Yasiru Senarathna Logo
Case Study | Founder & Product Design

OpenHire.lk

Designing the listing flow for a service-ads platform around two things that usually fight each other staying free and open to everyday professionals, and not collapsing into the spam every other free-listing site eventually does.

Date FoundedJune 2025
My RoleFounder, Product & UX, Developer
StatusPublic Beta - Paused
StackNext.js, Firebase, Vercel
OpenHire.lk Hero Interface
01. The Problem

Service providers in Sri Lanka were posting tutoring, freelance, and wedding-vendor ads on platforms built to sell phones and furniture.

I noticed this firsthand before I ever opened a code editor. General classifieds sites like ikman.lk and saru.lk are built for physical-item listings a phone has a fixed price, a condition, and a single photo that tells the whole story. A service doesn't work that way. A tutor needs to describe subjects and availability, a freelancer needs to show a portfolio, a wedding vendor needs to communicate trust before a stranger calls them. None of that fits cleanly into a listing template built for objects, so service ads on those platforms end up as awkward, under-described, and easy to scroll past.

That gap was the entire premise: build a platform that only does service ads, structured around what a service actually needs to communicate, with low enough friction that a tutor or a part-time freelancer would actually use it instead of falling back to a Facebook group post.

* Public beta listings are free. Paused for now; see closing note below.

02. Research

No budget for a formal study, so the research was the gap itself

There was no research budget and no existing user base to interview this started as a personal observation, then I went and checked whether it held up against what was actually live in the market.

~/research$ catikman.lk.tab
ikman.lk

Sri Lanka's largest classifieds site built around items for sale. Service categories exist but use the same listing template as a used car: one price field, one condition field, no structure for availability or qualifications.

Nobody had built a listing form around what a service provider needs to say qualifications, availability, pricing type instead of what an item needs to say.

Who this had to work for

Two working profiles came directly out of that gap analysis, and every decision in the listing flow got pressure-tested against both of them.

The Provider.

A tutor, freelancer, or wedding vendor who wants to be found without paying for ads or maintaining a website. Needs to post in minutes, not learn a dashboard, and trusts the platform more if their listing doesn't sit next to obvious spam.

Worker
Pressvia Interface Overview

The Searcher.

Someone who needs a tutor, photographer, or repair person this week, not someday. Needs to tell a real listing from a fake one fast, because the entire value of the platform collapses the moment that judgment call gets hard.

User
Pressvia Interface Overview
03. Listing Flow & Spam Protection

Free and open invites spam. The fix had to live in the posting flow itself, not in moderation after the fact.

Every free-listing platform eventually has the same conversation with itself: openness is the entire value proposition, but openness is also what spam exploits. I didn't want to solve this with a moderation queue, because that just delays the damage a fake listing still goes live, still gets seen, and only gets pulled after a real user already wasted time on it. I wanted friction at the point of posting, not cleanup after.

That meant the listing flow had to do three jobs at once: stay fast enough that a tutor posting their first ad doesn't bounce, stop a bot or a spam account from flooding the platform, and give a searcher enough signal on a listing to trust it before they ever call the number on it.

Post-a-service flow where friction was placed on purposeWorkeropens dashboardRate limit checkmax 5 servicesper hourBlocked try laterno listing createdFill listing formtitle, pricing type,availability, locationAdd up to 3 imagescompressed client-side0.5MB · max 1200pxinvalid type/size → rejected before uploadFirestore rulesvalidate fields +ownership checkLivelistingSearcher reports listingspam / fake / duplicate → admin review queueFriction is placed before publish, not after reporting is the safety net, not the first line

The rate limit is the part that actually stops abuse five listings an hour is enough room for any real provider to manage their ads, but it makes flooding the platform with fake listings slow and unrewarding. Image compression and the 3-image cap kept uploads predictable for both the user's connection and Firebase Storage costs. The report flow spam, inappropriate, duplicate, or other, routed straight to an admin review queue is the backstop for whatever still gets through, not the primary defense.

openhire lk
04. The Hard Tradeoff

A Colombo angel investor told me the sign-up flow was the problem. My first instinct was to defend it. I built a second path instead.

I had the chance to pitch OpenHire to Asel Gunawardana, CEO of the Lankan Angel Network. The product held up the gap was real, the spam protection made sense to him but he pushed back on one specific thing: the sign-up flow. It's only Google sign-in plus a short form, which reads as minimal to anyone who's used a dozen SaaS products. But that's not who this is for. A lot of the providers OpenHire exists for an older tutor, a tradesperson, someone who isn't online all day find even a short structured form like a wall.

My first reaction was to defend the form it really is short. But that reaction was about being right, not about whether the provider gets listed. The form wasn't the problem to fix; it was the only path that existed. So instead of stripping the existing flow down further and risking the spam protection it was built around, I added a second one: OpenHire Agent Mode.

Two paths to the same listingSomeone wants to listSELF-SERVEAGENT MODEGoogle or email sign-increates an accountFills listing formself-directed, own paceMessages or calls OpenHireno account neededAgent fills the formfrom what they describeSame rules apply either way5 free listings · same Firestore record · same review queueLive listing

Agent Mode doesn't bypass spam protection it relocates the data-entry step. Someone describes their service over chat or a call, and an OpenHire agent fills in the same structured form a self-serve user would, then submits it under the same rate limit and review path. No new account type, no separate set of rules, no quietly weaker version of the product for people who find forms harder. The pitch-room feedback didn't tell me to change what I'd built; it told me who I'd accidentally left out of it.

05. Validation

A pitch room is its own usability test

I haven't run a moderated study on this there's no team and no budget for it, and I'm honest about that. The validation that actually shaped the product came from putting it in front of someone whose job is to find the hole in a pitch: an angel investor sitting across the table, not a friendly beta tester.

That's a harsher filter than most informal usability tests, because the feedback isn't "this felt a little confusing" it's "this is the reason I wouldn't back it." The sign-up friction point was exactly that kind of feedback, and it's the reason Agent Mode exists at all instead of staying a backlog idea.

06. Technical Architecture & Security

Built solo, so the stack favored shipping speed over flexibility I wouldn't use yet

Every choice here was made to keep one person able to ship, secure, and maintain the whole platform without a team — managed infrastructure over custom servers, and security enforced at the rules layer rather than bolted on afterward.

stack.ps
next.js + typescriptfrontendDeployed on Vercel's edge network for fast, predictable page loads.
firestoredatabaseHolds users, services, favorites, reports, and ratings, schema enforced through security rules, not just application code.
firebase authauthEmail and Google OAuth; Cloud Functions set custom claims on signup for role-based access.
vercel edgedeploymentZero server management, automatic scaling for a solo-maintained product.

Security protocol

Standard web security headers combined with strict Firebase rules to protect against XSS, clickjacking, SSL stripping, CSRF, and data exfiltration.

security-audit.log
security-headersA+

CSP, HSTS, and Permissions-Policy configured at the edge.

mozilla-observatoryB

Independently verified, not self-reported.

firestore-rulesENFORCED

Ownership and role checks run on every read and write, not just in the UI layer.

auth-guardsSERVER-SIDE

Custom claims gate admin and worker actions, so role checks can't be spoofed from the client.

07. Where It Stands

Shipped, validated against real feedback, currently on hold

06
5

Free listings per provider held constant across both onboarding paths

self-serveagent mode
2

Onboarding paths now live, self-serve and Agent Mode

FA+
A+

Security headers rating, with Firestore rules enforcing ownership and role checks on every write

OpenHire is currently paused while I complete my final year research project I haven't had the time to give it the attention a public beta deserves, so it's on hold rather than being run half-heartedly. The decisions that mattered are already in place: the rate-limited, spam-resistant listing flow, and Agent Mode as a second path for the providers the first one wasn't built for.

The next iteration once I'm back on it is less about adding features and more about testing Agent Mode at real volume, since right now it's validated in principle but not yet at scale.

openhire lk

Got a messy platform or a new idea?

Skip the guesswork. Pick a channel below and let's figure out the smartest UX strategy for your business goals.

[@ _ @][^◡^]

Email

Drop a message and I'll get back to you within 24 hours no templates, just a real reply.

SEND A MESSAGE ↗SEND A MESSAGE ↗
[= = =][^ - ^]

LinkedIn

Follow along for case studies, design breakdowns, and occasional thoughts on building better products.

CONNECT ↗CONNECT ↗