Skip to content
Dallan
HomeAboutWorkResumeContact
HomeAboutWorkResumeContact Me
  • GitHubGitHub
  • LinkedInLinkedIn
  • Amity ResultsAmity Results
  • Email Dallan JonesEmail Dallan Jones
Dallan Jones /about

Places

Portrait of Dallan Jones

Dallan Jones

workflow automation · long-running pipelines · AI service integration

I help turn complicated business processes into automatic systems. Most of my work has been on big platforms that help teams work together in real-time, automate payments, and manage data. Since 2024, I've also built my own products under Amity Results, including a software platform I own and built completely. I care about what happens behind the scenes as much as what it shows you, because that's where the real time savings come from.

Read the case studies

Where I've worked

Founder & Full-Stack Developer — Amity Results

Jul 2024 – Current

Founded and built a SaaS media platform that transcribes, translates and subtitles instructional video — my own product, owned outright from architecture through deployment.

Full-Stack Developer — Fabled Solutions

Sep 2022 – Mar 2025

Extended a legacy F&I platform used by 2,000+ dealerships — real-time collaborative editing, a role-based claims dashboard, and an automated XML/SOAP sync pipeline.

Junior Full-Stack Developer — Fabled Solutions

Mar 2022 – Sep 2022

Built a U.S. Bank Virtual Card payment integration, external REST APIs for insurance partner onboarding, and a multi-dealership vehicle purchasing workflow.

Coding Bootcamp Mentor — Juno College

Oct 2021 – Apr 2022

Mentored students one-on-one through coursework, debugging and refactoring, and reviewed their projects for code quality and maintainability.

What I do, and what it changed

Four capabilities I bring to product teams, each tied to work that shipped and a problem it changed for someone.

Workflow automation

Turn repeated, manual processes into dependable workflows. A safety instructor no longer has to translate aloud over the same training video in every class.

Read how

AI service integration

Connect transcription, translation and language models to real product workflows — with source-grounded timestamps, reviewable outputs and recovery when an external service fails.

Read how

Resilient background processing

Design long-running pipelines that can retry, resume and clean up after themselves. Upload, transcode, transcribe, translate and encode can each fail without losing the whole job.

Read how

Modernizing live systems

Add new capabilities without interrupting the people already using the system. A platform serving 2,000+ dealerships gained recording, AI transcription and searchable compliance records.

Read how

Why this work matters

The point is not another dashboard or an AI badge. It is software that removes repeated effort, behaves predictably when something fails and gives people an output they can actually use.

Less work gets repeated

Automation should remove a recurring task, not move it into a different screen. The result is time returned to the people doing the actual work.

Failures stay manageable

Retries, audit trails and explicit recovery paths keep a failed service or abandoned browser session from becoming an operational emergency.

AI produces usable output

AI matters when it is grounded in source material, placed inside an existing workflow and designed so a person can verify what it produced.

Proof in practice · Amity Results

A reusable lesson instead of a repeated translation

A safety instructor was translating aloud while her English training videos played for Vietnamese-speaking students. Amity Results turns the same source video into transcribed, translated and permanently subtitled material. She can teach the class instead of performing the same translation again, and the finished lesson can be reused.

See it liveHow it was built
Contact /contact
Contact

Let's talk.

Whether it's a role, a contract, or just a technical problem you'd like a second opinion on — send a message and I'll get back to you directly.

Direct

dallanjones@pm.me

Elsewhere

Based in Edmonton, AB. Typically replies within a day or two.

Résumé resume.pdf

Your browser won't display PDFs inline.

Download the résumé
Terminal ~

Desktop ready. Terminal available.

Modernizing an Insurance Platform /work
Jump to section
  • Overview
  • Business Challenge
  • Engineering Initiatives
  • Real-Time Claim Ownership
  • Synchronizing Dealer Data and Hierarchy
  • Virtual Credit Card (VCC) Payments via USBank
  • Claims Dashboard & Response-Time Analytics
  • Architecture
  • Results
  • Client Collaboration
  • Scope
  • Backend
  • Frontend
  • Infrastructure
Project Details

Technologies

LaravelVue.jsMySQLRedisWebSocketsREST APIsVuex

Engineering Highlights

  • Real-time claim locking and ownership
  • Pusher to self-hosted Soketi migration
  • 175+ dependent components migrated without disruption
  • Idempotent U.S. Bank payment pipeline
  • Dual authorization separating approval from payment release
  • Hierarchical dealership reconciliation with cascading updates
  • Reconciliation architecture reused across three subsystems

Modernizing an Insurance Platform

Role Full Stack DeveloperIndustry InsuranceUsers Internal Claims Teams

Overview

The FCI Claims Platform is a system used by FCI’s claims teams to process and pay out claims. It’s built on Laravel and Vue.js with Redis-backed WebSockets. The platform handles the full lifecycle of a claim, from intake to payment.

Over the past few years, I worked on this platform as a full-stack developer. I led several engineering initiatives that improved the system’s performance and functionality. I also worked closely with FCI’s client representatives to understand their needs and implement their ideas.

The three initiatives below share a common goal: they extend the same core real-time infrastructure to new parts of the business.

Business Challenge

Before these initiatives, the platform had several problems:

  • Concurrent editing safety: Adjusters could overwrite each other’s changes without warning.
  • Organizational depth: The platform only added or disabled dealership records, but didn’t represent dealer groups or territory managers.
  • Controlled, auditable payment: Claims were paid out manually, with no system-enforced spending limits.

Engineering Initiatives

Real-Time Claim Ownership

2+ years in production · Laravel · Vue · Redis · WebSockets

Fixed a problem where two adjusters could edit the same claim at the same time.

Problem

Adjusters worked from a shared claim queue, which meant they could open and edit the same claim at the same time. This caused problems:

  • One adjuster’s changes would be lost if the other adjuster saved last.
  • There was no way to see who else was working on a claim.
  • Supervisors couldn’t intervene when a claim was “stuck.”
  • As the number of claims grew, collisions became more frequent.

Solution

I built a system that assigns a claim to the first user who opens it and broadcasts that lock instantly to anyone else viewing the same claim.

When a second adjuster opens a locked claim, they see who has it and can review the claim without making changes. Supervisors with permission can reclaim a lock from a lower-permission user to unblock a stuck claim.

Technical Details

  • Locks are checked against the claim’s live WebSocket presence channel.
  • A scheduled cron job re-validates every locked claim against live channel occupancy.
  • The system has a manual kill-switch to disable WebSockets in case of an outage.
  • The system has a health check to verify the WebSocket service is reachable.
  • If the health check fails, the system releases every lock platform-wide.

Engineering Considerations

The system originally used Pusher for WebSocket broadcasting. When Pusher experienced a service failure, the system was affected. To prevent this in the future, I made the following changes:

  • Added a manual kill-switch to disable WebSockets in case of an outage.
  • Added a health check to verify the WebSocket service is reachable.
  • Added a scheduled cron job to release every lock platform-wide if the health check fails.
  • Migrated the WebSocket layer from Pusher to Soketi, a self-hosted alternative.

Outcome

  • Fixed the problem where two adjusters could edit the same claim at the same time.
  • Gave supervisors a safe way to unblock stuck claims.
  • Survived a live production outage of a core third-party dependency with no business disruption.
  • Remained one of the most heavily used pieces of frontend logic on the platform for over 2 years.

Synchronizing Dealer Data and Hierarchy

2+ years in production · Laravel · Vue · Redis · WebSockets

Built an automated daily sync to keep dealer data in sync with a nested XML feed, with real-time cascading disablement.

Problem

Dealer data was being pulled from the FCI third-party API through daily XML feeds, but there was no existing automated process to keep the data in the app in sync with the feed. Dealer data had to be handled outside of any scheduled reconciliation.

Solution

Built an automated sync job that parses the XML feed and reconciles dealer records against it, including detecting new dealerships and disabling ones that dropped out.

The sync handles more than just a flat dealership record from day one, because the business had introduced a new layer of organizational structure sitting on top of dealerships:

  • Dealer Groups — collections of dealerships under a shared parent.
  • Territory Managers — users responsible for a set of dealerships.
  • Territory Regions — a geographic/organizational grouping tying managers and dealerships together.

Every one of these new entities exists in relationship to a dealership, and dealerships themselves change constantly through the daily feed — added, disabled, reassigned.

Technical Highlights

  • A purpose-built XML parser: Built a new XmlUtility parser to handle the complex XML structure, including nested and repeated tags.
  • Polymorphic relationship table: Used a single user_relationships table to unify three otherwise-identical join tables, preventing duplicate relationship rows.
  • Reconciliation, not just insertion: Walked every dealer record in the parsed XML and called updateOrCreate for the dealer group, territory manager, and territory region tied to it, associating each back to the dealership as it goes.
  • Deactivation by absence: Tracked every dealer group/manager/region ID seen in this run and flipped is_active = false on anything in the database not in that set, triggering the cascade.
  • Pivot table rebuilt fresh every run: Territory manager-to-region assignments were collected during the loop, then cleared and re-synced from scratch every run.
  • Cascade logic centralized: Centralized the cascade logic in the DealerInfoService, making it easier to maintain and update.

Outcome

  • Built an automated dealership sync where none existed before.
  • Turned dealership data management into a full reconciliation of the dealership hierarchy.
  • Eliminated stale org-structure data.
  • Closed the real-time gap between a backend data change and its consequences for active users.
  • Gave admins accurate, live views of dealerships and org structure via a targeted, route-aware refresh.

Virtual Credit Card (VCC) Payments via USBank

2+ years in production · Laravel · Vue · Redis · WebSockets

We built a payment pipeline that makes sure payments are safe and reliable, even when the third-party payment API is slow or unreliable.

Problem

We had a problem where claims were paid instantly, without any checks on who was approving them or who was releasing the funds. This meant that a single person could approve and pay a claim all by themselves, without any checks.

The business wanted to let dealerships opt into being paid by virtual credit card instead, with USBank as the issuer. This introduced new requirements:

  • Eligibility had to be checked before a card was ever requested. Not every user is authorized to pay every dollar amount, and a single user shouldn’t be able to both approve a claim and release its payment.
  • A real financial instrument now had a lifecycle. A virtual card is created, has a balance, gets used, and eventually needs to be closed — none of which a flat “approved” status could represent on its own.
  • The claim’s active_status couldn’t just flip to “paid” the moment a user clicked approve. Card creation is a network call to a third party that can fail, time out, or need to be retried, so the status change had to be decoupled from the approval action and made resilient to USBank’s API being slow or unreliable.

What kicks off a payment. A user with edit access hits approveClaim() on an approved claim. If the dealership has VCC enabled ($dealership->vccEnabled()), the request runs through a chain of eligibility checks — checkTotal(), pay-point/pay-limit validation, platinumShieldApproval() — before anything is sent anywhere. Only once those pass does the claim either move straight to paid (non-VCC dealerships) or into payment_in_progress, and only then does CreditCardRemit get dispatched to actually talk to USBank.

What USBank’s API does. It’s a card-issuing API, not a full payment gateway — it doesn’t push money on its own or notify FCI when a card is used. UsBankClient authenticates with a client-credentials OAuth2 flow over mutual TLS (cert/ssl_key per environment), caches the resulting bearer token for 14 minutes (just under its 15-minute expiry), and then makes card operations against /virtual-cards/v1/cards: a POST with an Idempotency-Key to create a card and get back a card ID, CVV, and effective-until date; a /{id}/realtime-credit-details GET to pull a card’s live available balance; and a /{id}/close POST to close it out. Every request carries a fresh Correlation-ID for tracing a single call through USBank’s logs.

What had to be built around it. Because card creation is an external network call sitting inside a business process, almost everything interesting in this system exists to make that call safe to retry, safe to audit, and safe to leave half-finished without corrupting claim state.

Solution

We built the eligibility and dual-authorization logic into the approval endpoint itself, and everything downstream of “eligible” — card creation, status transition, notification, and eventual closure — into an idempotent, retryable job pipeline that reconciles with USBank rather than assuming a single request-response cycle will always succeed.

Eligibility and dual authorization live in approveClaim(). A user’s UserLimit (per program) determines both their pay_limit (max claim total they can release) and their pay_points (a weighted authority score). Two rules are enforced before a card is ever requested: the same user can’t be recorded as both the claim’s approver and its payer — checked by counting statusHistory() entries with a status of approved or pending_invoice against Auth::id() — and a single user’s pay_points must meet or exceed the claim’s ProgramLimit threshold, or the claim is parked in payment_in_progress so a second, different user’s points can combine with the first’s to clear it.

Card creation and status change happen inside CreditCardRemit, not the request/response cycle. The job builds the USBank payload from the claim’s XML-formatted data, requests the card with a cached idempotency key, and only updates virtual_card_id, is_virtual_card_open, vcc_effective_until, and vcc_balance once USBank confirms creation. If a card already exists for the claim (a retry after a partial failure), it skips straight to the status transition instead of creating a second card for the same claim.

Retry and failure handling assume USBank itself is unreliable. A ServerException on a 500 triggers a re-dispatch of the same job five minutes later, up to five times, per USBank’s own documented retry guidance — reusing the same idempotency key so a retried request can’t accidentally create a duplicate card. After five failures, or on any client-side error, failed() resets the claim’s in-progress flag and emails a dedicated USBank failure inbox so a stuck claim doesn’t sit silently.

Closure is a separate, independently reconcilable lifecycle step. Cards don’t close themselves just because a claim reached paid — CreditCardClose handles that as its own job with its own retry/backoff logic, and claims:close-credit-cards can run in bulk (auditing every open card’s live balance against USBank) or target a single claim by ID for manual intervention.

Technical Highlights

  • Idempotency key reuse across retries. generateIdempotencyKey() checks the cache for an existing key tied to the claim before generating a new one, and only clears it locally when testing — meaning a retried card-creation request after a transient failure reuses the exact same key USBank already saw, which is what prevents a retry from minting a second card for the same claim.
  • A dedicated logging channel instead of the default log. UsBankLog is a facade that walks the exception backtrace to capture the calling line, then writes through Log::channel('usbanklog') with a custom LineFormatter (LineFormatter) rather than the default one.
  • Duplicate frontend authorization logic, deliberately. canPay() in both ClaimSearchPage and ClaimReviewHeader independently re-derives the same rule as the backend: not the same user who last approved, and the combined pay_points of the current user and the claim’s active_status.user must meet the program’s required threshold. It’s re-implemented rather than shared because the two contexts (a full table row vs. a single claim’s action button) needed the check available synchronously in slightly different component shapes — the backend check in approveClaim() remains the actual source of truth either way.

Engineering Considerations

The dual-approval, combined-pay-points rule was the hardest part of this system to get right, not because any single check was complicated, but because “approver and payer must differ” and “one person’s authority might not be enough, but two people’s combined might be” needed to be true consistently across three different surfaces: the approval endpoint itself, the claims table’s row-level canPay(), and the individual claim view’s canPay(). Each of those had access to slightly different data shapes — the table has a flat claim listing, the review header has the fully loaded active claim with its nested active_status.user — so the same business rule had to be re-derived against each shape correctly, rather than written once and trusted everywhere.

The failure mode that made this worth getting right: without the approver/payer check, a single user with sufficient combined authority across two logins or sessions could approve and pay a claim entirely alone, defeating the reason payment_in_progress existed in the first place. Without the combined-points check reading the correct other user ($claim->activeStatus->user, not just whoever’s currently authenticated), a claim could get silently stuck in payment_in_progress forever, because the math would never find a second party’s points to add — or worse, under-verify and let a claim clear with less combined authority than the program required. Getting the identity of “the other approver” right — pulled from the claim’s own status history rather than assumed from context — was what made the combined-limit check trustworthy enough to gate an actual financial instrument being created.

Outcome

  • Gave FCI a payment path with real, enforced financial controls — spending limits per user, and a structural guarantee that approval and payment authority can’t collapse into a single person acting alone.
  • Turned “approve a claim” from an instant status flip into a resilient pipeline that survives USBank being slow, erroring, or timing out, without ever risking a duplicate card for the same claim.
  • Closed the gap USBank’s own webhooks left open with manual and automated reconciliation tools (claims:close-credit-cards, ResetClaimUsBankRequestInProgress) rather than depending on a third party’s callback reliability.
  • Extended the platform’s existing real-time infrastructure — the same WebSocket health check and the same “reconcile on a schedule, don’t trust a single event” pattern from claim locking — into a payments context instead of building parallel infrastructure from scratch.
  • Gave admins and dealership users live, accurate visibility into card and claim status without disrupting their place in a paginated, sorted table.

Claims Dashboard & Response-Time Analytics

2+ years in production · Laravel · Vue · Chart.js

Built the claims dashboard from scratch — role-aware activity feeds, pending-task breakdowns, and two analytics charts — then rebuilt the underlying time calculation after a business-hours miscalculation surfaced in production.

Problem

FCI’s claims teams had no single view into what needed attention or how the team was performing. Adjusters and admins had to work claim-by-claim through search filters to understand what was pending, and there was no visibility into how quickly claims were actually moving through the process.

The dashboard needed to serve two different audiences with two different permission levels — claims administrators and dealership-level users — without duplicating the page for each:

  • Activity and task visibility had to reflect only the statuses and actions each role was allowed to act on, not a generic list filtered after the fact.
  • Performance metrics — how long claims sat before a decision, and how long they took to actually process once submitted for payment — had no existing definition at all. What counted as the start and end of “response time” or “processing time” hadn’t been formally defined before this was built.

Solution

I built the dashboard as four independent panels — recent claim activity, a pending-tasks breakdown, two response/processing time charts, and a claim status summary — each backed by its own Vuex module state and API endpoint, so any panel can reload or filter independently of the others.

Role-aware pending tasks. DashboardModuleLoader::pendingTasks() builds an entirely different task taxonomy depending on whether the user can edit claims. An admin sees tasks grouped around approval authority — a single “Approvals” bucket absorbing both Pending Approval and Re-Submitted claims, with Re-Submitted also feeding a separate “Invoice Review” bucket filtered to claims with an attached invoice. A dealership user instead sees their own claim’s progress — information requests, invoice requests, awaiting payment — with no approval-authority tasks at all, since those aren’t actionable for their role. Each bucket’s count comes from a shared count_claims() closure that re-applies the same status and attachment filters used to build the bucket in the first place, rather than a second, independently-written query.

Two charts, two different definitions of “time.” DashboardService computes average response time (claim submission → approval/decline, in minutes) and average processing time (submitted for payment → paid, in days) per claim type — tire & rim, key & remote, platinum shield, auto guard — off the same underlying status-history walk, differing only in which status pairs count and whether the result is measured in minutes or days.

Technical Highlights

  • A single algorithm walking status-history pairs, parameterized by direction. findAvgTimeBetweenStatuses() walks each claim’s ordered status history looking for a transition from a defined “previous” status into a defined “active” status. Which status pairs qualify — and whether the result is measured in business minutes or calendar days — is entirely driven by the RespondedStatuses/ProcessedStatuses constant passed in, so the same method backs both charts instead of two parallel implementations.
  • A rolling average computed inside the loop, not after it. Rather than summing every status-change gap and dividing once at the end, $total /= $status_change_count recalculates the running average after every qualifying transition — which matters because a single claim can have more than one previous→active transition in its history (e.g., re-submitted and re-approved), and each one needed to be folded into that claim’s average as it was found.
  • Status IDs cached, not requeried per calculation. getCachedStatusIds() caches the resolved status-ID lists for both chart types for 24 hours, since they’re looked up on every dashboard load and every filter change but change essentially never.
  • A debug export command for verifying the math independently of the UI. dashboard:average-response-time authenticates as a super-admin, runs the same DashboardService logic in a “testing” mode that returns full claim-level status data — not just the averages — then writes it to a temporary file behind a signed URL that expires in five minutes and deletes itself after download. Built specifically so the underlying claim-level data behind a suspicious average could be pulled and checked by date range, without needing direct database access.
  • Claim summary counts collapsed for non-admin views. claimSummary() folds payment_in_progress counts into submitted_payment and hides the payment_in_progress row entirely for non-FCIC-admin users — a payment sub-status that’s meaningful internally but not something a dealership user needs to distinguish.

Engineering Considerations

Roughly a year and a half after this shipped, following a permissions and role restructure elsewhere in the platform, a client-side executive flagged that the average response time on the dashboard looked wrong — the reported number was higher than it should reasonably be. Diagnosing it took real back-and-forth: the original ticket’s definition of “response time” wasn’t fully unambiguous, and confirming what the client actually wanted to measure required working through a client-side representative transition mid-thread, since the original contact who’d have known the original intent had since moved on.

The root cause turned out to be that the calculation counted raw wall-clock time between status changes, including nights, weekends, and any gap where a claim simply sat untouched outside business hours. I rebuilt the calculation to count only business hours — 6AM to 6PM, excluding weekends — via calculateBusinessMinutes(), which walks day-by-day between the two timestamps, skips weekend days entirely, and clips each day’s contribution to the 6AM–6PM window (including partial first and last days). That single change dropped the reported average significantly and brought it in line with what the business actually expected the number to represent.

Verifying the fix wasn’t a one-shot deploy — it went through a UAT round checking specific claims against specific dates, including edge cases like claims created or actioned outside official hours, before it was signed off as correct.

Outcome

  • Gave claims teams and dealership users a single dashboard reflecting only the actions and data relevant to their own permission level, instead of a generic view filtered after the fact.
  • Defined and shipped the platform’s first formal response-time and processing-time metrics, broken out per claim type.
  • Diagnosed and corrected a real production data-accuracy issue flagged by the client, rebuilding the core time calculation around actual business hours rather than wall-clock time — verified through a full UAT pass before sign-off.
  • Built lasting debug tooling (dashboard:average-response-time) that lets the underlying claim-level data behind any reported average be pulled and audited independently of the dashboard UI.

Architecture

The platform is built on a Laravel backend and a Vue 2 frontend, with MySQL for data storage and Redis-backed WebSockets driving real-time updates.

A common pattern across the major initiatives is to verify state independently, rather than relying on a single event to be correct. This is achieved through WebSocket health checks and scheduled reconciliation jobs.

Results

The initiatives achieved several goals:

  • Concurrent editing safety: A locking system was implemented to prevent silent overwrites.
  • Survived a production outage: The system survived a live production outage of a core third-party dependency without business disruption.
  • Full reconciliation of dealership hierarchy: The platform now syncs the dealership organizational hierarchy in real-time.
  • Virtual credit card payment path: The platform now has a virtual credit card payment path with enforced financial controls.
  • Reliability gap in webhooks: The platform now closes a reliability gap in USBank’s webhooks with automated and manual reconciliation tooling.

Client Collaboration

I worked directly with FCI’s client representatives as the day-to-day technical point of contact. I scoped what was feasible, walked through trade-offs, and brought my own ideas to the table. This relationship spanned roughly three years and two different representatives.

Scope

Backend

  • Real-time claim ownership and locking
  • WebSocket infrastructure (Pusher → Soketi migration)
  • Scheduled reconciliation jobs (locking, org sync, payments)
  • XML data sync and dealership hierarchy modeling
  • Virtual credit card payment pipeline (USBank integration)
  • Dual-authorization approval logic

Frontend

  • Real-time lock state via Vuex-backed mixins
  • Live claim, dealership, and org-structure table updates
  • Row-level and claim-level payment authorization checks

Infrastructure

  • MySQL, Redis
  • Self-hosted Soketi WebSocket server
  • USBank card-issuing API (OAuth2 client credentials, mutual TLS)
PreviousMaking a Job Search MeasurableNextScreen Recording Audit Solution

Technologies

LaravelVue.jsMySQLRedisWebSocketsREST APIsVuex

Engineering Highlights

  • Real-time claim locking and ownership
  • Pusher to self-hosted Soketi migration
  • 175+ dependent components migrated without disruption
  • Idempotent U.S. Bank payment pipeline
  • Dual authorization separating approval from payment release
  • Hierarchical dealership reconciliation with cascading updates
  • Reconciliation architecture reused across three subsystems
On this page
  • Overview
    • Business Challenge
  • Engineering Initiatives
    • Real-Time Claim Ownership
      • Problem
      • Solution
      • Technical Details
      • Engineering Considerations
      • Outcome
    • Synchronizing Dealer Data and Hierarchy
      • Problem
      • Solution
      • Technical Highlights
      • Outcome
    • Virtual Credit Card (VCC) Payments via USBank
      • Problem
      • Solution
      • Technical Highlights
      • Engineering Considerations
      • Outcome
    • Claims Dashboard & Response-Time Analytics
      • Problem
      • Solution
      • Technical Highlights
      • Engineering Considerations
      • Outcome
  • Architecture
  • Results
  • Client Collaboration
  • Scope
    • Backend
    • Frontend
    • Infrastructure

All work

Case studies

  • Teaching Without TranslatingA media platform that transcribes, translates, and burns subtitles into instructional video — built so a safety instructor could stop translating aloud over her own lessons, after a thirteen-day emergency script proved the problem was worth solving properly.Laravel 12Laravel OctaneVue 3 Live Source
  • Making a Job Search MeasurableAn open-source job search workspace that turns applications, conversations, interviews, and follow-ups into one traceable workflow — then uses the history of that work to show what is actually producing results.Laravel 13PHP 8.3Vue 3 Source
  • Modernizing an Insurance PlatformAn enterprise claims management platform designed to streamline claim processing, improve collaboration, and automate complex business workflows.LaravelVue.jsMySQL
  • Screen Recording Audit SolutionAn enterprise compliance and AI-powered auditing platform for automotive F&I presentations, featuring browser-based recording, automated transcription, searchable subtitles, and PDF audit reporting.LaravelPHPVue 2

Open source

Focused projects whose code is the case study.

  • Laravel Query FiltersA composable, allowlist-based Eloquent filtering package with explicit value-presence rules, safe wildcard handling, relationship search, and an extension API for application-specific filters.PHPLaravelEloquent GitHub Composer
  • Pinia HydrateA Composer package and npm package sharing one versioned JSON envelope, letting Laravel explicitly hydrate or patch Pinia stores in Vue 3 without inspecting Pinia internals or scanning the filesystem for stores.PHPLaravelVue 3PiniaTypeScriptInertia GitHub Composer npm
  • Vue FormsAccessible Vue 3 form field components with framework-neutral error handling, SSR-stable field IDs, Laravel 13-inspired default styling, and an optional Inertia integration layer.Vue 3TypeScriptInertiaVite GitHub npm

Experiments

Built for their own sake. No write-ups.

  • Kim Painting CMS2022A custom website and lightweight CMS that lets a painting contractor manage pages, navigation, projects, galleries, testimonials, and customer enquiries without developer support.LaravelLivewireAlpine.jsTailwind
  • Desktop Environment Portfolio2023A browser window manager — drag, resize, snap, minimise to dock with a genie animation. Never shipped: I bolted an admin backend onto a portfolio, which is a lesson rather than a feature. Its window logic runs this site.Vue 3PiniaLaravel
  • 2D RPG Engine2023Quest, inventory, dialog and NPC systems built from scratch, because the interesting part of a game is the systems underneath it.GameMaker Studio 2GML
  • Encrypted Chat Platform2021Direct and group chat with Pretty Good Privacy encryption — written before I had any business writing crypto, which was the point.PHPMySQLJavaScriptjQuery

Nothing matches that.