Keenan Pereira My CV

Insights

64 problems from real projects: what broke, what fixed it, and the number that shows it worked.

Every write-up: the problem, the fix and its key number
InsightProblemFixKey number
Non-brand clicks are the SEO number that mattersSEO, Data & BI ProblemMost Google clicks came from people already searching “AHA”, which hid real SEO progress. FixA Search Console scorecard that splits brand from non-brand and tracks rank and blog share. +183% non-brand clicks
A blog hub that builds its own topic pagesSEO, Web ProblemA hand-written list of 11 posts, with no topics and almost no links to sales pages. FixOne post list and one taxonomy generate the hub, topic pages and schema. 11 → 48 posts in the Journal
A thank-you page that liedLeads & CRM, Web ProblemFailed leads still showed “thank you” and counted as ad conversions. FixEvery form now confirms the lead saved, with tests that force each failure. 7 / 7 forms verify the save
The first-week SEO audit that read the site like a crawlerSEO, Web ProblemCrawlers saw duplicate titles, no FAQs, no form and facts that disagreed. FixFix the HTML that ships, then have every build check it before release. 21 → 0 pages sharing a duplicate title
Turning showroom pages into local landing pagesSEO ProblemThin centre pages, one unknown to Google, and three pages chasing one Mumbai query. FixA real local page per centre, and one page that owns the Mumbai query. 362 → 999 words, Lower Parel page
The slow part was the server, not the pagePerformance, Web ProblemPages failed Core Web Vitals for real users while lab tests passed. FixDo the arithmetic first, fix what the repo controls, and test every page on every device. 96% of the LCP wait came before first paint
Measuring whether AI assistants recommend youSEO, AI & LLMs ProblemNobody could say whether AI assistants named AHA when buyers asked. FixA fixed 12-prompt panel on two engines, then crawler access, llms.txt, one Organization and Bing. 5 → 7 of 24 panel answers name AHA
Where did this lead come from?Leads & CRM, Web ProblemNo website lead in Zoho could be traced to the page it came from. FixEvery form now sends its page, the visit’s first page and a callback time; 90-day ad tags are going live. 7 / 7 forms record the lead’s page
The sitemap that quietly hid the whole blogSEO, Web ProblemA hand-kept sitemap drifted, then silently dropped the entire blog. FixGenerate it from the built pages and blog data, and check every URL on deploy. 38 → 108 URLs in the sitemap
What a fortnight of Google Business Profile posts taught usSEO ProblemBusiness Profile posting was ad hoc, and one early reading looked like a long tail. FixA tagged post bank on a fixed cadence, read three times before the plan changed. +93% → 0% first four posts: ten days, then five
The hero image that waited in linePerformance, Web ProblemHero images took 5.4 s on phones, queued behind 23 other images. FixPreload the hero, lazy-load the rest, and content-hash every asset. −80% LCP on /solutions
Product pages led by specificationsWeb, Leads & CRM ProblemProduct pages repeated their facts as bullets and had no specifications. FixOne data file renders each page’s spec table, related products and PDF catalogue. 2,037 px of bullets, and no spec table
Writing about Apple without breaking Apple’s rulesWeb, SEO ProblemManagement wanted the site to feel Apple-ish, with none of the trademark risk. FixEncode Apple’s trademark rules in data, templates and a wording check before writing copy. 6 of 6 Apple pages indexed within days
A path-traced showroom in a TV browserWeb, Performance ProblemThe website concept’s 3D tour of the experience centre was hard to drive in a live demo. FixPath-trace every room offline, and let the TV only turn the camera and crossfade the light. 22 renders, path-traced offline in about 2 hours
A sales pitch that plays itselfWeb ProblemEvery scene of the showroom pitch waited for someone to press on. FixSlides that play themselves and pause only on a To remember slide. 15 → 5½ min walkthrough, with a presenter clicking
Product films recorded from the app, with no ffmpegWeb, Performance ProblemDemo videos were wanted to send, in lengths that kept changing from 20 seconds to 90. FixRecord the app’s own films in headless Chrome on a virtual clock, and encode them in Chrome. 87 s lock film, no feature left out
The BACK button that kept walking out of the appWeb ProblemA few BACK presses in a row could leave the showroom app for an old cached page. FixBank one history step per real button press, and serve every page fresh. 1 per press history steps banked
From sleep loop to portable screensaverWeb ProblemThe TV’s idle loop was wanted inside another app, without the login, the map or the CRM. FixBuild a standalone page from the TV’s own code, and stop the build if that code changes shape. 22 slides a pass on the TV, about 4½ minutes
Building for a 2 GB TV and a remote with no pointerGIS & maps, Performance ProblemA map of 500 buildings had to run on a 2 GB TV, driven by a D-pad. FixA TV mode: zone jumps, overscan calibration, a lighter renderer and a 6-minute story. −35% browser memory
Five bugs a data audit caught before anyone made a decision on themData & BI ProblemDashboards looked plausible, but leads, spend and channels were each off. FixRecompute every number by a second route before trusting it. 2.00× → 1.00× Meta lead count
The shared token that switched off the website’s leadsLeads & CRM, Data & BI ProblemAbout nine systems shared one Zoho refresh token, and any could cancel another’s access. FixThe BI got its own refresh token and shares one access token an hour. ~30 min website leads stopped, once
A 15-minute warehouse that runs on one PCData & BI ProblemThe BI read a hand-synced copy that reported failed syncs as successes. FixRead-only pullers feed a private warehouse every 15 minutes, from one PC. 15 min refresh, while the PC is on
One meaning per number, so the screens stop arguingData & BI ProblemTabs and the Ask chat used different rules for the same number. FixWrite each rule once with its date, and check every copy against it on every change. 54 metric formulas, one definition each
A phone page that tells consultants who to call nextData & BI, Leads & CRM ProblemConsultants needed to know who to call next, not another screen of totals. FixA read-only phone page per consultant, copied from a whiteboard sketch, with a ranked call list. 7 days with nothing logged puts a deal on the list
A wrong pin is worse than no pinGIS & maps, Data & BI ProblemCRM building names were messy, and some deals were pinned in the middle of India. FixMerge spellings by hand, take the pin the data agrees on, and accept new pins only after four checks. 507 buildings on the map
Planning billboards around where the leads areGIS & maps, Data & BI ProblemA billboard inventory listed sites and rates, but said nothing about where AHA’s leads are. FixGeocode every site, then rank it by the leads within 2 km. 93 sites geocoded from a spreadsheet
Electrical plans that open fast and stay sharp on a TVPerformance, Web ProblemA plan’s PDF took seconds to open on the TV, and zooming in blurred the drawing. FixPre-render every page as an image, and redraw from the PDF only when someone zooms. 1,800 px pre-rendered page, about 200 to 350 KB
Giving a TV remote a mouse pointerGIS & maps, Web ProblemA map wants a mouse, and a TV remote has four arrows and OK. FixA pointer that eases, curves and settles, with OK and BACK moving one level at a time. 3× drag threshold for the air mouse
A phone as the TV remote, with voice searchGIS & maps, Web ProblemA full-screen map on a TV needed a way to find one building by name from across the room. FixA phone page sends voice searches over Supabase Realtime, and a fuzzy matcher finds the building. 4 speech guesses scored per search
What buyers really ask on sales callsAI & LLMs, Leads & CRM ProblemCall transcripts held what buyers ask, in noisy Hinglish nobody could read at scale. FixHaiku pulls question-and-answer pairs from each call; Sonnet clusters them across calls. 5 to 6 buyer questions per call
Asking AI assistants about AHA without saying AHAAI & LLMs, SEO ProblemNobody knew whether AI assistants named AHA when buyers asked them for a company. FixAsk 31 buyer questions without AHA’s name, score every answer, and brief the gaps. 31 buyer questions, AHA’s name removed
Recovering building names from addresses and plan PDFsGIS & maps, Leads & CRM ProblemHundreds of deals had no usable building name, so the map couldn’t group homes by building. FixMine the address text with a geocoder, then have Claude read the plan PDFs for the rest. 633 / 711 building names recovered from address text
An ads agent that grades its own adviceAI & LLMs, Data & BI ProblemAds advice is only useful if someone checks, a week later, whether it worked. FixA Claude agent suggests at most 8 changes, a person applies them, and the next run grades each one. ≤ 8 recommendations per weekly run
A nightly sync that survives its own failuresData & BI ProblemOne flaky API or expired token could hold back the whole day’s data. FixCore steps stop the run, optional steps only warn, and 28 checks grade every run. 16 of 25 steps that can fail without stopping the run
Mapping a whole market when the API stops at 60 resultsGIS & maps, Data & BI ProblemGoogle’s Places search stops at 60 results per query. FixA quadtree sweep with ID-only requests, then a greedy set cover for details. 1,176 firms mapped in Mumbai
Telling an automation firm from a copier dealerData & BI Problem“Automation” also matches copier dealers, software houses and institutes, and many real firms have vague names. FixCheap name and category rules first, then score each firm’s own home page. 27% of the Mumbai list got in on website text
Buying place details with a greedy set coverData & BI, GIS & maps ProblemPaying for details on every search would have bought most places several times over. FixSweep for free IDs, then buy the result pages that cover the most places still needed. 49,695 sweep searches, all the free ID-only kind
Thirteen keywords in Mumbai, six for the rest of IndiaGIS & maps, Data & BI ProblemThirteen keywords at Mumbai’s depth across India meant far more squares and places to pay for. FixMeasure each keyword’s unique finds in Mumbai, then test cheaper split rules on the saved results. 6 of 13 keywords kept for India
A review sheet instead of a silent filterData & BI, GIS & maps ProblemA filter that drops every doubtful result hides its own mistakes. FixGive doubtful firms their own sheet, and record on every row why it’s there. 787 doubtful Mumbai firms kept for review
Tracking every enquiry without slowing the page downWeb, Performance ProblemTag Manager slows the first screen, and a tap on Submit isn’t a lead. FixLoad tags on the first tap, queue events in the data layer, and signal success separately. First tap when tags load, 7 s at most
Phone and pincode checks that make every lead CRM-readyLeads & CRM, Web ProblemA lead with a wrong phone number or no last name is useless to sales, or refused by the CRM. FixThe browser’s own checks, then a small script that maps each answer to the field sales uses. 7 → 12 answers to CRM fields
Designing a landing page for people who just clicked an adWeb ProblemAd visitors arrive cold, on phones, for a purchase nobody makes on impulse. FixProof before the form, a contact route always in reach, and copy in the words people search with. 12 sections, one form
Lead capture without handing the browser your CRM keysLeads & CRM, Web ProblemMy first lead form would have put the CRM keys in the page source. FixA tiny server endpoint holds the keys; the browser only posts the form. 0 secrets in the page
From 3.3 MB to 180 KB, the image diet behind a fast landing pagePerformance, Web ProblemThe ads landing page carried 3.3 MB of photos. FixA sharp pipeline: WebP, exact display sizes and lazy loading. −94% image weight
Turning “it’s too hot” into an AC command without an LLMAI & LLMs ProblemPeople say “it’s too hot”, not “turn on the bedroom AC”. FixPattern tables map complaints, comparatives and aliases to device actions. 10 comfort-complaint patterns
Keeping locks and alarms out of “everything”AI & LLMs ProblemTaken literally, “turn off everything” includes the alarm and the locks. FixThree layers drop security devices, and a guardrail decides what needs a person. 6 of 8 device types “everything” can touch
Console, offline voice and WhatsApp on one command engineAI & LLMs ProblemThree ways to talk to the house could mean three different answers. FixOne parser, guardrail and device state behind every channel. 3 channels on one parser and guardrail
48 test commands, each with a reason to existAI & LLMs ProblemA parser that works on easy sentences says nothing about hard ones. Fix48 labelled commands, reported by intent, layer and confidence. 48 test commands, each with a reason
Rules first, LLM secondAI & LLMs ProblemVague voice commands are slow, and unsafe, to send straight to an LLM. FixRules answer first, a local LLM handles the rest, and guardrails decide. 0.9 confidence for the rules to answer
The model that writes the CRM briefing never sees a customerAI & LLMs ProblemPosting CRM records to a hosted AI service was the easy route, and the wrong one. FixGive a local model totals only, and list every place the data does go. 0 customer records sent to an outside AI service
Moving the CRM maths out of Python and into PostgresData & BI ProblemEvery dashboard load pulled rows into Python and counted them in loops. FixTwelve Postgres functions do the counting and return one JSON object each. 33 → 13 database calls per dashboard load
Fitting a daily CRM briefing into one WhatsApp messageAI & LLMs, Leads & CRM ProblemThe full report was too long and too heavily formatted for a phone. FixA fixed template in the prompt, and a 1,500-character cap enforced in code. ≤ 1,500 characters, cut at a line break
Don’t let the LLM do the mathsAI & LLMs, Data & BI ProblemAn LLM summarising CRM data dropped digits and mislabelled fields. FixSQL computes every figure; the model only narrates them. ~255 lines of Python maths moved to SQL
A Zoho CRM copy that only fetches what changedLeads & CRM, Data & BI ProblemRe-downloading the whole CRM every day gets slower as it grows, and a fixed field list drops data. FixFetch only changed records, upsert them by Zoho ID, and keep each full record as JSON. 4 Zoho modules copied on every run
Why FER-2013 is hard, and what 62% really meansAI & LLMs ProblemThe faces are tiny, grey, noisily labelled and badly unbalanced. FixCount every class before training, and read accuracy against simple baselines. 7,215 vs 436 happy vs disgust training faces
A CNN that shrinks a face to 512 numbersAI & LLMs ProblemExpression cues live in a few pixels of a 48 × 48 grey face. FixFour widening convolution blocks pool the face down to 512 features, with dropout throughout. 4 convolution blocks
When more epochs stopped helpingAI & LLMs ProblemTraining accuracy kept rising while validation stalled and validation loss turned upward. FixWatch validation loss and stop where it bottoms out, around epoch 85. ~82% training accuracy at epoch 200
From webcam to Flask, one frame a secondAI & LLMs, Web ProblemA notebook model can’t see a webcam, and live frames must look like its training faces. FixThe page posts one JPEG a second to Flask, which repeats the training preprocessing exactly. 1 s between frames
Turning an emotion label into a colour and a tipWeb, AI & LLMs ProblemA bare label like “sad” tells a person nothing they can use. FixMap each emotion to a background colour and a short, kind tip. 7 emotions, each with a response
Filling a customer’s gaps from their own other monthsData & BI ProblemThousands of blanks and placeholders, in data where every customer appears eight times. FixFill each blank from the same customer’s other months, never from a column average. 12,500 customers behind 100,000 rows
Cleaning ages of -500 with rules, not formulasData & BI ProblemImpossible values everywhere, from ages of -500 to 1,798 bank accounts. FixA plain limit per column, set by what each value can be, applied after placeholders become blanks. -500 to 8,698 ages before the rules
Four feature selectors, three signals they all keptData & BI, AI & LLMs Problem44 candidate columns, most of them month and occupation flags. FixLet four models each shortlist features, then trust what they agree on. 44 → 5 features in the final forest
Four credit models compared on more than accuracyData & BI, AI & LLMs ProblemAccuracy alone can’t rank models when half the customers share one band. FixCompare on one split against a baseline, recall per band and two-band errors. 76.6% random forest accuracy
Split credit data by customer, not by rowData & BI, AI & LLMs ProblemA random row split put the same customers in both the training and test data. FixSplit by customer, so every test row belongs to someone the model has never seen. 8 monthly rows per customer