[{"data":1,"prerenderedAt":850},["ShallowReactive",2],{"work-case-studies":3,"work-projects":487,"work-github":843},[4,172,281,390],{"id":5,"title":6,"body":7,"businessProblem":134,"confidentiality":135,"description":136,"employer":137,"extension":138,"featured":139,"heroStat":140,"meta":143,"navigation":139,"ogImage":144,"order":145,"path":146,"publishedAt":147,"results":148,"seo":160,"stem":161,"summary":162,"technologies":163,"updatedAt":144,"__hash__":171},"caseStudies\u002Fwork\u002Fcase-studies\u002Fcatalogue-automation.md","High-Volume Ecommerce Catalogue Automation",{"type":8,"value":9,"toc":122},"minimark",[10,15,19,32,35,39,44,48,55,61,67,73,77,91,95,98,102,115,119],[11,12,14],"h2",{"id":13},"the-problem","The problem",[16,17,18],"p",{},"The business ran ecommerce on top of a supplier catalogue nobody fully controlled. More than 200,000\nSKUs came in through:",[20,21,22,26,29],"ul",{},[23,24,25],"li",{},"Nightly FTP drops in half a dozen different CSV\u002FExcel dialects",[23,27,28],{},"A handful of supplier REST and SOAP APIs, each with its own auth and pagination quirks",[23,30,31],{},"Scraped product pages for suppliers who published no feed at all",[16,33,34],{},"Every source had its own idea of a SKU, a category tree, and a unit of measure. Pricing and\ninventory changed daily. Before automation, updating the catalogue was a recurring manual chore —\nslow, error-prone, and a hard ceiling on how many suppliers the business could realistically carry.\nThe business problem wasn't \"we need a script,\" it was \"we can't grow the catalogue without this\nbecoming someone's full-time job.\"",[11,36,38],{"id":37},"architecture","Architecture",[40,41],"architecture-diagram",{":steps":42,"title":43},"[{\"label\":\"Ingest\",\"detail\":\"FTP, REST\u002FSOAP APIs, scrapers\"},{\"label\":\"Normalize\",\"detail\":\"Units, categories, attributes\"},{\"label\":\"Match & validate\",\"detail\":\"Dedup, price\u002Fstock sanity checks\"},{\"label\":\"Publish\",\"detail\":\"Shopify, Odoo, internal reporting\"}]","Catalogue pipeline — simplified",[11,45,47],{"id":46},"what-i-built","What I built",[16,49,50,54],{},[51,52,53],"strong",{},"Ingestion layer."," A set of Python jobs per supplier source — FTP pull, API client, or scraper —\neach normalizing into a common intermediate schema before anything touches the database. New\nsuppliers plug in as a new ingestion adapter, not a rewrite of the pipeline.",[16,56,57,60],{},[51,58,59],{},"Normalization and matching."," Supplier part numbers, UPCs, and free-text titles get reconciled\nagainst the existing catalogue using a mix of exact-key matching and fuzzy matching for the messy\ncases (title similarity, brand + attribute matching) with a manual review queue for anything under\na confidence threshold — so ambiguous matches get a human decision instead of a silent guess.",[16,62,63,66],{},[51,64,65],{},"Pricing and inventory sync."," Cost and quantity updates flow through margin rules before they hit\nthe storefront, with change thresholds that flag anything that moves further than expected (a price\ndrop of 90% is far more likely to be a bad feed row than a real discount).",[16,68,69,72],{},[51,70,71],{},"Publishing."," Validated records write to Odoo and Shopify through their APIs, with diffs logged so\nevery price or inventory change is traceable back to the source file or API call that caused it.",[11,74,76],{"id":75},"reliability-and-validation","Reliability and validation",[20,78,79,82,85,88],{},[23,80,81],{},"Every ingestion run produces a diff report before anything is published — new items, removed\nitems, and changed fields are all visible before they go live.",[23,83,84],{},"Sanity thresholds catch outlier price and quantity changes for manual review instead of\nauto-publishing them.",[23,86,87],{},"Failed or partial supplier feeds fail loudly (alerting) rather than silently publishing stale or\nincomplete data.",[23,89,90],{},"A confidence-scored matching queue means uncertain SKU matches never get merged automatically.",[11,92,94],{"id":93},"technologies-used","Technologies used",[16,96,97],{},"Python for ingestion and transformation, PostgreSQL as the system of record, pandas for bulk\ntransforms, and the Shopify Admin API and Odoo's API for publishing. Scheduled jobs run the pipeline\non a nightly and hourly cadence depending on the source.",[11,99,101],{"id":100},"business-impact","Business impact",[16,103,104,105,110,111,114],{},"The catalogue automation removed manual data entry as the ceiling on supplier growth — the business\nwent from a catalogue that required constant manual upkeep to one that scales by adding ingestion\nadapters. Combined with the marketplace and advertising work described in the\n",[106,107,109],"a",{"href":108},"\u002Fwork\u002Fcase-studies\u002Fshopify-amazon-sync","Shopify and Amazon marketplace synchronization"," case study,\nthis system was part of growing this employer's ecommerce revenue from roughly ",[51,112,113],{},"$60,000 to\n$400,000 per month",".",[11,116,118],{"id":117},"what-id-change-next","What I'd change next",[16,120,121],{},"The matching layer is the piece I'd keep investing in — better fuzzy-matching and a tighter feedback\nloop from the manual review queue back into the automated confidence scoring, so the system gets\nbetter at flagging its own uncertain calls over time.",{"title":123,"searchDepth":124,"depth":124,"links":125},"",3,[126,128,129,130,131,132,133],{"id":13,"depth":127,"text":14},2,{"id":37,"depth":127,"text":38},{"id":46,"depth":127,"text":47},{"id":75,"depth":127,"text":76},{"id":93,"depth":127,"text":94},{"id":100,"depth":127,"text":101},{"id":117,"depth":127,"text":118},"Product data for 200,000+ SKUs arrived from dozens of suppliers in inconsistent formats — FTP flat files, REST and SOAP APIs, and, for suppliers with no feed at all, scraped catalogue pages. None of it agreed on units, categories, or even what counted as the same product.\n","anonymized","How I built a Python-based pipeline that ingests, cleans, matches, and publishes 200,000+ supplier products across FTP feeds, APIs, and scraped sources — with validation built in.","a Canadian industrial distributor","md",true,{"label":141,"value":142},"SKUs under management","200,000+",{},null,1,"\u002Fwork\u002Fcase-studies\u002Fcatalogue-automation","2026-01-15",[149,152,154,157],{"label":150,"value":151},"Manual catalogue hours per week","-80%",{"label":153,"value":142},"SKUs under active automation",{"label":155,"value":156},"Pricing\u002Finventory refresh cycle","Daily → hourly",{"label":158,"value":159},"Duplicate\u002Fmismatched listings","Caught pre-publish",{"title":6,"description":136},"work\u002Fcase-studies\u002Fcatalogue-automation","Automating ingestion, cleanup, matching, and pricing for 200,000+ supplier SKUs.",[164,165,166,167,168,169,170],"Python","PostgreSQL","Pandas","Odoo","Shopify Admin API","Cron \u002F scheduled jobs","FTP\u002FSFTP","54mWLZEHR2EO6_FtvYCFbJ_-UOYmblyE3ijgq8hWufM",{"id":173,"title":174,"body":175,"businessProblem":256,"confidentiality":135,"description":257,"employer":137,"extension":138,"featured":139,"heroStat":144,"meta":258,"navigation":139,"ogImage":144,"order":127,"path":108,"publishedAt":259,"results":260,"seo":273,"stem":274,"summary":275,"technologies":276,"updatedAt":144,"__hash__":280},"caseStudies\u002Fwork\u002Fcase-studies\u002Fshopify-amazon-sync.md","Shopify and Amazon Marketplace Synchronization",{"type":8,"value":176,"toc":248},[177,179,182,184,188,190,200,206,212,218,220,234,236,243,245],[11,178,14],{"id":13},[16,180,181],{},"Selling the same products on Shopify and Amazon means keeping two independent systems honest with\neach other. Shopify handled the storefront and source-of-truth inventory; Amazon required its own\nlistings, its own pricing rules, and its own inventory feed through SP-API. Left unmanaged, that gap\nproduces the worst kind of ecommerce failure: an oversell on a marketplace, a listing that's\ntechnically live but effectively invisible because pricing or content issues knocked it out of buy\nbox contention, or inventory counts that just quietly drift apart over weeks.",[11,183,38],{"id":37},[40,185],{":steps":186,"title":187},"[{\"label\":\"Shopify (source of truth)\",\"detail\":\"Inventory, pricing, product data\"},{\"label\":\"Reconciliation engine\",\"detail\":\"Diff, match, policy checks\"},{\"label\":\"Amazon SP-API\",\"detail\":\"Listings, inventory feeds, pricing\"},{\"label\":\"Monitoring\",\"detail\":\"Mismatch + listing-health alerts\"}]","Marketplace sync — simplified",[11,189,47],{"id":46},[16,191,192,195,196,199],{},[51,193,194],{},"Product matching."," Amazon listings get matched back to Shopify SKUs using ASIN\u002FSKU mapping with\nfallback matching on UPC and title similarity for products without a clean existing mapping —\nsimilar in spirit to the matching logic in the\n",[106,197,198],{"href":146},"catalogue automation pipeline",", applied here across\nmarketplace boundaries instead of supplier boundaries.",[16,201,202,205],{},[51,203,204],{},"Inventory reconciliation."," A scheduled job compares Shopify's on-hand quantity against what\nAmazon believes it has, and pushes corrections through SP-API. Discrepancies beyond a normal sync\ndelay get flagged instead of silently corrected, since a persistent mismatch is usually a sign of a\ndeeper problem (a failed feed, a miscounted receiving, a return that didn't reconcile).",[16,207,208,211],{},[51,209,210],{},"Pricing sync with policy awareness."," Price updates flow to Amazon through SP-API respecting\nAmazon's pricing rules (minimum advertised price, fee-aware margin floors) so a Shopify-side sale\nprice can't accidentally violate marketplace policy or tank margin on a high-fee category.",[16,213,214,217],{},[51,215,216],{},"Listing health monitoring."," A recurring check watches for listings that dropped out of buy box\ncontention, got suppressed for content issues, or otherwise went quietly invisible — the kind of\nproblem that costs revenue for weeks before anyone notices it manually.",[11,219,76],{"id":75},[20,221,222,225,228,231],{},[23,223,224],{},"Reconciliation runs are diffed and logged before any corrective write, the same discipline used in\nthe catalogue pipeline.",[23,226,227],{},"Persistent mismatches (not explained by normal sync latency) escalate to a human instead of being\nauto-corrected indefinitely.",[23,229,230],{},"Pricing changes are checked against marketplace policy constraints before they're sent.",[23,232,233],{},"Listing-health checks run on a schedule independent of the sync jobs, so a healthy sync doesn't\nmask an unhealthy listing.",[11,235,101],{"id":100},[16,237,238,239,242],{},"Marketplace expansion is only worth doing if it doesn't create new operational risk. This system let\nthe business list and sell confidently on Amazon without inventory or pricing becoming a manual\nbabysitting job — a necessary piece of the same growth story covered in the\n",[106,240,241],{"href":146},"catalogue automation"," case study, where this employer's\necommerce revenue grew from roughly $60,000 to $400,000 per month.",[11,244,118],{"id":117},[16,246,247],{},"Buy-box and pricing dynamics on Amazon move faster than a scheduled job can always keep up with —\nthe next iteration I'd build is event-driven reconciliation triggered by Amazon notifications rather\nthan pure polling, to shrink the reaction window further.",{"title":123,"searchDepth":124,"depth":124,"links":249},[250,251,252,253,254,255],{"id":13,"depth":127,"text":14},{"id":37,"depth":127,"text":38},{"id":46,"depth":127,"text":47},{"id":75,"depth":127,"text":76},{"id":100,"depth":127,"text":101},{"id":117,"depth":127,"text":118},"Running the same catalogue on Shopify and Amazon meant two systems of record that disagreed — oversells when inventory drifted out of sync, pricing that violated marketplace policy, and listings that silently fell out of buy-box contention.\n","Architecture and lessons from building inventory reconciliation, pricing, and listing-health workflows across Shopify and Amazon SP-API for a multi-thousand-SKU catalogue.",{},"2026-02-10",[261,264,267,270],{"label":262,"value":263},"Marketplace oversells","Eliminated via reconciliation",{"label":265,"value":266},"Listing issues","Caught before customer impact",{"label":268,"value":269},"Price\u002Finventory sync","Automated, policy-aware",{"label":271,"value":272},"Marketplaces synchronized","2 (Shopify + Amazon)",{"title":174,"description":257},"work\u002Fcase-studies\u002Fshopify-amazon-sync","Keeping inventory, pricing, and listings consistent across Shopify and Amazon SP-API.",[168,277,164,165,278,279],"Amazon SP-API","Webhooks","Scheduled reconciliation jobs","VXLn4fG_S_7mzyThYgJ5UW8xRTtAU2H2_wlVKrs1ZgA",{"id":282,"title":283,"body":284,"businessProblem":362,"confidentiality":363,"description":364,"employer":365,"extension":138,"featured":139,"heroStat":144,"meta":366,"navigation":139,"ogImage":144,"order":124,"path":367,"publishedAt":368,"results":369,"seo":379,"stem":380,"summary":381,"technologies":382,"updatedAt":144,"__hash__":389},"caseStudies\u002Fwork\u002Fcase-studies\u002Fbig-box-outlet-growth.md","Ecommerce Growth and Marketplace Expansion at Big Box Outlet Store",{"type":8,"value":285,"toc":356},[286,288,291,295,301,307,313,319,328,334,336,344,348],[11,287,14],{"id":13},[16,289,290],{},"Big Box Outlet Store sells liquidation, closeout, and surplus inventory — the opposite of a stable\ncatalogue with predictable reorders. Product mix turns over constantly, quantities are often one-off\nor limited, and merchandising has to move fast enough to sell through inventory before it stops\nbeing relevant. Ecommerce for a business like this isn't just \"put products online\" — it's building\na channel and a set of workflows that can absorb constant change without falling apart.",[11,292,294],{"id":293},"what-i-did","What I did",[16,296,297,300],{},[51,298,299],{},"Platform management."," Owned the Shopify storefront end to end — merchandising, site structure,\nand the day-to-day decisions that keep a fast-changing catalogue usable for customers instead of\noverwhelming.",[16,302,303,306],{},[51,304,305],{},"Paid advertising."," Ran Google Ads and Meta Ads campaigns, tuning spend and targeting against a\ncatalogue that doesn't behave like a normal retailer's — creative and targeting had to keep pace\nwith inventory that could sell out or change entirely within days.",[16,308,309,312],{},[51,310,311],{},"Marketplace expansion."," Extended the sales channel beyond the core storefront into additional\nmarketplaces, adapting listings and operations to each platform's rules and audience.",[16,314,315,318],{},[51,316,317],{},"Auctions."," Built out auction-based selling as a channel for surplus and closeout inventory suited\nto that format — a different operating model from standard fixed-price ecommerce, run alongside it.",[16,320,321,324,325,114],{},[51,322,323],{},"Internal tools and workflow."," Where off-the-shelf tools didn't fit how the business actually\noperated, built internal tooling to close the gap — the same instinct that later became a core part\nof my ",[106,326,327],{"href":146},"ecommerce systems and automation work",[16,329,330,333],{},[51,331,332],{},"Team leadership."," Led the ecommerce function as it grew, balancing platform work, campaign\nmanagement, and day-to-day merchandising operations.",[11,335,101],{"id":100},[16,337,338,339,343],{},"This role is where I learned ecommerce as an ",[340,341,342],"em",{},"operation",", not just a technical system — merchandising\ndecisions, ad spend, marketplace rules, and fulfillment realities all interact, and the technical\nsystems only matter if they hold up against that operational messiness. That perspective now shapes\nhow I build software for ecommerce businesses: I design for the actual chaos of retail operations,\nnot an idealized version of it.",[11,345,347],{"id":346},"what-i-learned","What I learned",[16,349,350,351,355],{},"The biggest lesson from running ecommerce operations directly, rather than building systems for\nsomeone else's operation, is that the hardest problems are rarely purely technical. A perfectly\nengineered sync job doesn't help if the merchandising process feeding it is inconsistent. That's the\nlens I bring to the systems work described in my other ",[106,352,354],{"href":353},"\u002Fwork","case studies"," — I build for how the\nbusiness actually runs, not just for the API spec.",{"title":123,"searchDepth":124,"depth":124,"links":357},[358,359,360,361],{"id":13,"depth":127,"text":14},{"id":293,"depth":127,"text":294},{"id":100,"depth":127,"text":101},{"id":346,"depth":127,"text":347},"A liquidation and closeout retailer needed an ecommerce channel that could keep up with constantly changing, one-off, and surplus inventory — where the product catalogue itself is never stable.\n","public","The operator side of my experience — growing Big Box Outlet Store's ecommerce channel through platform management, paid advertising, marketplace expansion, auctions, and internal tooling.","Big Box Outlet Store",{},"\u002Fwork\u002Fcase-studies\u002Fbig-box-outlet-growth","2025-11-01",[370,373,376],{"label":371,"value":372},"Role","Ecommerce Manager",{"label":374,"value":375},"Scope","Platform, ads, marketplaces, ops",{"label":377,"value":378},"Tenure","2017–2023",{"title":283,"description":364},"work\u002Fcase-studies\u002Fbig-box-outlet-growth","Running ecommerce end-to-end — platform, advertising, marketplaces, merchandising, and internal tools.",[383,384,385,386,387,388],"Shopify","Google Ads","Meta Ads","Marketplace integrations","Internal tooling","Merchandising systems","S2pVpnby0FOfKBhMlSw0nZjDPlcQCwZgXyQ8kfJtuvc",{"id":391,"title":392,"body":393,"businessProblem":461,"confidentiality":363,"description":462,"employer":144,"extension":138,"featured":139,"heroStat":144,"meta":463,"navigation":139,"ogImage":144,"order":464,"path":465,"publishedAt":466,"results":467,"seo":477,"stem":478,"summary":479,"technologies":480,"updatedAt":144,"__hash__":486},"caseStudies\u002Fwork\u002Fcase-studies\u002Fai-assisted-automation.md","AI-Assisted Business Automation",{"type":8,"value":394,"toc":455},[395,397,400,404,408,414,420,426,432,438,442,448,452],[11,396,14],{"id":13},[16,398,399],{},"There's a wide gap between \"AI wrote some code\" and \"AI-assisted development that's actually\ntrustworthy in production.\" The first is a demo. The second requires a workflow — one where AI tools\nhandle the parts they're genuinely good at (drafting, boilerplate, exploring an unfamiliar API,\nfirst-pass tests) while a human still owns system design, correctness review, and the decision to\nship.",[11,401,403],{"id":402},"the-workflow","The workflow",[40,405],{":steps":406,"title":407},"[{\"label\":\"Business problem\",\"detail\":\"Defined by me, not the model\"},{\"label\":\"System design\",\"detail\":\"Architecture + constraints set upfront\"},{\"label\":\"AI-assisted implementation\",\"detail\":\"Claude Code, Codex, Cursor, Gemini\"},{\"label\":\"Tests + human review\",\"detail\":\"Nothing ships unread\"},{\"label\":\"Deploy + monitor\",\"detail\":\"Same ops discipline as any change\"}]","How AI fits into the process",[16,409,410,413],{},[51,411,412],{},"Business problem first."," Every task starts with the actual operational problem — a catalogue\nmismatch, a slow report, a manual process eating hours every week — not a prompt in search of a use\ncase.",[16,415,416,419],{},[51,417,418],{},"System design stays mine."," Architecture decisions, data models, and failure-mode thinking happen\nbefore AI tools touch the problem. This is the part that determines whether the resulting system is\nmaintainable six months later, and it's the part I don't delegate.",[16,421,422,425],{},[51,423,424],{},"AI-assisted implementation."," Different tools for different jobs: Claude Code and Codex for\nlarger, multi-file implementation work and refactors; Cursor for fast in-editor iteration; Gemini\nfor research and second opinions on approach. I treat model output as a strong first draft, not a\nfinished product.",[16,427,428,431],{},[51,429,430],{},"Tests and human review."," Nothing generated ships without tests and a real read-through — the same\nbar I'd hold a human collaborator's pull request to. AI-generated code gets the same scrutiny as\nanyone else's, arguably more, because it doesn't yet have a track record with this specific codebase.",[16,433,434,437],{},[51,435,436],{},"Deployment and monitoring."," Once something ships, it's watched the same way any production change\nwould be — logging, alerting, and a rollback plan, not \"the AI said it works.\"",[11,439,441],{"id":440},"why-this-matters","Why this matters",[16,443,444,445,447],{},"The honest pitch isn't \"AI writes my code.\" It's that AI tools meaningfully speed up the\nimplementation phase of systems I'd have designed and validated either way — the catalogue pipelines,\nmarketplace sync jobs, and internal tools described in my other ",[106,446,354],{"href":353}," get built\nfaster because of this workflow, not because judgment got outsourced to a model.",[11,449,451],{"id":450},"what-im-still-refining","What I'm still refining",[16,453,454],{},"The weakest link right now is turning implicit operational knowledge — the stuff I know about how a\nspecific supplier feed misbehaves, or how a marketplace's edge cases work — into context the AI tools\ncan actually use, instead of re-explaining it every session. That's the direction most of my current\ntooling investment is going.",{"title":123,"searchDepth":124,"depth":124,"links":456},[457,458,459,460],{"id":13,"depth":127,"text":14},{"id":402,"depth":127,"text":403},{"id":440,"depth":127,"text":441},{"id":450,"depth":127,"text":451},"AI coding tools are good at producing code fast. They're not automatically good at producing code that's correct, maintainable, and safe to run against real supplier data, real inventory, and real customer orders — that gap is where most \"AI-generated\" work quietly fails.\n","The workflow I use to fold AI tools into real ecommerce systems work, from problem framing through deployment and monitoring — with human review at every step that matters.",{},4,"\u002Fwork\u002Fcase-studies\u002Fai-assisted-automation","2026-03-01",[468,471,474],{"label":469,"value":470},"AI tools used daily","Claude Code, Codex, Cursor, Gemini",{"label":472,"value":473},"Human review","Every deploy",{"label":475,"value":476},"Judgment retained by","Me, not the model",{"title":392,"description":462},"work\u002Fcase-studies\u002Fai-assisted-automation","How Claude Code, Codex, Cursor, and Gemini fit into a real development process — not just code snippets.",[481,482,483,484,164,485],"Claude Code","Codex","Cursor","Gemini","CI\u002FCD","4e_ExX31zgQuu7opLtcYSbLIwiTkCTsvT9qGnt_TRP8",[488,594,677,756],{"id":489,"title":490,"body":491,"demo":144,"description":575,"extension":138,"featured":139,"github":144,"meta":576,"navigation":139,"ogImage":144,"order":145,"path":577,"plannedImprovements":578,"problem":583,"publishedAt":584,"seo":585,"status":586,"stem":587,"summary":588,"technologies":589,"__hash__":593},"projects\u002Fwork\u002Fprojects\u002Fcatalogue-pipeline-toolkit.md","Product Catalogue Pipeline Toolkit",{"type":8,"value":492,"toc":566},[493,497,504,508,511,515,519,523,526,530,541,545,548,552],[11,494,496],{"id":495},"one-sentence-explanation","One-sentence explanation",[16,498,499,500,503],{},"A command-line Python toolkit that turns messy supplier catalogue exports into normalized,\nvalidated, diffable data — the reusable core of the pipeline described in the\n",[106,501,502],{"href":146},"catalogue automation case study",", rebuilt from scratch\nwith synthetic data so the design and code can be public even though that case study's data isn't.",[11,505,507],{"id":506},"the-problem-being-solved","The problem being solved",[16,509,510],{},"Supplier catalogue ingestion is one of the most common — and most repeatedly reinvented — problems\nin ecommerce tooling. Every business writes its own one-off scripts to parse CSV\u002FExcel exports,\nguess at unit conversions, and check for obviously broken rows before publishing. None of that logic\nis inherently proprietary; it's just rarely extracted into something reusable.",[11,512,514],{"id":513},"planned-architecture","Planned architecture",[40,516],{":steps":517,"title":518},"[{\"label\":\"Adapter\",\"detail\":\"Parse CSV\u002FExcel\u002FJSON into a common schema\"},{\"label\":\"Normalize\",\"detail\":\"Units, categories, attribute mapping\"},{\"label\":\"Validate\",\"detail\":\"Rule-based checks, typed errors\"},{\"label\":\"Diff \u002F export\",\"detail\":\"Compare snapshots, write clean output\"}]","Toolkit — planned shape",[11,520,522],{"id":521},"technology-stack","Technology stack",[16,524,525],{},"Python, with Pydantic for schema validation and typed records, pandas for the bulk transform steps,\nand a small CLI (Typer or argparse) so the toolkit is usable standalone or importable as a library in\na larger pipeline.",[11,527,529],{"id":528},"current-status","Current status",[16,531,532,535,536,540],{},[51,533,534],{},"Concept — design complete, implementation not yet started."," This page documents the toolkit I\nintend to build by generalizing the ingestion and validation logic from my professional work into a\nstandalone, MIT-licensed package with synthetic sample data. No public repository exists yet — check\nback, or ",[106,537,539],{"href":538},"\u002Fcontact","get in touch"," if you'd like to see this prioritized.",[11,542,544],{"id":543},"what-i-expect-to-learn","What I expect to learn",[16,546,547],{},"Extracting private pipeline logic into a general-purpose tool forces real API design decisions that\na one-off internal script never has to make — this is where I expect the most useful lessons about\nwhat's actually reusable versus what's specific to one business's data quirks.",[11,549,551],{"id":550},"planned-improvements","Planned improvements",[20,553,554,557,560,563],{},[23,555,556],{},"Pluggable adapters for common supplier feed formats",[23,558,559],{},"Configurable normalization rules per source",[23,561,562],{},"Human-readable diff reports between catalogue snapshots",[23,564,565],{},"A tested validation-rules layer, not inline script logic",{"title":123,"searchDepth":124,"depth":124,"links":567},[568,569,570,571,572,573,574],{"id":495,"depth":127,"text":496},{"id":506,"depth":127,"text":507},{"id":513,"depth":127,"text":514},{"id":521,"depth":127,"text":522},{"id":528,"depth":127,"text":529},{"id":543,"depth":127,"text":544},{"id":550,"depth":127,"text":551},"A planned open-source Python toolkit that extracts the reusable parts of supplier catalogue ingestion — import, normalize, validate, diff — away from any one employer's private pipeline.",{},"\u002Fwork\u002Fprojects\u002Fcatalogue-pipeline-toolkit",[579,580,581,582],"Pluggable adapters for common supplier feed formats (flat file, JSON, XML)","A rules-based normalization layer (units, categories, attributes) configurable per source","A diff command that outputs a human-readable change report between two catalogue snapshots","Validation rules as a first-class, testable component rather than inline script logic","Every ecommerce business with a supplier-fed catalogue rebuilds the same handful of primitives — parse a messy CSV\u002FExcel export, normalize units and categories, validate before publishing, and diff one version of a catalogue against the next. That logic usually lives locked inside one company's private pipeline instead of existing as a reusable tool.\n","2026-04-01",{"title":490,"description":575},"concept","work\u002Fprojects\u002Fcatalogue-pipeline-toolkit","A reusable Python toolkit for importing, normalizing, validating, and comparing supplier catalogue files.",[164,166,590,591,592],"Pydantic","CSV \u002F Excel \u002F JSON","CLI","Hri19A0-m6yzVe7VaOMWBxJqoQgWK1BUMS2nv80D1W8",{"id":595,"title":596,"body":597,"demo":144,"description":660,"extension":138,"featured":139,"github":144,"meta":661,"navigation":139,"ogImage":144,"order":127,"path":662,"plannedImprovements":663,"problem":668,"publishedAt":669,"seo":670,"status":586,"stem":671,"summary":672,"technologies":673,"__hash__":676},"projects\u002Fwork\u002Fprojects\u002Finventory-reconciler.md","Shopify\u002FAmazon Inventory Reconciler",{"type":8,"value":598,"toc":651},[599,601,607,609,612,614,618,620,623,625,630,632,635,637],[11,600,496],{"id":495},[16,602,603,604,606],{},"A tool that pulls inventory from Shopify and Amazon, compares them, and produces a clear\nmismatch report — a public demonstration of the reconciliation approach described in the\n",[106,605,109],{"href":108}," case study.",[11,608,507],{"id":506},[16,610,611],{},"Reconciliation logic — the part of a marketplace sync system that actually catches drift before it\nbecomes an oversell — is rarely shared publicly, because it's usually written against one company's\nprivate data. This project aims to demonstrate the same approach against sample\u002Fdemo data so the\narchitecture and logic are inspectable without exposing anyone's real inventory.",[11,613,514],{"id":513},[40,615],{":steps":616,"title":617},"[{\"label\":\"Fetch\",\"detail\":\"Shopify Admin API + Amazon SP-API\"},{\"label\":\"Match\",\"detail\":\"SKU\u002FASIN mapping, fallback matching\"},{\"label\":\"Compare\",\"detail\":\"Tolerance-aware diffing\"},{\"label\":\"Report\",\"detail\":\"CLI output + exportable report\"}]","Reconciler — planned shape",[11,619,522],{"id":521},[16,621,622],{},"Python for the fetch\u002Fcompare\u002Freport pipeline, with Shopify's Admin API and Amazon's SP-API as data\nsources, and a lightweight local database (SQLite for the demo, PostgreSQL for anything continuous)\nto track mismatch history between runs.",[11,624,529],{"id":528},[16,626,627,629],{},[51,628,534],{}," This will ship with fully synthetic\ndemo data (fake stores, fake ASINs) so the tool is runnable and inspectable by anyone without needing\nreal marketplace credentials. No public repository exists yet.",[11,631,544],{"id":543},[16,633,634],{},"Building this against synthetic data instead of a live, revenue-bearing system is a genuinely\ndifferent design problem — it forces the mismatch-detection logic to be legible and well-documented\non its own, rather than implicitly understood because it's embedded in a larger system.",[11,636,551],{"id":550},[20,638,639,642,645,648],{},[23,640,641],{},"Additional channel adapters beyond Shopify\u002FAmazon",[23,643,644],{},"Continuous\u002Fscheduled mode with mismatch history tracking",[23,646,647],{},"A simple web report view",[23,649,650],{},"Configurable tolerance windows for normal sync latency",{"title":123,"searchDepth":124,"depth":124,"links":652},[653,654,655,656,657,658,659],{"id":495,"depth":127,"text":496},{"id":506,"depth":127,"text":507},{"id":513,"depth":127,"text":514},{"id":521,"depth":127,"text":522},{"id":528,"depth":127,"text":529},{"id":543,"depth":127,"text":544},{"id":550,"depth":127,"text":551},"A planned open-source tool that compares Shopify and Amazon inventory data, flags mismatches, and generates a clear report — a public, demo-data version of the reconciliation logic used in production.",{},"\u002Fwork\u002Fprojects\u002Finventory-reconciler",[664,665,666,667],"Support for additional channels beyond Shopify and Amazon (e.g. a generic CSV\u002FAPI adapter)","A scheduled mode that runs reconciliation continuously and tracks mismatch history over time","A simple web report view in addition to the CLI\u002Ffile output","Configurable tolerance windows to avoid flagging normal sync latency as a mismatch","Multi-channel sellers need to know when Shopify and Amazon disagree about inventory before it causes an oversell — but the reconciliation logic that catches this is almost always buried inside a private, employer-specific system with no public reference implementation.\n","2026-04-05",{"title":596,"description":660},"work\u002Fprojects\u002Finventory-reconciler","A public demonstration that compares inventories across platforms, detects mismatches, and produces an actionable report.",[164,168,277,674,675],"PostgreSQL or SQLite","Report generation","xn0dx8UwERReoMZgHd3GOmuEIc3YfG9YAXHzIa19GSA",{"id":678,"title":679,"body":680,"demo":144,"description":740,"extension":138,"featured":139,"github":144,"meta":741,"navigation":139,"ogImage":144,"order":124,"path":742,"plannedImprovements":743,"problem":745,"publishedAt":746,"seo":747,"status":586,"stem":748,"summary":749,"technologies":750,"__hash__":755},"projects\u002Fwork\u002Fprojects\u002Fqr-proof-of-delivery.md","QR Delivery and Proof-of-Delivery System",{"type":8,"value":681,"toc":731},[682,684,687,689,692,694,698,700,703,705,710,712,715,717],[11,683,496],{"id":495},[16,685,686],{},"A full-stack application that generates QR-coded labels for shipments and store transfers, logs\ntracking events as they're scanned, and gives customers a live, shareable delivery status page.",[11,688,507],{"id":506},[16,690,691],{},"Retailers moving inventory between stores — or shipping directly to customers — need an auditable\nrecord of where a package has been and who scanned it, without building or paying for a full carrier\nintegration for internal transfers. A lightweight, self-hosted QR-based tracking system covers that\ngap: generate a label, scan it at each handoff point, and give both staff and customers visibility\ninto status.",[11,693,514],{"id":513},[40,695],{":steps":696,"title":697},"[{\"label\":\"Label generation\",\"detail\":\"QR code + shipment\u002Ftransfer record\"},{\"label\":\"Scan events\",\"detail\":\"Authenticated staff scanning app\"},{\"label\":\"Tracking API\",\"detail\":\"Event log, status derivation\"},{\"label\":\"Customer status page\",\"detail\":\"Public, link-based, no login required\"}]","QR tracking — planned shape",[11,699,522],{"id":521},[16,701,702],{},"Nuxt for both the staff-facing (authenticated) scanning interface and the public customer-facing\nstatus pages, a PostgreSQL-backed event log as the source of truth for tracking history, and\nserver-side QR code generation tied to each shipment or transfer record.",[11,704,529],{"id":528},[16,706,707,709],{},[51,708,534],{}," This is the most full-stack of the\nplanned public projects — auth, structured data, real-time-ish status, and a public-facing page all\nin one system — and the one I'm most looking forward to building. No public repository exists yet.",[11,711,544],{"id":543},[16,713,714],{},"The interesting design problem here isn't the QR codes — it's modeling delivery\u002Ftransfer state as an\nappend-only event log rather than a single mutable \"status\" field, so the customer-facing page can\nshow real history instead of just a current snapshot.",[11,716,551],{"id":550},[20,718,719,722,725,728],{},[23,720,721],{},"Native barcode\u002Flabel printer integration",[23,723,724],{},"Delivery ETA estimation from historical scan data",[23,726,727],{},"Customer notifications on status change",[23,729,730],{},"Multi-tenant support for more than one store network",{"title":123,"searchDepth":124,"depth":124,"links":732},[733,734,735,736,737,738,739],{"id":495,"depth":127,"text":496},{"id":506,"depth":127,"text":507},{"id":513,"depth":127,"text":514},{"id":521,"depth":127,"text":522},{"id":528,"depth":127,"text":529},{"id":543,"depth":127,"text":544},{"id":550,"depth":127,"text":551},"A planned full-stack system for generating QR-coded shipping\u002Ftransfer labels, logging scan-based tracking events, and giving customers a live delivery status page — demonstrating auth, operational workflows, and real-time status tracking.",{},"\u002Fwork\u002Fprojects\u002Fqr-proof-of-delivery",[721,724,744,730],"Customer notifications (SMS\u002Femail) on status change","Store transfers and last-mile deliveries often lack a simple, auditable proof-of-delivery trail — especially for multi-location retail where inventory moves between stores as often as it moves to customers.\n","2026-04-10",{"title":679,"description":740},"work\u002Fprojects\u002Fqr-proof-of-delivery","A full-stack tracking system for carrier and store-transfer deliveries — labels, QR codes, tracking events, and customer-facing status pages.",[751,165,752,753,754],"Nuxt","QR code generation","Authentication","Server routes \u002F APIs","-R4R-xoS44zH5cHF5_Aj904MnGAaM7kjFpCkyxYpZwY",{"id":757,"title":758,"body":759,"demo":144,"description":823,"extension":138,"featured":139,"github":144,"meta":824,"navigation":139,"ogImage":144,"order":464,"path":825,"plannedImprovements":826,"problem":831,"publishedAt":832,"seo":833,"status":586,"stem":834,"summary":835,"technologies":836,"__hash__":842},"projects\u002Fwork\u002Fprojects\u002Fai-ops-recap-agent.md","AI Operations Recap Agent",{"type":8,"value":760,"toc":814},[761,763,770,772,775,777,781,783,786,788,793,795,798,800],[11,762,496],{"id":495},[16,764,765,766,769],{},"An agent that reads Git commits, issue-tracker activity, task lists, and calendar events, and turns\nthem into a short, accurate daily or weekly operational recap — a practical, small-scale example of\nthe ",[106,767,768],{"href":465},"AI-assisted workflow"," I use day to day.",[11,771,507],{"id":506},[16,773,774],{},"Reconstructing \"what actually happened this week\" across commits, tickets, and meetings is tedious\nand easy to get wrong from memory. It's also a well-scoped, low-risk task for an AI agent: the\nsource data is concrete and verifiable, so the agent's job is synthesis and summarization, not\njudgment calls with real consequences — a good fit for AI assistance precisely because the failure\nmode of a bad summary is low-stakes and easy to spot.",[11,776,514],{"id":513},[40,778],{":steps":779,"title":780},"[{\"label\":\"Collect\",\"detail\":\"Git, issues, tasks, calendar\"},{\"label\":\"Normalize\",\"detail\":\"Common event schema\"},{\"label\":\"Summarize\",\"detail\":\"Claude API, grounded in source data\"},{\"label\":\"Deliver\",\"detail\":\"Daily\u002Fweekly recap, scheduled\"}]","Recap agent — planned shape",[11,782,522],{"id":521},[16,784,785],{},"A scheduled job (Python or TypeScript) pulling from the GitHub API, a calendar API, and whatever\ntask tracker is in use, normalized into a common event schema, then summarized with the Claude API\nusing the source events as grounding context — not free-form generation.",[11,787,529],{"id":528},[16,789,790,792],{},[51,791,534],{}," This is the smallest and fastest of\nthe planned public projects to build, and a good candidate for a first real implementation. No\npublic repository exists yet.",[11,794,544],{"id":543},[16,796,797],{},"The interesting constraint is keeping the summary grounded and verifiable — every line in the recap\nshould trace back to a specific commit, ticket, or event, not a plausible-sounding hallucination.\nThat's the same discipline described in the AI-assisted automation case study, applied to a much\nsmaller, lower-stakes tool.",[11,799,551],{"id":550},[20,801,802,805,808,811],{},[23,803,804],{},"Slack\u002Femail delivery",[23,806,807],{},"Configurable sources without code changes",[23,809,810],{},"A feedback loop to improve future summaries",[23,812,813],{},"Multi-project rollups",{"title":123,"searchDepth":124,"depth":124,"links":815},[816,817,818,819,820,821,822],{"id":495,"depth":127,"text":496},{"id":506,"depth":127,"text":507},{"id":513,"depth":127,"text":514},{"id":521,"depth":127,"text":522},{"id":528,"depth":127,"text":529},{"id":543,"depth":127,"text":544},{"id":550,"depth":127,"text":551},"A planned AI-assisted agent that pulls together Git activity, issue trackers, tasks, and calendar events into a concise daily or weekly operational recap.",{},"\u002Fwork\u002Fprojects\u002Fai-ops-recap-agent",[827,828,829,830],"Slack\u002Femail delivery of the daily or weekly recap","Configurable sources (add\u002Fremove trackers without code changes)","A feedback loop so corrections improve future summaries","Multi-project rollups for people juggling more than one codebase","Staying on top of what actually happened across a week of commits, tickets, and meetings takes real effort to reconstruct after the fact — most of that synthesis work is exactly what an AI-assisted agent is good at, if it's grounded in real operational data instead of guessing.\n","2026-04-15",{"title":758,"description":823},"work\u002Fprojects\u002Fai-ops-recap-agent","A tool that turns commits, issues, tasks, and calendar events into a daily operational summary.",[837,838,839,840,841],"Python or TypeScript","Claude API","Git \u002F GitHub API","Calendar API","Scheduled jobs","4UR_qp77igU7jLguHUdyjPByQ-MiuzynGkoZLSwfhgM",[844],{"name":845,"description":846,"url":847,"language":164,"stars":848,"updatedAt":849},"home-row-mouse-x11","Command and control the mouse cursor from the keybord home row","https:\u002F\u002Fgithub.com\u002Fsigkappel\u002Fhome-row-mouse-x11",0,"2025-09-23T14:06:01Z",1785688078907]