Nicolas Karam — Beirut, open to relocation
I buildwhat businessesrun on.
Nine production systems for real businesses. Every one below is running — the screens on this page are live, not pictures.
See them run00 — Daawa · daawa.us · my own business
Invitationsthat open.
Press play on any of these. They're the real invitations, running live inside the phones — envelope, music, countdown and all.







01 — Lea Press
A whole shop.
Run daily by someone
who's never opened
a terminal.
Not a catalogue. Stock products, a print-and-copy service with file upload, and a gift box you build from real cut-out photographs — three different kinds of order that check out as one delivery, guest or not.
- Print & Copy — upload a file, pick paper, binding and add-ons
- Create Your Gift — cut-out photos composited inside a real box
- A 3-step map wizard over a Lebanon gazetteer drives delivery zones
- Guest tracking through a
SECURITY DEFINERfunction — a stranger reads exactly one row - Installable PWA; a new order pushes to every admin device with the app closed
This Week's Deals
Sketchbook A5$9.00Categories
NotebooksPensPaperArtOfficeGifts
02 — Arthro Leb
| Catalogue | Product Name | Out | Back | Used | Stock |
|---|---|---|---|---|---|
| AL-1120 | Tibial baseplate, size 3 | 2 | — | — | — |
| AL-3340 | Femoral component, size 4 | 2 | — | — | — |
| AL-5512 | Poly insert, 10 mm | 4 | — | — | — |
| AL-7708 | Fixation screw, 35 mm | 8 | — | — | — |
| AL-9004 | Suture cartridge | 8 | — | — | — |
03 — Karam Chicken Lab
=E2-(B2+C2-SUMPRODUCT(Recipes!$C$2:$C$40,Sales!$D$2:$D$40))| A | B | C | D | E | F | |
|---|---|---|---|---|---|---|
| 1 | Item | Opening | Purchased | Expected | Counted | Variance |
| 2 | Chicken breast | 18.40 | 24.00 | 19.22 | 15.20 | |
| 3 | Bread loaves | 60 | 120 | 75 | 73 | |
| 4 | Garlic sauce | 6.10 | 8.00 | 8.31 | 8.25 | |
| 5 | Pickles | 4.20 | 5.00 | 5.62 | 5.60 | |
| 6 | Fries | 22.00 | 30.00 | 25.50 | 25.40 |
He knew stock was walking out.
Now he can prove it.
Every dish knows its recipe, so the day's sales say exactly what should be left. The gap between that and the shelf is the evidence.
What happened today
- Sold 40 kg of mushrooms, paid cash$320
- Bought 60 kg of substrate on account$145
- Paid the electricity bill$78
- Wages for two pickers$122
Plain language. Nobody is asked what a debit is.
General journal
| Account | Dr | Cr |
|---|---|---|
| Totals | 0 | 0 |
Corrections reverse. History is never edited.
04 — Shrooms Est.
Real double-entry.
Nobody has to know
what a debit is.
Staff record what happened in plain language. The same taps become a general journal an accountant can audit. Corrections reverse; history is never edited.
Figures on screen are invented — the farm's real books stay private.
05 — MADAREK Consultants
Fourteen buildings.
One day. Never built
a Gantt before.
Weighted by floor area, so a big building running late outranks a small one that's finished. Switch the phases and watch the two headline numbers disagree — that disagreement is the whole reason it was built this way. It went straight into an executive presentation.
Two-phase residential programme — 14 buildings
06 — Also shipped
Two more, in daily use.
- Karamel CateringChromis POS on MySQL, self-taught, for plat-du-jour delivery orders.
- Frenchie ClosetBoutique catalogue — categories, colour variants, per-item pages and an owner-facing admin.
07 — How one person ships this much
I got deliberately good at building with AI.
Nine systems. One person. Eighteen months. No engineers hired.
I treat it as a system with a cost model, failure modes and a discipline — my own context files, task batching, and a written record of every failure class so nothing is paid for twice. The engineering judgment is mine. The leverage is the method.
Happy to walk through it in an interview.
08 — What it cost me to learn
Five things that broke.
Real incidents. Guess the cause, then open it.
A cleanup script freed unused images from storage by comparing every stored file's name against the tail of every image URL in the database. Anything referenced by nothing was deleted. It ran, and it deleted 211 files that were very much in use.
The matching logic looked right, and it worked for most files. What was different about the 211?
What was actually happening
Their URLs carried a cache-busting query string and an encoded slash: …/cutouts%2F<id>.webp?v=3. Compared against a storage key, that matches nothing — so every one of those files was classified as unreferenced. A URL is not a storage path, and the conversion between them belongs in exactly one function.
What I do differently now
The rule I now apply everywhere: before any bulk delete driven by "what is referenced", verify the references resolve first. A few misses are normal; if many miss, the matching logic is wrong — not the files — and the script must refuse to delete and say so. That single check would have prevented all of it. Two confirmations for irreversible scripts, report-only by default, and a backup before the destructive step rather than after being asked.
Delivery pricing had a validity guard that looked entirely reasonable: Number.isFinite(Number(price)). It passed review several times, because reading it, it's fine.
A delivery zone whose price was never set, or that an admin cleared in a form, charged what?
Number.isFinite(Number(price)). It passed review several times, because reading it, it's fine.What was actually happening
Nothing. Number(null) and Number("") are both 0, and 0 is a perfectly finite number — so a missing price validated cleanly as free delivery. Nothing errored and nothing logged. The only symptom would ever have been revenue that didn't add up.
What I do differently now
Wherever missing and zero mean different things, I now test for absence explicitly before parsing, and never reach for falsiness — 0 is falsy and usually valid. It also changed how I verify: I found this within a minute of writing the first real test for that module, after repeatedly "reviewing" it by reading it. Reading code confirms what you expect; running it tells you what's true.
Minutes after a deploy, the site stopped loading on the owner's phone. Every browser, private mode, the installed app — all dead. Desktop ran the same build perfectly. He was certain the deploy had broken it, and the obvious move was to roll back immediately.
Rolling back would have been wrong. Why — and what proved it?
What was actually happening
His mobile carrier had lost its route to the CDN. The deploy was fine. What settled it was testing something we had never touched: the CDN's own marketing site, which failed on his phone in exactly the same way. A rollback would have destroyed a good build and fixed nothing, and the real cause would have persisted.
What I do differently now
Before rolling back, I find a control case outside my own change. "It broke right after my change" is a correlation, not evidence. The related habit: two derivations that share an assumption are one derivation — during the deletion incident above, a database query and the script agreed with each other precisely because both had the same bug.
The hosting plan gave 1 GB of storage. Watching that number, the shop had years of headroom — plenty of room for photographs of every product.
The site would have died months earlier. Of what?
What was actually happening
Bandwidth. The same plan allowed 5 GB of transfer per month, and pages were serving 4.6 MB of images each — about a thousand page views before it stopped. The cap that bites is rarely the one you're watching.
What I do differently now
I measure the real bytes before optimising, and I check the transfer quota whenever I check a storage quota. Sampling the actual stored photos gave 195 KB average and a 6.3 MB worst case, which turned "images feel heavy" into a specific problem — and proved the fix afterwards. Resizing in the browser at upload time cut it ~70% with no visible loss, because the win was the codec, not the downscale. Done before the data-entry phase, not after.
The checkout's submit button stayed disabled until the form was valid — a standard pattern, and it prevents bad orders. It sat on the one screen that turns a visitor into money.
What does a customer with one field wrong actually experience?
What was actually happening
They tap the button, nothing happens, and nothing on screen says why. It's a dead end on the most valuable page in the shop, and the only person who ever noticed was the owner. Worse, a related path took a malformed email address, stored it as nothing, and placed the order anyway — so the customer got no receipt and no hint that anything had gone wrong.
What I do differently now
Keep the control enabled and let the click explain the problem: name every missing field, mark them, scroll to the first one. Never discard bad input silently — an empty optional value is fine, a malformed one blocks. And I choose the failure direction deliberately: for a phone field spanning 243 dial codes, a strict format rule eventually rejects somebody's real number, and a blocked checkout is a lost sale while a bad number is just a phone call. A minimum digit count catches what actually happens without that risk.
09 — Before the code
Six years keeping other people's systems alive.
A bank's infrastructure, then a flagship venue in Riyadh.
Operations Coordinator & IT Support
2024 – 2026Courchevel — BLVD World · Riyadh, Saudi Arabia
- Ran onsite IT for Wi-Fi, POS and printers across every service area of one of Riyadh's flagship entertainment venues, through peak hours.
- Supervised 35 staff across reception, training and ski-fitting.
- Built a custom Airtable scheduling system combining availability, roles and task assignment — 40% more efficient scheduling.
- Allocated sessions for 19 ski instructors by tracking workload across 6 daily sessions, keeping the split fair.
- Built a per-instructor client feedback system and sent the CEO daily Excel reports from it.
- Wrote the IT SOPs and user manuals that cut recurring support issues.
System Administrator
2020 – 2024Banque BEMO SAL · Lebanon
- 20+ support tickets a day at a 90% first-call resolution rate, for 250 users across 3 branches.
- Ran Active Directory, Microsoft 365, Exchange and Outlook for all staff.
- Imaging and deployment, hardware inventory, endpoint security with vendors.
- Daily tape backups and data-integrity monitoring for business continuity.
Contracted to digitise 1,500 client files — scanning, CRM entry and KYC processing into Laserfiche and the SVS signature platform. Finished in 45 days. The bank created a permanent IT position for him off the back of it, with no formal IT degree.
Smaller things, also built
Supplier catalogue, meat & poultry import
3-sheet Excel system with 2,000+ products pulled from international supplier brochures — barcodes, QR codes linking to supplier sites, country of origin, categories, all driven by dynamic combo boxes off a master sheet.
Reception ↔ fitting-room comms
Spotted a recurring bottleneck between two departments at Courchevel and built the link between them himself, cutting delays in client flow. Nobody asked for it.
30-machine gaming network
A 30-computer LAN built in one day — Windows installs, full software configuration, networking, all machines operational.
Education
B.S. Business Administration & Finance — Sagesse University, Lebanon (2016–2020)
Certificates
- Oracle Financial Cloud: General Ledger — Certified Implementation Professional (2023)
- CompTIA Network+ (2023)
- Elements of AI for Business — University of Helsinki (2025)
Languages
Arabic (native) · English (fluent) · French (conversational)
Technical
10 — Work with me
Let's build yours.
Still running on spreadsheets, phone calls and someone's memory? That's the job.
