Portfolio
Production workflows, automations, and reporting systems rebuilt here in public form without private company details.
Customer Lifecycle Followup System Multi-month consolidation of followup scripts into a shared SQLite-backed workflow system. Python SQL SQLite APIs
Description
A consolidated workflow system to track and manage customer followups across multiple lifecycle stages. It brought several earlier scripts into one centralized project, giving each workflow shared tracking, clearer ownership, and visibility into related customer activity.
Scale
This was a multi-month project that cleaned up, adapted, and connected many existing scripts into a shared system with local state, scheduled jobs, and cross-workflow rules.
Initial Problem
Followups were spread across disconnected scripts, support tickets, and spreadsheets. That made it hard to see whether a customer had already received outreach from another workflow, and easy to create duplicate tickets at different points in the lifecycle. The separate scripts were also harder to maintain as the process grew.
What Was Built
A shared Python workflow system with local status tracking, scheduled jobs, customer-state rules, ticket creation, email steps, and Slack alerts. The system keeps separate followup paths aware of each other so higher-priority customer activity can suppress lower-priority outreach, using shared status tables and priority rules to avoid duplicate tickets, repeated calls, and overlapping workflows.
Workflow Pieces
Tradeshow Customer Outreach
Imports leads met at tradeshows, prepares email lists, and creates call tickets for eligible leads.
Early-Life Assistance
Tracks new account registrations, no-order customers, and incomplete orders so Customer Service can assist before a customer's first completed order. Accounts in this stage are treated as potential customers.
Sample Pack Workflow
Coordinates welcome emails, sample pack shipping status emails, and followup ticket generation for Customer Service to walk the customer through the sample pack and available products.
First-Order Process
Posts a Slack alert when a customer places their first qualifying order. This allows the team to reach out and provide a personal touch, and to help ensure the customer has a smooth first experience. These customers are considered high-priority and suppress other outreach in the early-life and sample pack stages.
Customer Health Followups
Categorizes customers as Active, Needs Attention, or Inactive based on their order history. It creates tickets for Customer Service to reach out to customers in the Needs Attention and Inactive categories, while suppressing other outreach for customers in the Active category.
Impact
Gave Customer Service clearer followup ownership, reduced duplicate outreach, and made separate customer lifecycle workflows visible to each other.
Tools
Python, SQL, SQLite, cron, Zendesk API, Slack API, SendGrid, Google Sheets API.
Shipping Reconciliation Reporting Compares carrier charges, internal records, Slack exceptions, and shipping-cost outliers. Python SQL CSV Linux
Description
A reporting process for comparing shipping records across carrier exports, internal order data, and operational tracking notes.
Initial Problem
Shipping data lived in multiple places, which made it difficult to compare carrier charges against internal records or find shipments that did not match the expected system history.
What Was Built
A Python reporting workflow that merged FedEx CSV exports with internal shipping and order data. It compared what customers paid for shipping against what FedEx charged, produced overview and detail reports for spotting outliers, and helped verify that shipping discounts were being applied correctly.
The workflow also identified shipments that were not tracked in the internal system. For special-case shipments, it checked Slack messages where tracking numbers were sometimes shared separately, which helped distinguish true gaps from operational exceptions. The reports included extra detail for international shipments, since those followed a slightly different workflow.
The FedEx report was generated automatically, then exported to a watched folder. An inotifywait watcher on the Linux server detected new files and triggered the reporting script, then the generated reports were organized for review.
Impact
Created a repeatable review process for shipping exceptions, cost differences, discount issues, and shipments that did not match the expected internal history.
Tools
Python, SQL, CSV processing, inotifywait, Slack API, Google Drive API, carrier exports.
Inventory Reporting Automation Scrapes distributor portals and turns inventory reports into internal spreadsheet updates. Python Playwright Beautiful Soup Sheets
Description
A reporting automation that collected inventory data from multiple external distributor portals and updated internal spreadsheet reports.
Initial Problem
Inventory and sales data had to be gathered from several separate distributor systems, each with its own portal and report format. The process was manual, repetitive, and easy to delay or miss.
What Was Built
A Python workflow that used Playwright to navigate distributor portals and retrieve inventory reports, then used Beautiful Soup and spreadsheet processing to clean, extract, and normalize the data. The processed results were written back into internal reporting documents so the team could review stock and sales information in one place.
Impact
Reduced repetitive portal checking and gave the team a more consistent way to review stock and sales information from multiple outside sources.
Tools
Python, Playwright, Beautiful Soup, spreadsheet automation, web scraping, report processing.
Scheduled Call Automation Connects Calendly bookings to Zendesk tickets, Slack alerts, Sheets, and shared calendars. Flask Webhooks Zendesk Slack
Description
A scheduling automation that connected customer-booked call appointments to the support team's existing Zendesk and Slack workflows.
Initial Problem
Customer Service needed a way to offer scheduled calls without moving daily work into a separate scheduling tool. The process needed to keep Zendesk as the operational record, use Slack only for alerts, and avoid adding unnecessary assignment or tracking overhead.
What Was Built
A Flask webhook service that received Calendly booking and cancellation events, normalized scheduled times to Eastern Time, created or found the matching Zendesk user, and created a parked Zendesk ticket for each scheduled call. The workflow logged each event to a Google Sheet as a lightweight datastore and audit trail, then sent Slack alerts so the team had visibility without using Slack as the task system.
Cancellation handling solved the related Zendesk ticket, updated the sheet, and sent a Slack cancellation alert. A reminder scheduler moved upcoming calls from a future-call state to an imminent-call state, sent a reminder alert, and updated reminder tracking so Customer Service could work from familiar Zendesk views.
Impact
Let customers schedule calls while keeping Customer Service in the tools they already used, with Zendesk as the source of truth and Slack as a lightweight alert layer.
Tools
Python, Flask, Calendly webhooks, Zendesk API, Slack API, Google Sheets API, Google Calendar, cron.
Customer Account Cleanup Workflow Groups related customer records by phone so teams can recognize account context faster. Python SQL Zendesk CSV
Description
A data cleanup workflow for identifying related customer accounts and making them easier for internal teams to recognize without disrupting active accounts or changing account status.
Initial Problem
All accounts started with an account-number name, and some customers chose not to add a business name. That made certain records harder to interpret at a glance and made it harder for teams to understand which accounts belonged together, especially when more than one record was connected to the same phone number.
What Was Built
A Python and SQL workflow that used phone numbers as the connecting factor between likely related accounts. It grouped accounts for review, identified the most useful account context, exported cleanup data, tracked already-processed records, and created Zendesk tickets so the updates could be handled through the normal support workflow.
The process did not merge records, remove accounts, or mark active customers inactive. It was designed to make relationships between accounts clearer by updating display context in a way that helped departments recognize the related account and assist the customer more easily.
Impact
Helped departments recognize related accounts more easily without merging records, removing accounts, or changing active customer status.
Tools
Python, SQL, CSV processing, Zendesk API, production database queries.
Zendesk Attachment Cleanup Redacts outdated ticket attachments to reduce storage while preserving support history. Python Zendesk API CSV Logs Cron
Description
A scheduled cleanup process for reducing Zendesk storage by redacting outdated ticket attachments while leaving ticket history and support records intact.
Initial Problem
Zendesk storage usage was growing because old tickets still had file attachments long after the related jobs were complete. After confirming the retention approach with stakeholders, the team determined that most files were no longer needed after a certain age because job work was short-lived and source artwork was stored elsewhere.
What Was Built
A Python cleanup workflow that searched Zendesk for older tickets with attachments, fetched ticket comments, skipped already-redacted placeholder files, and redacted real attachments through the Zendesk API. The process did not delete tickets or remove the support conversation; it only removed outdated files that were no longer needed as extra reference material.
The workflow logged successful and failed redactions to CSV so cleanup runs could be reviewed and retried safely. It was also scheduled to keep running regularly, reducing storage use and preventing outdated files from being retained longer than necessary.
Impact
Reduced Zendesk storage use while keeping support conversations intact and preventing outdated files from being retained longer than necessary.
Tools
Python, Zendesk API, CSV logging, cron.
Zendesk Account Merging Finds phone-only Zendesk users and helps reconnect fragmented ticket history. Python Zendesk API Phone Normalization CSV
Description
A Zendesk cleanup workflow requested by Customer Service to help identify phone-only user records that were not attached to an email address, making it easier to connect them to existing customer records and complete support histories.
Initial Problem
Some Zendesk users existed only as phone numbers with no email address. That left ticket history attached to records that were hard to connect back to the correct customer. Phone formatting made this harder because the same number could appear in different forms, such as with or without a leading country code, and look like separate accounts.
What Was Built
A Python workflow that pulled unattached Zendesk users with phone numbers, normalized phone formats, searched for matching existing users, and exported likely related records for review. The output gave Customer Service a cleaner way to identify phone-only records that could be merged into existing customer accounts without manually checking each possible phone-number variation.
Impact
Gave Customer Service a faster path to identify phone-only records that belonged with existing users, making complete ticket history easier to find.
Tools
Python, Zendesk API, phone normalization, CSV reporting.