[{"data":1,"prerenderedAt":340},["ShallowReactive",2],{"writing-index":3},[4,83,152,219,279],{"id":5,"title":6,"body":7,"date":69,"description":70,"draft":71,"extension":72,"meta":73,"navigation":71,"path":74,"readingTime":75,"seo":76,"stem":77,"tags":78,"__hash__":82},"writing\u002Fwriting\u002Fscreen-io-two-weeks.md","Building screen.io in Two Weeks",{"type":8,"value":9,"toc":60},"minimark",[10,21,24,29,32,36,39,43,46,50,53,57],[11,12,13],"blockquote",{},[14,15,16,20],"p",{},[17,18,19],"strong",{},"Draft."," This article is being written. The outline below is the plan.",[14,22,23],{},"In July 2026 I built a cross-platform desktop activity tracker in a stack\nI'd never shipped: Python, FastAPI, PySide6, SQLAlchemy. Two weeks from\nempty repo to packaged builds for four platforms. This is how, including\nthe parts where AI assistance helped and the parts where it absolutely\ndidn't.",[25,26,28],"h2",{"id":27},"why-a-php-developer-picked-python-for-this","Why a PHP developer picked Python for this",[14,30,31],{},"The problem shaped the stack: OS-level hooks, a tray app, a local API.",[25,33,35],{"id":34},"architecture-before-speed","Architecture before speed",[14,37,38],{},"Service → Repository → Model, OS adapters behind Protocols, a manual DI\ncontainer. Fast is only fast if you don't rewrite it in week three.",[25,40,42],{"id":41},"what-ai-assistance-is-actually-good-for","What AI assistance is actually good for",[14,44,45],{},"Where the AI pair earned its keep (boilerplate, unfamiliar APIs) and where\nit would have quietly wrecked the codebase without review.",[25,47,49],{"id":48},"_243-tests-in-a-two-week-project","243 tests in a two-week project",[14,51,52],{},"Repos tested against a real temp database, services tested with fakes,\nand why strict mypy caught more than the tests did.",[25,54,56],{"id":55},"shipping-four-platforms-from-github-actions","Shipping four platforms from GitHub Actions",[14,58,59],{},"The build matrix, PyInstaller quirks, and macOS entitlements for screen\nrecording.",{"title":61,"searchDepth":62,"depth":62,"links":63},"",2,[64,65,66,67,68],{"id":27,"depth":62,"text":28},{"id":34,"depth":62,"text":35},{"id":41,"depth":62,"text":42},{"id":48,"depth":62,"text":49},{"id":55,"depth":62,"text":56},"2026-07-14","A Python desktop app with 243 tests, strict typing, and 4-platform CI, built fast with AI assistance and old-fashioned discipline.",true,"md",{},"\u002Fwriting\u002Fscreen-io-two-weeks","9 min planned",{"title":6,"description":70},"writing\u002Fscreen-io-two-weeks",[79,80,81],"python","ai-assisted","desktop","1UD6NoqM6v_kjkUJchV_H1MwOnBhcFPpBGnX7MXP6js",{"id":84,"title":85,"body":86,"date":140,"description":141,"draft":71,"extension":72,"meta":142,"navigation":71,"path":143,"readingTime":144,"seo":145,"stem":146,"tags":147,"__hash__":151},"writing\u002Fwriting\u002Fbuilding-saas-solo.md","Building SaaS Alone: What Four Platforms Taught Me",{"type":8,"value":87,"toc":133},[88,95,98,102,105,109,112,116,119,123,126,130],[11,89,90],{},[14,91,92,94],{},[17,93,19],{}," This article is being written. The outline below is the real\nskeleton. The war stories are on their way.",[14,96,97],{},"Between 2019 and 2026 I built four production SaaS platforms where I was the\nonly engineer: architecture, code, servers, support. This is the article I\nwish someone had handed me before the first one.",[25,99,101],{"id":100},"what-solo-actually-means","What \"solo\" actually means",[14,103,104],{},"It means being the one who answers when Stripe webhooks silently stop\nreconciling on a Friday night.",[25,106,108],{"id":107},"scope-is-the-only-real-architecture-decision","Scope is the only real architecture decision",[14,110,111],{},"Two platforms in eight months taught me that every feature deferred is a\nfeature that ships. How I decided what Visionerro could live without.",[25,113,115],{"id":114},"boring-stacks-are-a-survival-strategy","Boring stacks are a survival strategy",[14,117,118],{},"Why Laravel + Vue + MySQL for all four, and where I deliberately spent my\nnovelty budget instead.",[25,120,122],{"id":121},"the-documentation-you-owe-your-future-self","The documentation you owe your future self",[14,124,125],{},"Seven years into QCS, the only teammate I have is the me who wrote it in\n2019. What I now write down, and what I stopped writing down.",[25,127,129],{"id":128},"when-the-team-finally-arrives","When the team finally arrives",[14,131,132],{},"Jase Medical grew from one engineer to four. What held up, what didn't, and\nwhat I'd establish on day one next time.",{"title":61,"searchDepth":62,"depth":62,"links":134},[135,136,137,138,139],{"id":100,"depth":62,"text":101},{"id":107,"depth":62,"text":108},{"id":114,"depth":62,"text":115},{"id":121,"depth":62,"text":122},{"id":128,"depth":62,"text":129},"2026-07-10","Notes on architecture, scope, and survival from building QCS, Visionerro, FlexSited, and Jase Medical as a one-person engineering team.",{},"\u002Fwriting\u002Fbuilding-saas-solo","12 min planned",{"title":85,"description":141},"writing\u002Fbuilding-saas-solo",[148,149,150],"saas","architecture","solo","g0-KyNsqpgUqUX7ETkTu-VutZrxNlm04is6jS9cXgjU",{"id":153,"title":154,"body":155,"date":209,"description":210,"draft":71,"extension":72,"meta":211,"navigation":71,"path":212,"readingTime":213,"seo":214,"stem":215,"tags":216,"__hash__":218},"writing\u002Fwriting\u002Fscaling-laravel-applications.md","Scaling Laravel Past the Tutorial Phase",{"type":8,"value":156,"toc":202},[157,164,167,171,174,178,181,185,188,192,195,199],[11,158,159],{},[14,160,161,163],{},[17,162,19],{}," This article is being written. The outline is real; the code\nsamples are coming.",[14,165,166],{},"Most Laravel content covers the first month of an application's life. These\nare notes from years five through seven: auth systems with five guards,\nschemas nearing a hundred tables, and four codebases sharing one database.",[25,168,170],{"id":169},"status-columns-become-state-machines-or-they-become-bugs","Status columns become state machines, or they become bugs",[14,172,173],{},"The QCS employee lifecycle (Active, Suspended, Declined, Approved, Pending)\nand why every transition writes to a history table.",[25,175,177],{"id":176},"multi-guard-auth-beyond-the-docs","Multi-guard auth beyond the docs",[14,179,180],{},"Five guards on one Laravel app: web, team, api, and the middleware that\nkeeps super admins, company teams, and multi-company agents apart.",[25,182,184],{"id":183},"one-database-four-codebases","One database, four codebases",[14,186,187],{},"Jase Medical ran ~246 migrations across four projects against a single\nMySQL schema. The ownership rules that made that survivable.",[25,189,191],{"id":190},"queues-tenancy-and-the-context-you-forget-to-carry","Queues, tenancy, and the context you forget to carry",[14,193,194],{},"Tenant-aware jobs in Visionerro: what breaks when serialized jobs wake up\nwithout their tenant.",[25,196,198],{"id":197},"the-migration-that-never-ends","The migration that never ends",[14,200,201],{},"Running Blade + Vue 2 and Inertia + Vue 3 in the same app, on purpose, for\nyears, and what I'd do differently with feature flags.",{"title":61,"searchDepth":62,"depth":62,"links":203},[204,205,206,207,208],{"id":169,"depth":62,"text":170},{"id":176,"depth":62,"text":177},{"id":183,"depth":62,"text":184},{"id":190,"depth":62,"text":191},{"id":197,"depth":62,"text":198},"2026-06-28","State machines, auth guards, queue discipline, and schema ownership: patterns from Laravel systems serving thousands of companies.",{},"\u002Fwriting\u002Fscaling-laravel-applications","15 min planned",{"title":154,"description":210},"writing\u002Fscaling-laravel-applications",[217,149],"laravel","eZjaLbIsChvr-b3U5xLXoiyKSR75h4q1vcQEQfjCLyg",{"id":220,"title":221,"body":222,"date":268,"description":269,"draft":71,"extension":72,"meta":270,"navigation":71,"path":271,"readingTime":272,"seo":273,"stem":274,"tags":275,"__hash__":278},"writing\u002Fwriting\u002Fstripe-integration-lessons.md","Stripe Lessons from Three Very Different Billing Models",{"type":8,"value":223,"toc":262},[224,231,234,238,241,245,248,252,255,259],[11,225,226],{},[14,227,228,230],{},[17,229,19],{}," This article is being written. The outline maps the three\nsystems it draws from.",[14,232,233],{},"I've shipped Stripe three very different ways: QCS charges\ncompanies at three levels, Visionerro let tenants bring their own Stripe\naccounts, and FlexSited combined subscriptions with one-time add-ons in a\nsingle checkout. Each model failed in its own special way first.",[25,235,237],{"id":236},"model-one-layered-charges-on-one-account-qcs","Model one: layered charges on one account (QCS)",[14,239,240],{},"Subscriptions, per-order charges, one-time enrollment fees, setup intents,\nand the unified billing abstraction I wish I'd built on day one.",[25,242,244],{"id":243},"model-two-connect-as-payment-facilitator-visionerro","Model two: Connect as payment facilitator (Visionerro)",[14,246,247],{},"Mapping tenant Stripe credentials into Cashier at runtime, and why\nper-tenant webhook handling deserves more respect than it gets.",[25,249,251],{"id":250},"model-three-recurring-one-time-in-one-checkout-flexsited","Model three: recurring + one-time in one checkout (FlexSited)",[14,253,254],{},"Selling a subscription and a logo design in the same transaction without\norphaning either when payment fails.",[25,256,258],{"id":257},"webhooks-are-the-actual-integration","Webhooks are the actual integration",[14,260,261],{},"Every Stripe bug I've shipped was a reconciliation bug. The logging and\nidempotency habits that ended them.",{"title":61,"searchDepth":62,"depth":62,"links":263},[264,265,266,267],{"id":236,"depth":62,"text":237},{"id":243,"depth":62,"text":244},{"id":250,"depth":62,"text":251},{"id":257,"depth":62,"text":258},"2026-06-15","Subscriptions plus per-order charges, Stripe Connect as a payment facilitator, and mixed recurring\u002Fone-time checkouts: what each taught me.",{},"\u002Fwriting\u002Fstripe-integration-lessons","10 min planned",{"title":221,"description":269},"writing\u002Fstripe-integration-lessons",[276,277,148],"stripe","payments","7Z07DuVFWC8zClJSijTyOQWtV-73QhVZJVdDUYQay7o",{"id":280,"title":281,"body":282,"date":328,"description":329,"draft":71,"extension":72,"meta":330,"navigation":71,"path":331,"readingTime":332,"seo":333,"stem":334,"tags":335,"__hash__":339},"writing\u002Fwriting\u002Fus-timezones-from-pakistan.md","Seven Years of US Hours from Pakistan",{"type":8,"value":283,"toc":322},[284,291,294,298,301,305,308,312,315,319],[11,285,286],{},[14,287,288,290],{},[17,289,19],{}," This article is being written. The outline is the honest\nversion of the story.",[14,292,293],{},"Since 2019 I've worked US hours from Pakistan: awake when my clients are,\nasleep when my city is. It sounds brutal. Done deliberately, it became a\nprofessional advantage. These are the mechanics.",[25,295,297],{"id":296},"the-schedule-concretely","The schedule, concretely",[14,299,300],{},"What a 12 to 16 hour day looked like during the transition years, and what a\nsustainable night-shift routine looks like now.",[25,302,304],{"id":303},"written-first-is-a-feature-not-a-fallback","Written-first is a feature, not a fallback",[14,306,307],{},"Every decision with my longest client exists in writing. Why that made a\nseven-year engagement calmer than most co-located jobs.",[25,309,311],{"id":310},"availability-is-a-trust-currency","Availability is a trust currency",[14,313,314],{},"The compounding effect of being reliably present at the same hours for\nyears, and how it kept one client relationship alive since 2019.",[25,316,318],{"id":317},"what-id-tell-a-us-employer","What I'd tell a US employer",[14,320,321],{},"How to get the most out of a timezone-shifted senior engineer, and the\noverlap patterns that actually matter.",{"title":61,"searchDepth":62,"depth":62,"links":323},[324,325,326,327],{"id":296,"depth":62,"text":297},{"id":303,"depth":62,"text":304},{"id":310,"depth":62,"text":311},{"id":317,"depth":62,"text":318},"2026-05-30","Working night shifts across a nine-hour gap: the habits that made written-first, timezone-shifted collaboration work for years.",{},"\u002Fwriting\u002Fus-timezones-from-pakistan","8 min planned",{"title":281,"description":329},"writing\u002Fus-timezones-from-pakistan",[336,337,338],"remote","async","career","njZCSfEZJJaCwgE0G1pJY9HQYOPGkSVWFsAvj7MWlW8",1785702626220]