I am Oscar Napoles. These are businesses I looked at closely, and what I changed. Not all of it was built, and the ones that were not say so.
RUNNING — built and in use. PROPOSED — designed and presented, not deployed. EXERCISE — a problem I set myself. No client, no build.
A general contractor of any age carries four kinds of paper that never stop mattering: subcontract agreements, submittals and RFIs, change orders, and closeout manuals. The agreements are signed PDFs, sometimes scanned, sometimes photographed on a truck seat. The submittals reference spec sections by number. The change orders reference the agreements. The closeout manuals reference everything and are opened four years later by somebody who was not there.
None of it is filed badly. It is filed by project, which is the only way anybody has ever filed it, and it is the correct way to file it while the project is running. The trouble starts when the useful question stops being about a project and starts being about a clause, a price, or a trade. Then the folder structure is answering a question nobody is asking any more, and the only index is a person.
The money is in the bid. A firm rebids the same scopes for years, and what makes the next bid good is what the last eight taught you: what the excavation actually cost against what was quoted, which subs came in over, which clause got argued about and how it was settled.
That knowledge sits in scans. Scans are not searchable in any way that answers a question about a clause. So the firm's most valuable document set is the one with the worst retrieval, and its least valuable — this week's email — has the best. The estimator who has been there twelve years bridges the gap, and he does it fast enough that nobody counts what it costs. What it costs is that the firm has one copy of its own history, and it goes home at five.
Put everything in SharePoint and turn on search.
It would find the documents whose text layer happens to be good, which is the recent ones, which is the half you did not need help with. It matches words rather than meaning, so a search for "liquidated damages" misses the agreement that says "delay damages" and the one that spells it out in a paragraph without ever using the phrase. It returns files, not passages, so the answer is still sixty PDFs and an afternoon. And it says nothing about how confident it is, which for a scanned corpus is the only number that matters.
The approach I worked out has four parts, and the order matters.
Ingest would be typed before it is parsed. An agreement, a submittal and a change order are different shapes, and pretending otherwise is why generic ingest produces generic answers. Each file would carry metadata pulled at ingest: project, date, trade, spec section, counterparty.
OCR would produce a legibility score per page, not just text. Pages below the threshold would go to a review queue instead of silently entering the index as garbage, because a bad page that looks like a good page is worse than a missing one.
Chunking would follow the document's own structure: clause boundaries in agreements, section numbers in specs, line items in change orders. Cutting a contract every five hundred characters splits the clause you are looking for across two passages and neither one answers.
Retrieval would filter on metadata before it searches meaning. "What did we quote this customer in 2023" is a date-and-counterparty filter with a semantic search inside it, and running it the other way round returns everything that sounds similar from twelve years.
Every answer would carry the file and the page. Where the filtered set comes back empty or the scores are low, it would refuse and say which filter emptied it.
The assessment costs money before anything works, and it can come back saying half the pre-2018 scans are not legible enough to be worth indexing. That is a real outcome and the honest reason to run the assessment first rather than sell the deployment first.
The system would refuse more often than a chatty one, and refusal feels like failure to a person who has just typed a question. I would take that trade every time in a business where a wrong clause is a claim. And per-person access has to be set up before any of it is useful, which is a day of somebody's time that nobody budgets for.
Exercise. Nobody paid for it, nothing was built, and no construction firm has run this. If you are one and you want to know whether your own scans clear the bar, that is the $400 document assessment on the catalog, and it is the only way to find out.
A clothing brand selling one heavyweight hemp-cotton hoodie, built around a small circle of people who wore it and talked about it. Orders arrived because somebody saw somebody. The brand knew this — it is the whole reason the brand works — and had no machinery for it. When a friend drove three sales, the owner knew it the way you know things in a small town: roughly, and after the fact.
Nobody had fixed it because nothing looked broken. Sales came in. The people doing the selling were not complaining, because they had never been promised anything to begin with.
The most effective sales channel was the one with no record. A repeat customer who brings three buyers costs nothing and converts better than any ad, and the brand's only way to reward that was to remember it. Memory does not scale past a dozen people, and a promoter who suspects they were forgotten stops promoting — quietly, without telling you.
Sign up for an affiliate SaaS and give everyone a dashboard.
Those platforms are built for influencer programs with hundreds of strangers, and they price and onboard like it. For a circle of a dozen known customers, the dashboard is friction: another login, another app, a wall between the brand and people who already text the owner directly. The tool would replace a relationship with an interface, and the relationship was the asset.
Each promoter would get one personal code, tied to their name in the storefront's own discount system — no separate platform, no login. Every order carrying a code would land in a payout record the owner reads: who, what order, what is owed. Attribution would run on the storefront platform itself; what I designed is the code scheme and the payout reconciliation on top of it, so the owner settles up from one page instead of a spreadsheet and a memory.
The promoter's experience would stay exactly what it already is — texting a friend a code — except the code now proves what it produced.
Codes undercount. Somebody buys because of a promoter and forgets the code, and that sale credits nobody. I would accept that, because the alternative — link tracking and cookies — measures better and feels like surveillance inside a friend group. An undercount that everyone trusts beats a precise number nobody understands. And the owner still has to actually pay out on a schedule; the record removes the excuse, not the obligation.
Proposed. The storefront is live and selling. The code scheme and payout record are designed and presented, not yet in production use. No figures on this page are results.
The truck had no website. It had a Facebook page with 18,500 followers and a post every morning saying where it would park. That post was the entire address system of the business.
A post reaches some fraction of a page's followers and then falls down the feed. The next morning it has to be written again. So the business re-earned its own location every day, from zero, in front of an audience it had already spent years building. Nobody had fixed it because from the inside it did not look like a problem. It looked like posting.
Catering is where the money is. One booked event is worth more than a good night at the window.
Catering requests arrived as Facebook messages, in the same thread as "are you open" and "where are you parked today." The highest-value enquiry in the business queued behind the lowest, answered by the same thumb between orders. How many events were lost that way is unknowable. That is the characteristic of this kind of loss and the reason it survives for years. Nothing shows up missing.
Build a food truck website: menu, photos, an About page, a contact form.
It would sit still. The one thing this business changes daily — where it is — would be the one thing the site could not answer, so the Facebook post would remain the address system and the site would be decoration. A contact form marked "contact" would collect the same mixed queue the message thread already collects, one inbox further from the owner's thumb.
A permanent link that answers "where" without being asked. Location and open state would sit at the top of the page, and she would set both from her phone without signing into anything. She would post the same link every day instead of a new address. The post would still decay. The link would not.
Catering off the message thread and onto its own path. Date, headcount, address, service window, and whether the site has power. Those five answers are what turn a conversation into a quote, and a form would collect them in one pass instead of six replies across two days. It would land in a separate inbox with its own notification, so it could never queue behind the churro question.
She would have to press the button when she parks. If she forgot, the page would be wrong, and a wrong address costs more than no address. So the page states when the location was last set, and if the morning passes with no update it says so instead of showing yesterday's corner.
Proposed. Designed and presented to the owner; not deployed. The follower count is the business's own public figure, not a result.
A mobile detailer who drives to the vehicle. Every job was quoted by phone, and nearly every quote was assembled from the same four inputs: vehicle size, package, add-ons, and how far away the vehicle sits. The person answering those calls was the same person with both hands inside somebody's car.
Nobody had fixed it because each call was short and the price came out right. What the calls cost was not visible on any one of them — it was the callers who reached voicemail mid-job and dialed the next detailer on the list.
The revenue is in the booked job, and the booking depended on being reachable at the exact moment a stranger felt like asking. A detailer working is a detailer not answering. The business's busiest days were therefore its worst days for winning the next job, which is the arithmetic backwards from how a schedule should compound.
Put a "request a quote" form on a website.
A form that emails the owner is the phone call with extra steps: the customer still waits, the owner still answers between jobs, and the quote still arrives after the moment has passed. The prospect who wanted a number at 9pm gets it at noon, from someone else. The form moves the queue; it does not remove it.
The four inputs, turned into four taps. Vehicle size, package, add-ons, location — each one a choice, not a text field, because choices can carry prices and text cannot. The number would appear on screen the moment the fourth tap lands, from a price table the owner sets and edits himself. Booking would sit directly under the number, so the distance between "that seems fair" and a slot on the calendar is one screen.
The owner's phone would stop being the price list. It would get one notification per booked job, which is the only call that was ever worth interrupting a job for.
A published price table ends price flexibility. The awkward vehicle, the filthy interior, the job he would have quoted high on instinct — the screen quotes it flat. The design accepts that, and puts one escape hatch on the confirmation: the owner can adjust on arrival for stated reasons, printed in advance. Fewer surprises for the customer, one lost lever for the owner. And the price table only stays honest if he edits it when his costs move, which is a habit, not a feature.
Proposed. Built as a working demonstration; not deployed for the business. No figures on this page are results.
Names are withheld until a client asks to be named. There are no counts or percentages on this page, because I cannot show you the arithmetic behind them.