And of the people is he who sells himself, seeking means to the approval of Allāh. And Allāh is Kind to [His] servants. Al-Baqarah 2:207

← Back to projects

Whippy

Senior Elixir software engineer

Introduction

Hello — I have been a programmer for the past 10 years in Elixir, Ruby on Rails, and Node.js, with an appetite to learn and try new things; I mostly learned through R&D. I love to contribute to open source and tend to dive into strange, complicated problems. I still have plenty to learn, but I ship answers in production.

About the company

Whippy builds conversational engagement tooling and ATS integrations for staffing teams. The integration surface spans onboarding, credential validation, sync orchestration, role/access controls, reporting migration, and operational alerting.

My role

I built the Bullhorn integration from scratch and do most of the ATS sync work across Bullhorn, TempWorks, Avionte and Aqore, plus forms, custom roles and reporting. Since April 2025 that is 1,100+ commits and 200+ merged pull requests.

  • Built the Bullhorn ATS integration in the Sync service from scratch: login through a proxy or directly against Bullhorn (with a fresh login when a stored token is rejected), stepped self onboarding, and a full sync that starts when onboarding completes.
  • Split the sync into separate Oban lanes: a 15 minute tip lane for recent changes, page range backfills that claim their range before fetching it, a last N days window, and two push lanes into Whippy. Every queue limit is per integration, so one big customer cannot starve the others.
  • Replaced a hardcoded object list from the first customer with live Bullhorn metadata read at runtime (cached for 24 hours), so each customer syncs its own standard and custom objects.
  • Worked within Bullhorn's limits (100k calls a month, 1,500 requests a minute, 50 sessions): trimmed candidate pulls from 244 fields to 85, so 500 rows come back in about 6 seconds instead of 42 seconds per 100, and split tip pulls into an ID scan plus parallel fetches of 100 records.
  • Found and fixed silent data loss: Bullhorn caps pages that include one to many fields at 200 rows, which skipped 300 of every 500. Also fixed short pages ending backfills early and progress cursors saved from the wrong point.
  • Stopped Whippy rate limit (429) responses being stored as permanent errors, which had kept 400k+ contacts from syncing, and added Postgres indexes that took the tip query from 1,037 ms to 2.4 ms.
  • Made the sync safe under concurrency: row locks on settings updates, a Postgres advisory lock for gap recovery, claim before write for Bullhorn Notes, and config version checks so edits after onboarding only apply when nothing changed underneath them.
  • Hash based change detection so only changed records are pushed again, cleanup for merged and deleted Bullhorn records, texts logged back to Bullhorn as Notes, and a job that restarts any dead push chain every minute.
  • Cut per record cost in the custom data push path: key normalization in one pass instead of seven regex passes, and records sanitized once instead of twice.
  • Built self-serve onboarding flows for staffing integrations (notably TempWorks, with Avionte/Aqore patterns): stepped forms, validation, config-to-auth/settings transforms, and connection-test APIs so customers can verify credentials before go-live.
  • Implemented onboarding completion that persists typed integration settings, triggers full-sync orchestration, and exposes step/status APIs consumed by the product (including dashboard-v2 proxy patterns).
  • Shipped per-integration custom object controls (toggles, settings embeds, enqueue paths) so background sync runs only for customer-selected entity types across TempWorks/Avionte/Aqore.
  • Extended TempWorks sync coverage with interest codes, richer contact profile fields (communication + birthday-related data), and call/communication modelling with configurable outbound activity labeling.
  • Delivered last-message activity sync from TempWorks into Whippy with scheduled pulls, range-based jobs, and before-activity jobs to power recruiter engagement signals in-product.
  • Added onboarding-level data retention and archiving policy configuration (custom data archiving policies) across multiple ATS integrations, aligned with sync and dashboard behaviour.
  • Introduced custom roles and invite-time role assignment (schema, APIs, registration/acceptance paths) so orgs can provision access before first login.
  • Shipped assign-roles APIs with OpenAPI coverage and expanded audit logging for role-change actions.
  • Led migration of usage and campaign reporting from legacy message records to a unified messages model across reports and background workers.
  • Built cross-system reporting comparison and billing-oriented usage comparison (automated runs, Slack delivery, S3 artifacts) to validate and operationalise the new reporting path.
  • Wired operational notifications (Slack) for integration sync-failure workflows across TempWorks, Avionte, and Crelate so teams get fast signal when integrations break.
  • Built the core domain for Whippy’s Forms Builder, including the lifecycle for form creation, updates, versioning, and publishing behavior.
  • Shipped public-facing Forms APIs (public listing and public show) to support externally accessible form discovery and rendering.
  • Designed and delivered form response capabilities end-to-end, including submission processing, response retrieval APIs, and response filtering workflows.
  • Implemented form-response-to-conversation integration by turning submissions into inbound messages, enabling response activity to flow directly into customer communication timelines.
  • Added form submission notification workflows with formatted email/SMS response outputs, including richer rendering for rating/star and signature-type fields.
  • Built cross-organization form reuse by implementing copy/clone capabilities for forms across organizations.
  • Delivered form URL/link management features (environment/domain-aware URL resolution and stable ID-based URL strategy) to improve portability and consistency of form links.
  • Added campaign/contact-aware filtering for form responses, improving reporting and operational workflows for teams using forms at scale.
  • Introduced protective controls for form attachment upload paths (rate-limiting and validation flow hardening) to support safer high-volume usage.
  • Expanded Forms API quality and adoption readiness through strong docs/typespec coverage and public API alignment for downstream consumers.

Technologies

ElixirPhoenixBullhornTempWorksAvionteAqoreObanOpenAPI