From 508b3d43c705b64060cc1a04ebbc67672f121d08 Mon Sep 17 00:00:00 2001 From: Kyle Neal Date: Thu, 19 Mar 2026 12:00:20 -0500 Subject: [PATCH 1/4] (enhance) Update resume + portfolio site --- assets/resume/kyle-neal-resume.pdf | Bin 129960 -> 129909 bytes priv/resume/kyle-neal-resume.pdf | Bin 129960 -> 129909 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/resume/kyle-neal-resume.pdf b/assets/resume/kyle-neal-resume.pdf index 3f85605719a7c511e8bdf1283400e4ee13fe86b2..6e323e1b501fd913c4311e76426745991b92c7c8 100644 GIT binary patch delta 18621 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 Vrfr(b>-qC>|3qA_*W2U!@(b1WY{38k delta 18727 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

-+gzB-h|^?o@db=f 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 Vrfr(b>-qC>|3qA_*W2U!@(b1WY{38k delta 18727 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

-+gzB-h|^?o@db=f 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 Date: Thu, 19 Mar 2026 12:32:05 -0500 Subject: [PATCH 2/4] (enhance) content updates for portfolio site --- lib/revstack_web/live/whoami_live.ex | 563 ++++++++++++------ test/revstack_web/layouts_user_menu_test.exs | 2 +- .../whoami_live_career_modal_test.exs | 43 ++ test/revstack_web/whoami_live_layout_test.exs | 17 +- .../whoami_live_projects_test.exs | 25 +- 5 files changed, 455 insertions(+), 195 deletions(-) diff --git a/lib/revstack_web/live/whoami_live.ex b/lib/revstack_web/live/whoami_live.ex index 4b3fd13..753d5ec 100644 --- a/lib/revstack_web/live/whoami_live.ex +++ b/lib/revstack_web/live/whoami_live.ex @@ -65,9 +65,9 @@ defmodule RevstackWeb.WhoamiLive do def mount(_params, _session, socket) do socket = assign(socket, - page_title: "Kyle Neal | Lead Elixir & Erlang Engineer", + page_title: "Kyle Neal | Lead Distributed Systems Engineer", page_description: - "Kyle Neal — Lead Distributed Systems Engineer specializing in Erlang/OTP, Elixir, Phoenix LiveView, high-volume event processing, and technical leadership.", + "Kyle Neal — Lead Distributed Systems Engineer specializing in Erlang/OTP, Elixir, high-throughput event systems, distributed data platforms, and hands-on technical leadership.", current_path: "/whoami", admin_gallery_open?: false, admin_gallery_index: 0, @@ -210,20 +210,21 @@ defmodule RevstackWeb.WhoamiLive do

- <.icon name="hero-user" class="size-4" /> Technical Profile + <.icon name="hero-cpu-chip" class="size-4" /> Distributed Systems Engineer

Kyle Neal

- Lead Elixir & Erlang Engineer + Lead Distributed Systems Engineer

- 10+ years building revenue-critical distributed systems on the BEAM. - Erlang/OTP, Elixir, Phoenix LiveView, Cassandra, RabbitMQ, and technical leadership. + Erlang/OTP and Elixir engineer building revenue-critical systems on the BEAM. + I've owned affiliate tracking, attribution, reporting, and infrastructure platforms + supporting 1.5M+ events/day, $2.5M+ monthly revenue, and hands-on leadership of up to 5 engineers.

@@ -288,11 +289,37 @@ defmodule RevstackWeb.WhoamiLive do ~H"""
-
- <.stat_card value="10+" label="Years on the BEAM" /> - <.stat_card value="1.5M+" label="Daily events processed by systems I built" /> - <.stat_card value="$2.5M+" label="Monthly revenue supported by systems I built" /> - <.stat_card value="5" label="Engineers managed" /> +
+ <.stat_card + value="10+" + headline="Years building on the BEAM" + detail="Erlang/OTP + Elixir in production" + /> + <.stat_card + value="1.5M+" + headline="Events processed per day" + detail="tracking, attribution, and reporting workloads" + /> + <.stat_card + value="$2.5M+" + headline="Monthly revenue supported" + detail="revenue-critical platform ownership" + /> + <.stat_card + value="6-node" + headline="Cassandra event store" + detail="operated in production for high-volume tracking data" + /> + <.stat_card + value="~25%" + headline="Infrastructure cost reduction" + detail="delivered through audits and scaling changes" + /> + <.stat_card + value="5" + headline="Engineers led hands-on" + detail="across UI and infrastructure" + />
@@ -310,35 +337,35 @@ defmodule RevstackWeb.WhoamiLive do
<.summary_item icon="hero-cpu-chip" - text="Lead Distributed Systems Engineer focused on long-lived, production BEAM systems (Erlang/OTP + Elixir)" + text="Lead distributed systems engineer specializing in long-lived production systems built with Erlang/OTP and Elixir" /> <.summary_item icon="hero-server-stack" - text="Builds and operates high-throughput, revenue-critical platforms with a strong performance and operability mindset" + text="Built and operated a revenue-critical affiliate platform handling high-volume click tracking, attribution, callbacks, analytics, and partner reporting" /> <.summary_item - icon="hero-circle-stack" - text="Designs distributed data + messaging architectures across Cassandra/PostgreSQL, RabbitMQ, and search/analytics" + icon="hero-cog-6-tooth" + text="Architected NetAdmin, an Elixir/Phoenix LiveView + Ash control plane for lifecycle orchestration, monitoring, auditability, and automation" /> <.summary_item - icon="hero-magnifying-glass" - text="Owns data modeling and query tuning across OLTP and time-series workloads, with deep comfort debugging production paths" + icon="hero-circle-stack" + text="Designs distributed data and messaging systems across Cassandra, PostgreSQL, RabbitMQ, Elasticsearch/OpenSearch, and Spark pipelines" /> <.summary_item - icon="hero-cog-6-tooth" - text="Reliability-first engineering: OTP fault tolerance, BEAM VM tuning, release strategy, CI/CD automation, and incident response" + icon="hero-globe-alt" + text="Comfortable close to the wire with HTTP, WebSockets, DNS, SMTP, and proxying in production systems" /> <.summary_item - icon="hero-computer-desktop" - text="Full-stack builder with Phoenix/LiveView and Ash; ships internal platforms and tooling from concept to production" + icon="hero-bolt" + text="Reliability-focused owner of OTP supervision, BEAM tuning, relup upgrades, CI/CD, and production incident debugging" /> <.summary_item icon="hero-user-group" - text="Hands-on technical leader: mentors engineers, aligns cross-team delivery, and stays deep in the code" + text="Hands-on technical lead who hired, mentored, and managed up to 5 engineers without stepping away from architecture or code" /> <.summary_item icon="hero-cloud" - text="Infrastructure-aware across AWS and Linux, with pragmatic automation experience (Jenkins/Ansible)" + text="Infrastructure-aware across AWS, Linux, VPS fleets, Jenkins, and Ansible, with a practical cost and operability mindset" />
@@ -361,33 +388,34 @@ defmodule RevstackWeb.WhoamiLive do <.expertise_group title="BEAM & Languages" items={[ - "Erlang/OTP (GenServers, Supervisors, clustering)", - "Elixir", + "Erlang/OTP for high-throughput, fault-tolerant services", + "Elixir application and platform development", "Phoenix + LiveView", "Ash Framework", - "BEAM VM tuning & relup zero-downtime upgrades", - "REST API design & third-party integrations" + "BEAM VM tuning and relup zero-downtime upgrades", + "REST API design and third-party integrations" ]} /> <.expertise_group title="Data & Messaging" items={[ - "Cassandra (6-node production cluster)", - "PostgreSQL", - "Elasticsearch / OpenSearch analytics", - "Apache Spark (AWS EMR)", + "Cassandra (6-node production cluster, time-series modeling)", + "PostgreSQL query tuning and reporting workloads", "RabbitMQ distributed messaging pipelines", - "Time-series data modeling (1.5M+ events/day)" + "Elasticsearch / OpenSearch analytics", + "Apache Spark (Scala, AWS EMR)", + "Event ingestion and reporting pipelines at 1.5M+ events/day" ]} /> <.expertise_group - title="Infrastructure & DevOps" + title="Infrastructure & Protocols" items={[ "AWS (EC2, RDS, S3)", "Linux operations & administration", "Ansible automation", - "CI/CD (Jenkins, Ansible)", - "Observability & reliability engineering" + "CI/CD with Jenkins", + "HTTP, WebSockets, DNS, SMTP, and proxies", + "Observability, monitoring, and reliability engineering" ]} />
@@ -409,32 +437,37 @@ defmodule RevstackWeb.WhoamiLive do
<.experience_card + id="experience-ionik" title="Lead Distributed Systems Engineer" - company="Ubiquity Agency an Ionik company" - period="October 2014 — 2026" - current?={false} + company="Ionik (formerly VeriAS)" + period="October 2014 — Present" + current?={true} items={[ - "Lead architect and primary backend engineer for a revenue-critical affiliate network platform written in Erlang, supporting $2.5M+ monthly revenue and processing 1.5M+ events daily (~20+ events/sec average with significantly higher peak throughput).", - "Design and operate distributed data and messaging architecture including a 6-node Cassandra production cluster, RabbitMQ event pipelines, and Elasticsearch/OpenSearch analytics infrastructure.", - "Own data modeling and performance strategy across Cassandra and PostgreSQL; routinely debug and optimize complex production queries and high-volume transaction paths.", - "Responsible for system reliability, BEAM VM tuning, release strategy (relup), CI/CD automation, and production incident debugging across distributed environments.", - "Architected and built an internal infrastructure management platform from inception, a full-stack Elixir (Phoenix + Ash) internal infrastructure control platform enabling resource lifecycle orchestration, authorization modeling, operational auditability, and cross-system automation.", - "Lead and managed 5 engineers (UI + infrastructure) while remaining hands-on across backend, data architecture, and full-stack feature delivery. Conducted technical interviews and evaluated engineering candidates as part of the hiring process." + "Lead architect and primary backend engineer for a revenue-critical affiliate marketing platform using Erlang/OTP. The platform supports $2.5M+ monthly revenue, processes 1.5M+ events daily, and powers high-volume click tracking, attribution, and real-time partner reporting.", + "Owned backend platform design across tracking, analytics, and partner connectivity, including REST APIs and internal service integrations used throughout the product.", + "Designed and operated distributed data and messaging architecture including a 6-node Cassandra production cluster, RabbitMQ event pipelines, and Elasticsearch/OpenSearch analytics infrastructure.", + "Owned data modeling across Cassandra and PostgreSQL; routinely debugged and optimized high-volume transaction paths, production SQL, and reporting workloads.", + "Built Apache Spark (Scala, AWS EMR) pipelines that aggregated Cassandra raw event data into PostgreSQL datasets used for analytics and financial reporting.", + "Architected and built NetAdmin, an internal Elixir platform using Phoenix, LiveView, and Ash Framework for resource lifecycle orchestration, distributed systems monitoring, operational auditability, and cross-system automation.", + "Owned system reliability across BEAM VM tuning, relup strategy, CI/CD automation, Ansible-based infrastructure automation, and production incident debugging in distributed environments.", + "Led and managed up to 5 engineers across UI and infrastructure while remaining hands-on in backend development, data architecture, and full-stack delivery. Conducted technical interviews and hiring evaluations.", + "Managed cloud and infrastructure operations across AWS, domains, and VPS providers, and implemented audits and scaling changes that reduced infrastructure operating costs by ~25%." ]} /> <.experience_card + id="experience-revenuelink" title="Founder & Software Engineer" company="RevenueLink Technologies LLC" period="2023 — Present" current?={true} items={[ - "Founded a consulting and technology services company used for independent software projects, consulting engagements, and local technology services.", + "Founded a consulting and software vehicle for independent projects, select consulting engagements, and Elixir/Phoenix experiments.", {:parts, [ {:text, "Designed and built "}, {:link, "https://hardcorehandyman.fly.dev/", "hardcorehandyman.fly.dev"}, {:text, - " (formerly hardcorehandymanoflawton.com), a custom lead-generation platform for a local handyman business. Built with Elixir, Phoenix LiveView, and Ecto, the system included SEO-driven service pages, conversion-focused design, and an internal admin interface for managing customer quote requests with photo uploads of project details. "}, + ", a custom Phoenix LiveView lead-generation platform for a local handyman business. The system included SEO-driven service pages, a quote workflow with photo uploads, and an internal admin interface for managing requests. "}, {:strong, "The platform ultimately generated more inbound demand than the business could operationally support."} ]}, @@ -443,10 +476,9 @@ defmodule RevstackWeb.WhoamiLive do {:text, "Built and operate "}, {:link, "https://revstack.fly.dev/", "revstack.fly.dev"}, {:text, - ", a Phoenix LiveView application serving as a professional portfolio, lead-generation platform, and development sandbox for new ideas."} + ", a Phoenix LiveView application serving as a recruiter-facing portfolio, lead-generation platform, and sandbox for new ideas."} ]}, - "Provide consulting and technical services including custom web application development, systems architecture guidance, and local technology support for individuals and small businesses.", - "Use the company as a vehicle for experimentation with Elixir, distributed systems, infrastructure tooling, and small SaaS-style projects." + "Use the company as a vehicle for consulting, hands-on product work, and experimentation with Elixir, infrastructure tooling, and small SaaS-style projects." ]} /> <.experience_card @@ -486,7 +518,9 @@ defmodule RevstackWeb.WhoamiLive do

Career Portfolio

- Two major chapters of production systems engineering on the BEAM.
+ The affiliate platform is the centerpiece of my career story, and NetAdmin is the major + Elixir platform I built alongside it. Supporting systems are grouped the way they were + actually owned in production.
<.icon name="hero-cursor-arrow-rays" class="size-7 inline-block align-text-bottom" @@ -517,7 +551,8 @@ defmodule RevstackWeb.WhoamiLive do

Personal Live Projects

- Production applications I designed, built, and deployed on my spare time
+ Recent side projects and deployed experiments outside the affiliate platform and NetAdmin work. +
<.icon name="hero-cursor-arrow-rays" class="size-5 inline-block align-text-bottom" @@ -529,7 +564,7 @@ defmodule RevstackWeb.WhoamiLive do <.project_card id="project-handyman" title="Hardcore Handyman" - subtitle="Production Phoenix LiveView system enabling customers to submit job requests with image uploads. Data is validated, stored with Ecto, and triggers email notifications for a streamlined quoting workflow." + subtitle="Phoenix LiveView lead-generation system with quote requests, photo uploads, SEO-driven service pages, and an admin workflow that generated more demand than the business could operationally support." href="https://hardcorehandyman.fly.dev/" icon="hero-wrench-screwdriver" preview_src={~p"/images/hardcorehandyman_preview.png"} @@ -537,18 +572,18 @@ defmodule RevstackWeb.WhoamiLive do /> <.project_card id="project-admin" - title="Admin Dashboard (for this site!)" - subtitle="Custom-built admin dashboard for managing leads and estimates. Features real-time data grids, filtering, status management, and single-user authentication." + title="Revstack Admin Dashboard" + subtitle="Internal Phoenix LiveView admin surface for managing leads and estimates, with real-time data grids, filtering, status workflows, and authenticated operations." href="https://github.com/kyle-neal/revstack" icon="hero-cog-6-tooth" preview_src={~p"/images/admin_panel/admin_dashboard.png"} - tech={~w(Elixir Phoenix LiveView Ash Postgres)} + tech={["Elixir", "Phoenix", "LiveView", "Ash Framework", "Postgres"]} on_click="open_admin_gallery" /> <.project_card id="project-revenuelink" title="RevenueLink" - subtitle="My personal business website and portfolio hub. Showcases my professional profile and services, and serves as a central point for inquiries and collaborations." + subtitle="Consulting and business site for RevenueLink Technologies, used as a public home for services, projects, and lightweight product experiments." href="https://revenuelink.net/" icon="hero-building-office-2" preview_src={~p"/images/revenuelink_preview.png"} @@ -575,13 +610,13 @@ defmodule RevstackWeb.WhoamiLive do <.education_card degree="B.S. Computer Science" school="Cameron University" - period="2010 — 2014" + period="Fall 2010 — July 2014" honors="Magna Cum Laude" /> <.education_card degree="A.S. Information Technology" school="Cameron University" - period="2014 — 2016" + period="Fall 2012 — June 2014" honors="Magna Cum Laude" />

@@ -601,8 +636,9 @@ defmodule RevstackWeb.WhoamiLive do

Leadership & Teamwork

- Technical leadership across distributed teams, from architecting production systems to - mentoring engineers and coordinating cross-functional delivery. + Hands-on technical leadership across backend, infrastructure, and delivery. I stayed + responsible for architecture and production systems while leading engineers, hiring, and + driving operational decisions.

@@ -610,27 +646,27 @@ defmodule RevstackWeb.WhoamiLive do
<.leadership_item icon="hero-building-office" - text="Architecture ownership across all production systems" + text="Long-term ownership of revenue-critical backend platforms" /> <.leadership_item icon="hero-academic-cap" - text="Mentored & managed 5 engineers across backend and infrastructure" + text="Led, mentored, and managed up to 5 engineers" /> <.leadership_item - icon="hero-arrows-right-left" - text="Coordinated frontend, backend & infrastructure teams" + icon="hero-user-plus" + text="Conducted technical interviews and engineering evaluations" /> <.leadership_item icon="hero-arrow-trending-up" - text="Scaled platforms to $2.5M+ monthly revenue" + text="Scaled systems supporting $2.5M+ monthly revenue" /> <.leadership_item icon="hero-calendar" - text="Managed delivery timelines, releases & incident response" + text="Managed releases, incidents, and infrastructure operations" /> <.leadership_item icon="hero-wrench-screwdriver" - text="Hands-on across backend, full-stack & DevOps delivery" + text="Reduced infrastructure operating costs by ~25%" />
@@ -645,9 +681,9 @@ defmodule RevstackWeb.WhoamiLive do <.icon name="hero-user-group" class="size-5" />
-

Affiliate Platform Team

+

Affiliate Platform Ownership

- Poland-based backend & DevOps collaboration + Distributed backend and operations collaboration

@@ -656,23 +692,23 @@ defmodule RevstackWeb.WhoamiLive do
  • <.icon name="hero-chevron-right" class="size-4 text-primary shrink-0 mt-0.5" /> - Collaborated with 5 backend - and 3 DevOps engineers - to build a multi-million-dollar affiliate network platform. + Partnered with backend and infrastructure engineers across multiple stages of the + platform, then became the long-term owner of backend architecture, features, and + production operations.
  • <.icon name="hero-chevron-right" class="size-4 text-primary shrink-0 mt-0.5" /> - Partnered with 2 lead engineers - on architecture and initial production launch, then became the sole owner - for features, maintenance, and major rewrites. + Worked directly with the CTO on business rules, partner integrations, reporting + requirements, and production decision-making for the affiliate platform.
  • <.icon name="hero-chevron-right" class="size-4 text-primary shrink-0 mt-0.5" /> - Ultimately rewrote more of the system than the original team-built release contained. + Rewrote and expanded major portions of the system over time while keeping the + platform live, revenue-critical, and operationally stable.
  • @@ -689,7 +725,7 @@ defmodule RevstackWeb.WhoamiLive do

    Infrastructure Team

    - Built & led a self-managed ops team + Hands-on infrastructure and operational leadership

    @@ -698,16 +734,16 @@ defmodule RevstackWeb.WhoamiLive do
  • <.icon name="hero-chevron-right" class="size-4 text-primary shrink-0 mt-0.5" /> - Built a Philippines-based infrastructure team to operate as a - self-managed unit - with the structure and autonomy to run independently. + Led up to 3 infrastructure engineers + and 2 UI engineers + while still owning critical backend architecture, reliability work, and escalations.
  • <.icon name="hero-chevron-right" class="size-4 text-primary shrink-0 mt-0.5" /> - Balanced delegation with hands-on involvement during high-pressure delivery periods, - keeping the team sustainable and operationally independent. + Managed AWS, VPS, domain, and operational cost decisions directly, including audits + and scaling changes that lowered infrastructure spend by ~25%.
  • @@ -753,11 +789,11 @@ defmodule RevstackWeb.WhoamiLive do

    - Hiring for a role? + Hiring for a remote role?

    - I'm always open to discussing the right engineering opportunity. + Open to the right Erlang/Elixir, platform, or distributed systems opportunity.

    <.link navigate={~p"/contact"} class="btn btn-primary gap-2"> @@ -1108,10 +1144,20 @@ defmodule RevstackWeb.WhoamiLive do end defp stat_card(assigns) do + assigns = + assigns + |> assign(:headline, Map.get(assigns, :headline, Map.get(assigns, :label))) + |> assign_new(:detail, fn -> nil end) + ~H""" -
    -

    {@value}

    -

    {@label}

    +
    +

    {@value}

    +

    + {@headline} +

    +

    + {@detail} +

    """ end @@ -1142,8 +1188,13 @@ defmodule RevstackWeb.WhoamiLive do end defp experience_card(assigns) do + assigns = assign_new(assigns, :id, fn -> nil end) + ~H""" -
    +

    {@title}

    @@ -1348,7 +1399,30 @@ defmodule RevstackWeb.WhoamiLive do {@phase.overview}

    <.phase_scale_metrics :if={Map.get(@phase, :metrics)} metrics={@phase.metrics} /> -
    + +
    + <.career_project_group + :for={group <- @phase.project_groups} + phase={@phase} + group={group} + /> +
    +

    <.icon name="hero-cursor-arrow-rays" class="size-4 inline-block align-text-bottom" /> Click any project for the full story @@ -1403,12 +1477,26 @@ defmodule RevstackWeb.WhoamiLive do end defp career_project_card(assigns) do + assigns = assign_new(assigns, :featured?, fn -> false end) + ~H""" + """ + end + + defp career_project_group(assigns) do + assigns = assign(assigns, :projects, phase_projects(assigns.phase, assigns.group.project_ids)) + + ~H""" +

    +
    +
    + <.icon name={@group.icon} class="size-5" /> +
    +
    +

    {@group.title}

    +

    {@group.description}

    +
    +
    +
    + <.career_project_list_item :for={project <- @projects} project={project} /> +
    +
    + """ + end + + defp career_project_list_item(assigns) do + ~H""" + """ end @@ -1448,12 +1594,14 @@ defmodule RevstackWeb.WhoamiLive do label in [ "Cassandra", "Elasticsearch", + "Elasticsearch/OpenSearch", "PostgreSQL", "RabbitMQ", "Distributed Systems", "Infrastructure Reliability", "Platform Ownership", - "Leadership" + "Leadership", + "Technical Leadership" ] -> "skill-badge-subtle" @@ -1742,6 +1890,13 @@ defmodule RevstackWeb.WhoamiLive do # Career Portfolio Data # --------------------------------------------------------------------------- + defp phase_projects(phase, project_ids) do + Enum.map(project_ids, fn project_id -> + Enum.find(phase.projects, &(&1.id == project_id)) + end) + |> Enum.reject(&is_nil/1) + end + defp find_career_project(phases, project_id) do Enum.find_value(phases, fn phase -> Enum.find(phase.projects, &(&1.id == project_id)) @@ -2145,108 +2300,141 @@ defmodule RevstackWeb.WhoamiLive do title: "Affiliate Network Platform & Infrastructure Leadership", card_title: "Affiliate Network Platform", card_icon: "hero-chart-bar", - card_era: "2018–2026 — Senior Engineer & Platform Ownership", + card_era: "2018–Present — Senior Engineer & Platform Ownership", card_summary: - "Built and owned a revenue-critical affiliate network platform end-to-end, spanning high-throughput Erlang services, internal Elixir/Phoenix tooling, and large-scale Cassandra, Elasticsearch, and PostgreSQL data systems.", + "Long-term ownership of a revenue-critical affiliate marketing platform in Erlang/OTP, complemented by NetAdmin, the Elixir control plane I built for infrastructure lifecycle orchestration and monitoring.", card_badges: [ "Erlang/OTP", "Elixir", "Phoenix LiveView", "Ash Framework", "Cassandra", - "Elasticsearch", + "Elasticsearch/OpenSearch", "RabbitMQ", "PostgreSQL", - "Apache Spark (scala)", + "Apache Spark", "REST APIs", - "High-Throughput Backends", - "Leadership over UI and Infrastructure Engineers", - "Event Driven Architecture and Pipelines", - "Big Data Processing", - "Reporting and Analytics", + "HTTP", + "WebSockets", + "DNS", + "SMTP", + "Technical Leadership", "Affiliate Marketing Technology" ], card_bullets: [ - "Owned the entire backend stack of a $2.5M+/month affiliate network platform", - "Designed event-driven click tracking, redirect, and conversion systems at scale", - "Operated Cassandra, Elasticsearch, and Spark across ~1.2PB of combined data", - "Led supporting engineers while remaining hands-on across all backend systems" + "Owned the backend architecture of a $2.5M+/month affiliate platform processing 1.5M+ events/day", + "Built click tracking, attribution, reporting, and partner integration systems in Erlang/OTP", + "Architected NetAdmin in Elixir/Phoenix LiveView/Ash as the internal infrastructure control plane", + "Led UI and infrastructure engineers while staying hands-on in architecture, code, and operations" ], overview: - "Architected and operated backend systems powering a large affiliate marketing platform processing millions of daily events. Later built internal infrastructure management tooling used across multiple company systems.", + "This phase is the core of my professional story: long-term ownership of a revenue-critical affiliate marketing platform, plus the Elixir control plane I built to manage infrastructure and operational workflows around it.", metrics: [ %{value: "1.5M+", label: "events / day"}, - %{value: "~250", label: "peak events / sec"}, - %{value: "~600", label: "peak redirects / sec"}, + %{value: "$2.5M+", label: "monthly revenue"}, %{value: "6-node", label: "Cassandra cluster"}, - %{value: "3-node", label: "ES cluster"}, - %{value: "~600 TB", label: "Cassandra footprint"}, - %{value: "~600 TB", label: "ES analytics"}, - %{value: "12+", label: "years ownership"} + %{value: "~25%", label: "lower infra costs"}, + %{value: "5", label: "engineers led"} ], team: %{ description: - "Kyle served as the lead backend engineer for the affiliate platform, responsible for architecture, development, and production operations.", + "I stayed hands-on while leading engineers, owning backend architecture, and driving production operations for the affiliate platform and the systems around it.", members: [ - "Worked closely with the CTO on business issues and core technology", - "Kyle owned the entire affiliate network platform backend stack", - "Led 2 UI engineers building customer-facing tools on top of the platform", - "Led 3 infrastructure engineers that managed the underlying VPS, DNS, and monitoring infrastructure supporting the platform" + "Worked closely with the CTO on partner requirements, reporting needs, business rules, and core technology decisions", + "Owned the long-term backend architecture for the affiliate platform and its supporting services", + "Led up to 2 UI engineers and 3 infrastructure engineers while remaining active in system design and implementation", + "Handled releases, production debugging, infrastructure audits, and cost strategy without stepping away from code" ] }, + featured_project_ids: ["affiliate-network-platform", "netadmin-platform"], + project_groups: [ + %{ + id: "tracking-attribution", + title: "Tracking, Attribution & Partner Integrations", + description: + "Supporting services that turned incoming traffic into attributable, reportable partner outcomes.", + icon: "hero-arrows-right-left", + project_ids: [ + "edge-redirect-service", + "conversion-callback-engine", + "tracking-domain-infra" + ] + }, + %{ + id: "analytics-reporting", + title: "Analytics, Reporting & Data Infrastructure", + description: + "The ingestion, storage, aggregation, and reporting systems behind partner analytics and operational visibility.", + icon: "hero-circle-stack", + project_ids: [ + "traffic-analytics-pipeline", + "distributed-data-platform" + ] + } + ], projects: [ %{ id: "affiliate-network-platform", - title: "Affiliate Network Platform", + title: "Affiliate Marketing Platform", tagline: - "Core backend platform powering affiliate campaign tracking, conversion attribution, reporting, and partner integrations", + "Flagship Erlang/OTP platform for click tracking, attribution, reporting, and partner integrations", period_label: "Core Platform", phase: 2, icon: "hero-chart-bar", + featured_label: "Flagship Distributed System", card_copy: - "Revenue-critical Erlang platform handling click tracking, conversion attribution, campaign management, reporting, and partner integrations across millions of daily events.", + "Revenue-critical Erlang/OTP system supporting $2.5M+ monthly revenue and 1.5M+ daily events across click tracking, attribution, campaign logic, reporting, and partner APIs.", summary: - "Core backend platform powering affiliate campaign tracking, conversion attribution, reporting, and partner integrations. Built in Erlang/OTP with Cassandra, Elasticsearch, RabbitMQ, and PostgreSQL as the primary data and messaging layer.", + "The core backend platform I owned for the affiliate business. It handled click, impression, and conversion tracking; attribution; reporting; partner integrations; and the operational workflows that made the platform revenue-critical.", tech_used: [ "Erlang/OTP", + "Cassandra", "PostgreSQL", "RabbitMQ", - "Cassandra", - "Elasticsearch", + "Elasticsearch/OpenSearch", + "REST APIs", "Apache Spark" ], + architecture: [ + "Event-driven Erlang services handled tracking, attribution, routing, and partner workflows", + "Cassandra stored high-volume raw event data and time-series traffic history", + "PostgreSQL supported operational workflows, reporting datasets, and financial views", + "RabbitMQ connected ingestion, callbacks, and downstream processing services", + "Elasticsearch/OpenSearch powered detailed partner reporting and performance analytics", + "Spark pipelines aggregated raw event data into reporting datasets used for analytics and finance" + ], responsibilities: [ - "Click tracking", - "Impression tracking", - "Conversion attribution", - "Affiliate management", - "Advertiser management", - "Campaign configuration and payout rules", - "Reporting and analytics", - "CSV export pipelines", - "Moderation workflows", - "Suppression list management", - "Creative and landing page management", - "External APIs and integrations" + "Owned backend architecture, features, and production operations for the platform", + "Built and maintained click, impression, and conversion tracking paths", + "Implemented attribution, routing, campaign configuration, and payout workflows", + "Designed partner-facing and internal REST APIs plus service integrations", + "Owned data modeling, query tuning, and reporting paths across Cassandra and PostgreSQL" ], scale: [ - "Millions of events processed daily", - "Revenue-critical production system supporting $2.5M+ monthly revenue" + "1.5M+ events processed daily", + "$2.5M+ monthly revenue supported by the platform", + "6-node Cassandra production cluster", + "Real-time partner reporting and high-volume transaction paths" + ], + business_impact: [ + "Served as the primary technical engine behind a long-running affiliate business", + "Demonstrated sustained ownership of a revenue-critical distributed system on the BEAM" ], timeline_order: 1 }, %{ id: "netadmin-platform", - title: "NetAdmin/Infra Platform", + title: "NetAdmin", tagline: - "Internal infrastructure management platform supporting affiliate network, MTA, data verification, and external systems", + "Elixir control plane for lifecycle orchestration, monitoring, log streaming, and operational auditability", period_label: "Internal Tooling", phase: 2, icon: "hero-cog-6-tooth", + featured_label: "Featured Elixir Platform", card_copy: - "Full-stack Elixir/Phoenix/Ash internal platform managing infrastructure provisioning, VPS lifecycle, domain management, and service automation across company systems.", + "Phoenix + LiveView + Ash platform for provisioning, service lifecycle automation, monitoring, auditability, and cross-system operational workflows.", summary: - "Internal infrastructure management platform originally created to manage affiliate network infrastructure and later expanded to support company-wide systems including MTA infrastructure, data verification systems, and external affiliate network platforms. Served as a DevOps dashboard for provisioniong and monitoring all company infrastructure.", + "NetAdmin was the internal infrastructure platform I architected and built in Elixir. It started as a way to manage affiliate platform infrastructure and expanded into a control plane for MTA, verification, and other company systems.", tech_used: [ "Elixir", "Phoenix", @@ -2256,46 +2444,50 @@ defmodule RevstackWeb.WhoamiLive do "Ansible" ], architecture: [ - "Full-stack Elixir application built with Phoenix and Ash Framework", - "PostgreSQL for persistent data storage", - "Ansible integration for infrastructure automation", - "Multi-system management across affiliate network, MTA, data verification, and external platforms", - "Real-time monitoring and dashboards for infrastructure visibility", - "Log streaming and alerting for operational awareness" + "Phoenix + LiveView UI backed by Ash resources and authorization rules", + "PostgreSQL as the system of record for infrastructure state and operational history", + "Ansible integration for provisioning and lifecycle automation", + "Cross-system workflows spanning the affiliate platform, MTA, verification systems, and external platforms", + "Real-time dashboards, operational monitoring, and log visibility for daily operations", + "Operational auditability built into the platform rather than bolted on afterward" ], responsibilities: [ - "Infrastructure provisioning", - "VPS lifecycle management", - "Domain and SSL management", - "Payment method tracking", - "Service lifecycle automation", - "Infrastructure visibility dashboards" + "Resource lifecycle orchestration", + "VPS, service, domain, and SSL management", + "Monitoring dashboards and operational visibility", + "Real-time log streaming and cross-system troubleshooting support", + "Authorization modeling and auditability", + "Automation across multiple internal platforms" + ], + business_impact: [ + "Centralized infrastructure operations that had previously been spread across scripts and tribal knowledge", + "Showcases deep Elixir, Phoenix LiveView, and Ash experience in a production internal platform" ], timeline_order: 2 }, %{ id: "edge-redirect-service", - title: "Edge Redirect Service", + title: "Tracking Edge Service", tagline: - "High-performance edge service handling affiliate tracking links and routing traffic based on campaign rules", + "High-performance Erlang service handling tracking links and routing traffic based on campaign rules", period_label: "Edge Infrastructure", phase: 2, icon: "hero-arrows-right-left", card_copy: - "Erlang edge service on disposable VPS nodes generating real-time redirect responses for affiliate tracking links based on campaign routing rules.", + "Erlang edge service generating real-time redirect decisions for tracking links based on campaign routing, geo rules, and cap logic.", summary: - "High-performance edge service responsible for handling affiliate tracking links and routing traffic based on campaign rules. Deployed on disposable VPS nodes with DNS tracking domains pointed to these nodes.", + "High-performance edge service responsible for handling affiliate tracking links and routing traffic based on campaign rules. It sat close to incoming HTTP traffic and turned campaign configuration into live redirect behavior.", tech_used: [ "Erlang/OTP", - "DNS", "HTTP", + "DNS", "VPS Infrastructure" ], architecture: [ - "Erlang service deployed on disposable VPS nodes", - "DNS tracking domains pointed to these nodes", - "Nodes retrieved campaign configuration from backend services", - "Redirect responses generated in real time" + "Erlang service deployed on tracking edge nodes close to incoming traffic", + "Tracking domains routed HTTP requests into the service", + "Nodes pulled campaign configuration and routing rules from backend systems", + "Redirect responses were generated in real time based on live business logic" ], responsibilities: [ "Campaign routing", @@ -2315,15 +2507,21 @@ defmodule RevstackWeb.WhoamiLive do phase: 2, icon: "hero-circle-stack", card_copy: - "Distributed pipeline ingesting click, impression, and conversion events into Cassandra and Elasticsearch, powering real-time analytics and report aggregation.", + "Distributed ingestion and indexing pipeline feeding partner analytics, reporting, and downstream aggregation from raw traffic events.", summary: - "Distributed event pipeline responsible for ingesting click, impression, and conversion events and powering analytics and reporting across the affiliate network.", + "Distributed event pipeline responsible for ingesting click, impression, and conversion events and turning them into the analytics and reports used throughout the affiliate platform.", tech_used: [ "Cassandra", - "Elasticsearch", "RabbitMQ", + "Elasticsearch/OpenSearch", "Apache Spark" ], + architecture: [ + "RabbitMQ buffered and distributed event work between services", + "Cassandra stored high-volume event data for long-term analysis", + "Search and analytics infrastructure powered detailed reporting views", + "Spark aggregation jobs transformed raw data into reporting-friendly datasets" + ], responsibilities: [ "Event ingestion", "Traffic logging", @@ -2332,8 +2530,8 @@ defmodule RevstackWeb.WhoamiLive do "Export dataset generation" ], scale: [ - "~150\u2013250 peak events per second", - "Multi-terabyte traffic datasets" + "1.5M+ daily events across click, impression, and conversion paths", + "High-volume analytics and reporting workloads running continuously" ], timeline_order: 4 }, @@ -2345,9 +2543,9 @@ defmodule RevstackWeb.WhoamiLive do phase: 2, icon: "hero-paper-airplane", card_copy: - "Reliable server-to-server callback delivery system handling conversion notifications with retry logic, macro substitution, and delivery tracking.", + "Reliable server-to-server callback delivery system with retry logic, macro substitution, delivery tracking, and failure handling.", summary: - "Reliable delivery system for advertiser and affiliate conversion callbacks. Handles server-to-server conversion notifications with retries, macro substitution, and failure tracking.", + "Reliable delivery system for advertiser and affiliate conversion callbacks. It handled server-to-server notifications, retry behavior, macro substitution, and tracking around partner delivery failures.", tech_used: [ "RabbitMQ", "Erlang Worker Pools", @@ -2365,16 +2563,18 @@ defmodule RevstackWeb.WhoamiLive do %{ id: "tracking-domain-infra", title: "Tracking Domain Infrastructure", - tagline: "Infrastructure for managing tracking domains and routing configuration", + tagline: + "Domain, SSL, and routing infrastructure behind tracking links and redirect services", period_label: "Infrastructure", phase: 2, icon: "hero-globe-alt", card_copy: - "Managed tracking domain lifecycle including SSL certificates, DNS routing, and domain rotation experiments to reduce blacklist risk.", + "Managed the lifecycle of tracking domains, SSL certificates, routing configuration, and domain rotation experiments.", summary: - "Infrastructure responsible for managing tracking domains and routing configuration. Handled domain lifecycle, SSL certificates, and DNS routing across the affiliate network.", + "Infrastructure responsible for managing tracking domains and routing configuration. It handled the DNS and SSL layer that allowed tracking services to operate cleanly and evolve over time.", tech_used: [ - "Routing Configuration + DNS", + "DNS", + "HTTP", "SSL/TLS + letsencrypt", "Domain Management" ], @@ -2395,20 +2595,20 @@ defmodule RevstackWeb.WhoamiLive do phase: 2, icon: "hero-server-stack", card_copy: - "Operated a 6-node Cassandra cluster, 3-node Elasticsearch cluster, Spark aggregation jobs, and RabbitMQ pipelines supporting ~600TB of combined data.", + "Operated the core data layer behind the platform, including Cassandra, analytics infrastructure, Spark jobs, and RabbitMQ pipelines.", summary: - "Large-scale data storage and analytics infrastructure supporting event ingestion and reporting across the affiliate network platform.", + "Large-scale data storage and analytics infrastructure supporting event ingestion and reporting across the affiliate platform.", tech_used: [ "Cassandra", - "Elasticsearch", + "Elasticsearch/OpenSearch", "Apache Spark (Scala)", "RabbitMQ" ], architecture: [ "Cassandra cluster (6 nodes) for high-throughput event storage", - "Elasticsearch analytics cluster (3 nodes) for search and reporting", - "Spark aggregation jobs for batch processing", - "Ingested RabbitMQ messages via Erlang worker services for real-time processing" + "Search and analytics infrastructure for detailed reporting", + "Spark aggregation jobs for batch processing and reporting dataset generation", + "RabbitMQ-fed services for near-real-time downstream processing" ], responsibilities: [ "High-throughput event ingestion", @@ -2417,10 +2617,8 @@ defmodule RevstackWeb.WhoamiLive do "Reporting aggregation" ], scale: [ - "~600TB Cassandra data footprint", - "~600TB Elasticsearch analytics dataset", "6-node Cassandra production cluster", - "3-node Elasticsearch cluster" + "Large reporting and analytics workloads across raw and aggregated event data" ], timeline_order: 7 } @@ -2439,6 +2637,7 @@ defmodule RevstackWeb.WhoamiLive do "Postgres", "RabbitMQ", "Elasticsearch", + "Elasticsearch/OpenSearch", "OpenSearch", "Apache Spark", "AWS", diff --git a/test/revstack_web/layouts_user_menu_test.exs b/test/revstack_web/layouts_user_menu_test.exs index 63afa1c..79d8070 100644 --- a/test/revstack_web/layouts_user_menu_test.exs +++ b/test/revstack_web/layouts_user_menu_test.exs @@ -35,6 +35,6 @@ defmodule RevstackWeb.LayoutsUserMenuTest do test "whoami page includes the admin panel project card", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/whoami") - assert has_element?(view, "button#project-admin", "Admin Dashboard (for this site!)") + assert has_element?(view, "button#project-admin", "Revstack Admin Dashboard") end end diff --git a/test/revstack_web/whoami_live_career_modal_test.exs b/test/revstack_web/whoami_live_career_modal_test.exs index dc71647..3843052 100644 --- a/test/revstack_web/whoami_live_career_modal_test.exs +++ b/test/revstack_web/whoami_live_career_modal_test.exs @@ -41,6 +41,34 @@ defmodule RevstackWeb.WhoamiLiveCareerModalTest do assert has_element?(view, "button[phx-click='open_career_modal']") end + test "phase two highlights flagship systems and groups supporting systems beneath them", %{ + conn: conn + } do + {:ok, view, _html} = live(conn, ~p"/") + + view + |> element("button[phx-click='expand_career_phase'][phx-value-phase-id='phase-2']") + |> render_click() + + assert has_element?(view, "#career-featured-phase-2") + + assert has_element?( + view, + "#career-project-card-affiliate-network-platform", + "Affiliate Marketing Platform" + ) + + assert has_element?(view, "#career-project-card-netadmin-platform", "NetAdmin") + assert has_element?(view, "#career-group-tracking-attribution") + assert has_element?(view, "#career-group-analytics-reporting") + + assert has_element?( + view, + "#career-project-list-edge-redirect-service", + "Tracking Edge Service" + ) + end + test "collapsing a phase hides project cards", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/") @@ -80,6 +108,21 @@ defmodule RevstackWeb.WhoamiLiveCareerModalTest do assert has_element?(view, "#career-portfolio-modal") end + test "featured affiliate platform card opens the modal from phase two", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/") + + view + |> element("button[phx-click='expand_career_phase'][phx-value-phase-id='phase-2']") + |> render_click() + + view + |> element("#career-project-card-affiliate-network-platform") + |> render_click() + + assert has_element?(view, "#career-portfolio-modal") + assert has_element?(view, "h4", "Affiliate Marketing Platform") + end + test "modal has phx-hook LockBodyScroll for scroll locking", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/") diff --git a/test/revstack_web/whoami_live_layout_test.exs b/test/revstack_web/whoami_live_layout_test.exs index 58466f5..9e240f2 100644 --- a/test/revstack_web/whoami_live_layout_test.exs +++ b/test/revstack_web/whoami_live_layout_test.exs @@ -24,8 +24,17 @@ defmodule RevstackWeb.WhoamiLiveLayoutTest do test "renders role title and skill signature", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/") - assert has_element?(view, "#whoami-role-title") - assert has_element?(view, "#whoami-skill-signature") + assert has_element?(view, "#whoami-role-title", "Lead Distributed Systems Engineer") + assert has_element?(view, "#whoami-skill-signature", "1.5M+ events/day") + end + + test "at a glance surfaces recruiter-facing scale metrics", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/") + + assert has_element?(view, "#whoami-glance", "6-node") + assert has_element?(view, "#whoami-glance", "Cassandra event store") + assert has_element?(view, "#whoami-glance", "~25%") + assert has_element?(view, "#whoami-glance", "audits and scaling changes") end end @@ -46,8 +55,8 @@ defmodule RevstackWeb.WhoamiLiveLayoutTest do test "renders leadership items within the combined section", %{conn: conn} do {:ok, _view, html} = live(conn, ~p"/") - assert html =~ "Architecture ownership" - assert html =~ "Scaled platforms" + assert html =~ "Long-term ownership of revenue-critical backend platforms" + assert html =~ "Reduced infrastructure operating costs by ~25%" assert html =~ "leadership-teamwork" end end diff --git a/test/revstack_web/whoami_live_projects_test.exs b/test/revstack_web/whoami_live_projects_test.exs index a59f5b0..4b8ca9a 100644 --- a/test/revstack_web/whoami_live_projects_test.exs +++ b/test/revstack_web/whoami_live_projects_test.exs @@ -82,14 +82,23 @@ defmodule RevstackWeb.WhoamiLiveProjectsTest do html = render(view) - assert html =~ "5 backend" - assert html =~ "3 DevOps engineers" - assert html =~ "sole owner" - assert html =~ "self-managed unit" + assert html =~ "long-term owner of backend architecture" + assert html =~ "CTO on business rules" + assert html =~ "3 infrastructure engineers" + assert html =~ "~25%" end end describe "professional experience emphasis" do + test "renders Ionik experience with resume-aligned scale and NetAdmin language", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/whoami") + + assert has_element?(view, "#experience-ionik", "Ionik (formerly VeriAS)") + assert has_element?(view, "#experience-ionik li", "$2.5M+ monthly revenue") + assert has_element?(view, "#experience-ionik li", "1.5M+ events daily") + assert has_element?(view, "#experience-ionik li", "NetAdmin") + end + test "renders the demand outcome sentence in bold", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/whoami") @@ -107,14 +116,14 @@ defmodule RevstackWeb.WhoamiLiveProjectsTest do assert has_element?( view, - "li", - "the system included SEO-driven service pages, conversion-focused design" + "#experience-revenuelink li", + "SEO-driven service pages, a quote workflow with photo uploads" ) assert has_element?( view, - "li", - "Built with Elixir, Phoenix LiveView, and Ecto" + "#experience-revenuelink li", + "consulting, hands-on product work" ) end end From 37ef2488b419c889bf1b52be78bfc8757e5f3f7b Mon Sep 17 00:00:00 2001 From: Kyle Neal Date: Thu, 19 Mar 2026 13:14:43 -0500 Subject: [PATCH 3/4] updates iteration --- lib/revstack_web/live/whoami_live.ex | 519 ++++++++++-------- test/revstack_web/whoami_live_layout_test.exs | 12 +- .../whoami_live_projects_test.exs | 57 +- 3 files changed, 347 insertions(+), 241 deletions(-) diff --git a/lib/revstack_web/live/whoami_live.ex b/lib/revstack_web/live/whoami_live.ex index 753d5ec..882eb42 100644 --- a/lib/revstack_web/live/whoami_live.ex +++ b/lib/revstack_web/live/whoami_live.ex @@ -48,12 +48,10 @@ defmodule RevstackWeb.WhoamiLive do @section_navigation_items [ %{id: "whoami-hero", label: "Hero"}, - %{id: "whoami-glance", label: "At A Glance"}, - %{id: "whoami-summary", label: "Professional Summary"}, - %{id: "whoami-expertise", label: "Technical Expertise"}, %{id: "whoami-experience", label: "Professional Experience"}, %{id: "whoami-portfolio", label: "Career Portfolio"}, - %{id: "live-projects", label: "Personal Live Projects"}, + %{id: "whoami-expertise", label: "Technical Expertise"}, + %{id: "live-projects", label: "Independent Product Work"}, %{id: "leadership-teamwork", label: "Leadership & Teamwork"}, %{id: "whoami-education", label: "Education"}, %{id: "whoami-interests", label: "When I'm Not Coding"}, @@ -77,6 +75,7 @@ defmodule RevstackWeb.WhoamiLive do career_modal_open?: false, career_selected_project_id: nil, career_detail_view?: false, + experience_expanded_id: nil, career_expanded_phase_id: nil, career_phases: [career_portfolio_phase_two(), career_portfolio_phase_one()] ) @@ -124,6 +123,17 @@ defmodule RevstackWeb.WhoamiLive do {:noreply, assign(socket, career_expanded_phase_id: nil)} end + def handle_event("toggle_experience", %{"id" => experience_id}, socket) do + next_id = + if socket.assigns.experience_expanded_id == experience_id do + nil + else + experience_id + end + + {:noreply, assign(socket, :experience_expanded_id, next_id)} + end + def handle_event("open_career_modal", %{"project-id" => project_id}, socket) do {:noreply, assign(socket, @@ -171,14 +181,12 @@ defmodule RevstackWeb.WhoamiLive do />
    <.hero_section /> - <.at_a_glance_section /> - <.professional_summary_section /> - <.technical_expertise_section /> - <.professional_experience_section /> + <.professional_experience_section experience_expanded_id={@experience_expanded_id} /> <.career_portfolio_section career_phases={@career_phases} expanded_phase_id={@career_expanded_phase_id} /> + <.technical_expertise_section /> <.live_projects_section admin_gallery_images={@admin_gallery_images} /> <.leadership_and_teamwork_section /> <.education_section /> @@ -207,166 +215,142 @@ defmodule RevstackWeb.WhoamiLive do defp hero_section(assigns) do ~H""" -
    -
    -
    - <.icon name="hero-cpu-chip" class="size-4" /> Distributed Systems Engineer -
    -

    - Kyle Neal -

    -

    - Lead Distributed Systems Engineer -

    -

    - Erlang/OTP and Elixir engineer building revenue-critical systems on the BEAM. - I've owned affiliate tracking, attribution, reporting, and infrastructure platforms - supporting 1.5M+ events/day, $2.5M+ monthly revenue, and hands-on leadership of up to 5 engineers. -

    -
    - - <.link - navigate={~p"/contact"} - id="hero-contact-link" - class="btn btn-primary btn-md sm:btn-lg gap-2 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-0.5 w-full sm:w-auto max-w-xs" - > - <.icon name="hero-envelope" class="size-5" /> Contact Me - -
    - <%!-- Quick links --%> -
    -
    - +
    +
    +
    +

    + Erlang/OTP + Elixir • Revenue-Critical Platforms • Hands-On Technical Leadership +

    +

    - - GitHub - - +

    + I build and operate high-throughput BEAM systems that directly support revenue. +

    +

    - <.icon name="hero-envelope" class="size-4" /> nealkyle5@gmail.com - + My core story is long-term ownership of an Erlang/OTP affiliate platform handling + click tracking, attribution, partner callbacks, analytics, and reporting at + 1.5M+ events/day + and $2.5M+ monthly revenue. + I also architected NetAdmin, a major Elixir/Phoenix LiveView + Ash platform for + orchestration, monitoring, auditability, and automation. +

    + +
    +

    + Best fit roles +

    +
    + <.signal_chip label="Lead Distributed Systems Engineer" /> + <.signal_chip label="Senior Erlang / Elixir Engineer" /> + <.signal_chip label="Staff Backend Engineer" /> + <.signal_chip label="Platform / Infrastructure Engineer" /> + <.signal_chip label="Technical Lead Who Still Codes" /> +
    +
    + +
    +
    + <.proof_point_chip value="1.5M+" label="events/day processed by systems I've built" /> + <.proof_point_chip value="$2.5M+" label="monthly revenue supported on systems I've built" /> + <.proof_point_chip value="~25%" label="infrastructure cost reduction achieved as a result of workflow improvements by systems I've built" /> + <.proof_point_chip value="5" label="engineers led hands-on" /> +
    +
    + +
    +
    + <.link + navigate={~p"/contact"} + id="hero-contact-link" + class="btn btn-primary btn-md sm:btn-lg gap-2 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-0.5" + > + <.icon name="hero-envelope" class="size-5" /> Contact Me + + + <.icon name="hero-eye" class="size-5" /> View Resume + + + <.icon name="hero-arrow-down-tray" class="size-5" /> + +
    + + +

    -
    -
    -
    - """ - end - defp at_a_glance_section(assigns) do - ~H""" -
    -
    -
    - <.stat_card - value="10+" - headline="Years building on the BEAM" - detail="Erlang/OTP + Elixir in production" - /> - <.stat_card - value="1.5M+" - headline="Events processed per day" - detail="tracking, attribution, and reporting workloads" - /> - <.stat_card - value="$2.5M+" - headline="Monthly revenue supported" - detail="revenue-critical platform ownership" - /> - <.stat_card - value="6-node" - headline="Cassandra event store" - detail="operated in production for high-volume tracking data" - /> - <.stat_card - value="~25%" - headline="Infrastructure cost reduction" - detail="delivered through audits and scaling changes" - /> - <.stat_card - value="5" - headline="Engineers led hands-on" - detail="across UI and infrastructure" - /> -
    -
    -
    - """ - end +
    +
    +
    +

    + Why I stand out +

    +

    + The first-glance version before you dive into the deeper project and system detail. +

    +
    - defp professional_summary_section(assigns) do - ~H""" -
    -
    -
    -

    Professional Summary

    -
    -
    -
    - <.summary_item - icon="hero-cpu-chip" - text="Lead distributed systems engineer specializing in long-lived production systems built with Erlang/OTP and Elixir" - /> - <.summary_item - icon="hero-server-stack" - text="Built and operated a revenue-critical affiliate platform handling high-volume click tracking, attribution, callbacks, analytics, and partner reporting" - /> - <.summary_item - icon="hero-cog-6-tooth" - text="Architected NetAdmin, an Elixir/Phoenix LiveView + Ash control plane for lifecycle orchestration, monitoring, auditability, and automation" - /> - <.summary_item - icon="hero-circle-stack" - text="Designs distributed data and messaging systems across Cassandra, PostgreSQL, RabbitMQ, Elasticsearch/OpenSearch, and Spark pipelines" - /> - <.summary_item - icon="hero-globe-alt" - text="Comfortable close to the wire with HTTP, WebSockets, DNS, SMTP, and proxying in production systems" - /> - <.summary_item - icon="hero-bolt" - text="Reliability-focused owner of OTP supervision, BEAM tuning, relup upgrades, CI/CD, and production incident debugging" - /> - <.summary_item - icon="hero-user-group" - text="Hands-on technical lead who hired, mentored, and managed up to 5 engineers without stepping away from architecture or code" - /> - <.summary_item - icon="hero-cloud" - text="Infrastructure-aware across AWS, Linux, VPS fleets, Jenkins, and Ansible, with a practical cost and operability mindset" - /> + <.hero_spotlight_card + eyebrow="Primary Story" + title="Affiliate platform ownership" + description="Long-term owner of a revenue-critical Erlang/OTP platform spanning tracking, attribution, callbacks, partner reporting, distributed messaging, Cassandra-backed event storage, and production reliability." + /> + + <.hero_spotlight_card + eyebrow="Elixir Signal" + title="NetAdmin" + description="Architected a Phoenix LiveView + Ash control plane for lifecycle orchestration, monitoring, log visibility, audit trails, and operational automation across internal systems." + /> + + <.hero_spotlight_card + eyebrow="Leadership Style" + title="Hands-on technical leadership" + description="Led up to 5 engineers, handled technical interviews and hiring, and stayed directly responsible for architecture, code, escalations, and infrastructure decisions." + /> +
    +
    @@ -434,14 +418,27 @@ defmodule RevstackWeb.WhoamiLive do

    Professional Experience

    +

    + Condensed on the surface for fast scanning. Open a role for the deeper architecture, + systems, and delivery detail. +

    -
    +
    <.experience_card id="experience-ionik" title="Lead Distributed Systems Engineer" company="Ionik (formerly VeriAS)" period="October 2014 — Present" current?={true} + expanded?={@experience_expanded_id == "experience-ionik"} + summary="Long-term owner of a revenue-critical Erlang/OTP affiliate platform covering click tracking, attribution, callbacks, partner reporting, distributed data architecture, and production reliability. NetAdmin, the internal Elixir platform I architected, sits alongside that work as the strongest Elixir proof point on the page." + surface_points={[ + "1.5M+ events/day", + "$2.5M+ monthly revenue", + "6-node Cassandra event store", + "~25% infra cost reduction", + "Led up to 5 engineers" + ]} items={[ "Lead architect and primary backend engineer for a revenue-critical affiliate marketing platform using Erlang/OTP. The platform supports $2.5M+ monthly revenue, processes 1.5M+ events daily, and powers high-volume click tracking, attribution, and real-time partner reporting.", "Owned backend platform design across tracking, analytics, and partner connectivity, including REST APIs and internal service integrations used throughout the product.", @@ -460,6 +457,14 @@ defmodule RevstackWeb.WhoamiLive do company="RevenueLink Technologies LLC" period="2023 — Present" current?={true} + expanded?={@experience_expanded_id == "experience-revenuelink"} + summary="Independent consulting and product vehicle for real deployed work, including business-facing lead-generation systems, recruiter-facing software, and small Elixir experiments with full delivery ownership." + surface_points={[ + "Phoenix LiveView product work", + "Real business demand", + "Lead-gen + admin workflows" + ]} + impact_note="Hardcore Handyman generated more inbound demand than the business could operationally support." items={[ "Founded a consulting and software vehicle for independent projects, select consulting engagements, and Elixir/Phoenix experiments.", {:parts, @@ -481,26 +486,27 @@ defmodule RevstackWeb.WhoamiLive do "Use the company as a vehicle for consulting, hands-on product work, and experimentation with Elixir, infrastructure tooling, and small SaaS-style projects." ]} /> - <.experience_card - title="Application Programmer" - company="CGI Federal" - period="December 2013 — October 2014" - current?={false} - items={[ - "Performed detailed source code analysis for enterprise Java/ADA systems.", - "Developed tooling and assisted with build/release workflows for multi-million SLOC applications.", - "Created smoke and sanity testing processes supporting production releases." - ]} - /> - <.experience_card - title="In-House Technician" - company="Wichita Online" - period="April 2013 — December 2013" - current?={false} - items={[ - "Provided in-field network troubleshooting and wireless equipment deployment (MikroTik, Canopy routers)." - ]} - /> +
    +

    + Earlier experience +

    +
    + <.compact_experience_card + id="experience-cgi" + title="Application Programmer" + company="CGI Federal" + period="December 2013 — October 2014" + summary="Performed source analysis and release-support tooling work for large enterprise Java and ADA systems." + /> + <.compact_experience_card + id="experience-wichita" + title="In-House Technician" + company="Wichita Online" + period="April 2013 — December 2013" + summary="Handled in-field network troubleshooting and wireless equipment deployment for ISP operations." + /> +
    +
    @@ -518,9 +524,9 @@ defmodule RevstackWeb.WhoamiLive do

    Career Portfolio

    - The affiliate platform is the centerpiece of my career story, and NetAdmin is the major - Elixir platform I built alongside it. Supporting systems are grouped the way they were - actually owned in production.
    + The affiliate platform is the flagship system, and NetAdmin is the strongest Elixir + platform built alongside it. Supporting systems are grouped the way they were actually + owned in production.
    <.icon name="hero-cursor-arrow-rays" class="size-7 inline-block align-text-bottom" @@ -545,14 +551,12 @@ defmodule RevstackWeb.WhoamiLive do

    - <%!--
    - <.icon name="hero-rocket-launch" class="size-4" /> Live & Deployed -
    --%> -

    Personal Live Projects

    +

    Independent Product Work

    - Recent side projects and deployed experiments outside the affiliate platform and NetAdmin work. -
    + Deployed work outside the affiliate platform and NetAdmin. Hardcore Handyman is the + clearest business signal here: the platform generated more inbound demand than the + business could operationally support.
    <.icon name="hero-cursor-arrow-rays" class="size-5 inline-block align-text-bottom" @@ -564,7 +568,7 @@ defmodule RevstackWeb.WhoamiLive do <.project_card id="project-handyman" title="Hardcore Handyman" - subtitle="Phoenix LiveView lead-generation system with quote requests, photo uploads, SEO-driven service pages, and an admin workflow that generated more demand than the business could operationally support." + subtitle="Phoenix LiveView lead-generation platform that generated more inbound demand than the business could operationally support, backed by quote requests, photo uploads, SEO-driven pages, and an admin workflow." href="https://hardcorehandyman.fly.dev/" icon="hero-wrench-screwdriver" preview_src={~p"/images/hardcorehandyman_preview.png"} @@ -583,7 +587,7 @@ defmodule RevstackWeb.WhoamiLive do <.project_card id="project-revenuelink" title="RevenueLink" - subtitle="Consulting and business site for RevenueLink Technologies, used as a public home for services, projects, and lightweight product experiments." + subtitle="Public home for RevenueLink Technologies, used to ship business-facing services, deployed software, and lightweight product experiments with real delivery ownership." href="https://revenuelink.net/" icon="hero-building-office-2" preview_src={~p"/images/revenuelink_preview.png"} @@ -1143,32 +1147,29 @@ defmodule RevstackWeb.WhoamiLive do """ end - defp stat_card(assigns) do - assigns = - assigns - |> assign(:headline, Map.get(assigns, :headline, Map.get(assigns, :label))) - |> assign_new(:detail, fn -> nil end) + defp proof_point_chip(assigns) do + ~H""" + + {@value} + {@label} + + """ + end + defp signal_chip(assigns) do ~H""" -

    -

    {@value}

    -

    - {@headline} -

    -

    - {@detail} -

    -
    + + {@label} + """ end - defp summary_item(assigns) do + defp hero_spotlight_card(assigns) do ~H""" -
    -
    - <.icon name={@icon} class="size-4" /> -
    -

    {@text}

    +
    +

    {@eyebrow}

    +

    {@title}

    +

    {@description}

    """ end @@ -1188,12 +1189,24 @@ defmodule RevstackWeb.WhoamiLive do end defp experience_card(assigns) do - assigns = assign_new(assigns, :id, fn -> nil end) + assigns = + assigns + |> assign_new(:id, fn -> nil end) + |> assign_new(:summary, fn -> nil end) + |> assign_new(:surface_points, fn -> [] end) + |> assign_new(:impact_note, fn -> nil end) + |> assign_new(:expanded?, fn -> false end) ~H"""
    @@ -1210,15 +1223,51 @@ defmodule RevstackWeb.WhoamiLive do
    -
      -
    • - <.icon name="hero-chevron-right" class="size-4 text-primary shrink-0 mt-0.5" /> - <.experience_item item={item} /> -
    • -
    + +

    {@summary}

    + +
    + <.signal_chip :for={point <- @surface_points} label={point} /> +
    + +
    +
    + <.icon name="hero-megaphone" class="size-4 shrink-0 mt-0.5 text-primary" /> + {@impact_note} +
    +
    + + + +
    +
      +
    • + <.icon name="hero-chevron-right" class="size-4 text-primary shrink-0 mt-0.5" /> + <.experience_item item={item} /> +
    • +
    +
    """ end @@ -1253,6 +1302,24 @@ defmodule RevstackWeb.WhoamiLive do """ end + defp compact_experience_card(assigns) do + ~H""" +
    +
    +
    +

    {@title}

    +

    {@company}

    +
    +

    {@period}

    +
    +

    {@summary}

    +
    + """ + end + defp education_card(assigns) do ~H"""
    diff --git a/test/revstack_web/whoami_live_layout_test.exs b/test/revstack_web/whoami_live_layout_test.exs index 9e240f2..6664dc7 100644 --- a/test/revstack_web/whoami_live_layout_test.exs +++ b/test/revstack_web/whoami_live_layout_test.exs @@ -28,13 +28,15 @@ defmodule RevstackWeb.WhoamiLiveLayoutTest do assert has_element?(view, "#whoami-skill-signature", "1.5M+ events/day") end - test "at a glance surfaces recruiter-facing scale metrics", %{conn: conn} do + test "hero surfaces recruiter-facing fit and proof points without a stat grid", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/") - assert has_element?(view, "#whoami-glance", "6-node") - assert has_element?(view, "#whoami-glance", "Cassandra event store") - assert has_element?(view, "#whoami-glance", "~25%") - assert has_element?(view, "#whoami-glance", "audits and scaling changes") + assert has_element?(view, "#whoami-role-fit", "Staff Backend Engineer") + assert has_element?(view, "#whoami-role-fit", "Technical Lead Who Still Codes") + assert has_element?(view, "#whoami-proof-points", "6-node") + assert has_element?(view, "#whoami-proof-points", "Cassandra event store") + assert has_element?(view, "#whoami-proof-points", "~25%") + assert has_element?(view, "#whoami-proof-points", "infra cost reduction") end end diff --git a/test/revstack_web/whoami_live_projects_test.exs b/test/revstack_web/whoami_live_projects_test.exs index 4b8ca9a..877c04f 100644 --- a/test/revstack_web/whoami_live_projects_test.exs +++ b/test/revstack_web/whoami_live_projects_test.exs @@ -90,39 +90,76 @@ defmodule RevstackWeb.WhoamiLiveProjectsTest do end describe "professional experience emphasis" do - test "renders Ionik experience with resume-aligned scale and NetAdmin language", %{conn: conn} do + test "keeps Ionik concise on the surface with recruiter-facing proof points", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/whoami") assert has_element?(view, "#experience-ionik", "Ionik (formerly VeriAS)") - assert has_element?(view, "#experience-ionik li", "$2.5M+ monthly revenue") - assert has_element?(view, "#experience-ionik li", "1.5M+ events daily") - assert has_element?(view, "#experience-ionik li", "NetAdmin") + assert has_element?(view, "#experience-ionik", "NetAdmin") + assert has_element?(view, "#experience-ionik", "$2.5M+ monthly revenue") + assert has_element?(view, "#experience-ionik", "6-node Cassandra event store") + + assert has_element?( + view, + "#experience-ionik-toggle[aria-expanded='false']", + "Show full scope" + ) + + refute has_element?(view, "#experience-ionik-details") + end + + test "expands Ionik experience details on click", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/whoami") + + view + |> element("#experience-ionik-toggle") + |> render_click() + + assert has_element?( + view, + "#experience-ionik-toggle[aria-expanded='true']", + "Hide full scope" + ) + + assert has_element?(view, "#experience-ionik-details li", "1.5M+ events daily") + assert has_element?(view, "#experience-ionik-details li", "NetAdmin") + + view + |> element("#experience-ionik-toggle") + |> render_click() + + refute has_element?(view, "#experience-ionik-details") end - test "renders the demand outcome sentence in bold", %{conn: conn} do + test "surfaces the handyman demand outcome before founder details are expanded", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/whoami") assert has_element?( view, - "strong.experience-emphasis", - "The platform ultimately generated more inbound demand than the business could operationally support." + "#experience-revenuelink strong.experience-emphasis", + "Hardcore Handyman generated more inbound demand than the business could operationally support." ) + + refute has_element?(view, "#experience-revenuelink-details") end - test "renders handyman SEO and implementation details in founder experience", %{ + test "renders handyman SEO and implementation details after founder card expansion", %{ conn: conn } do {:ok, view, _html} = live(conn, ~p"/whoami") + view + |> element("#experience-revenuelink-toggle") + |> render_click() + assert has_element?( view, - "#experience-revenuelink li", + "#experience-revenuelink-details li", "SEO-driven service pages, a quote workflow with photo uploads" ) assert has_element?( view, - "#experience-revenuelink li", + "#experience-revenuelink-details li", "consulting, hands-on product work" ) end From 53f793cddbb22f2a92d56b7aaec8802b6bda9474 Mon Sep 17 00:00:00 2001 From: Kyle Neal Date: Thu, 19 Mar 2026 13:23:06 -0500 Subject: [PATCH 4/4] more wording updates --- lib/revstack_web/live/whoami_live.ex | 10 ++++++++-- test/revstack_web/whoami_live_layout_test.exs | 17 ++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/revstack_web/live/whoami_live.ex b/lib/revstack_web/live/whoami_live.ex index 882eb42..294db62 100644 --- a/lib/revstack_web/live/whoami_live.ex +++ b/lib/revstack_web/live/whoami_live.ex @@ -259,8 +259,14 @@ defmodule RevstackWeb.WhoamiLive do
    <.proof_point_chip value="1.5M+" label="events/day processed by systems I've built" /> - <.proof_point_chip value="$2.5M+" label="monthly revenue supported on systems I've built" /> - <.proof_point_chip value="~25%" label="infrastructure cost reduction achieved as a result of workflow improvements by systems I've built" /> + <.proof_point_chip + value="$2.5M+" + label="monthly revenue supported on systems I've built" + /> + <.proof_point_chip + value="~25%" + label="infrastructure cost reduction through workflow and scaling improvements" + /> <.proof_point_chip value="5" label="engineers led hands-on" />
    diff --git a/test/revstack_web/whoami_live_layout_test.exs b/test/revstack_web/whoami_live_layout_test.exs index 6664dc7..0d58d69 100644 --- a/test/revstack_web/whoami_live_layout_test.exs +++ b/test/revstack_web/whoami_live_layout_test.exs @@ -33,10 +33,21 @@ defmodule RevstackWeb.WhoamiLiveLayoutTest do assert has_element?(view, "#whoami-role-fit", "Staff Backend Engineer") assert has_element?(view, "#whoami-role-fit", "Technical Lead Who Still Codes") - assert has_element?(view, "#whoami-proof-points", "6-node") - assert has_element?(view, "#whoami-proof-points", "Cassandra event store") + assert has_element?(view, "#whoami-proof-points", "1.5M+") + + assert has_element?( + view, + "#whoami-proof-points", + "events/day processed by systems I've built" + ) + assert has_element?(view, "#whoami-proof-points", "~25%") - assert has_element?(view, "#whoami-proof-points", "infra cost reduction") + + assert has_element?( + view, + "#whoami-proof-points", + "infrastructure cost reduction through workflow and scaling improvements" + ) end end