All work
Case Study4 min read

Case Study: Better Addiction Care

A nationwide directory platform connecting people seeking addiction treatment with verified rehab centers, AA/NA meetings, and educational resources through a custom Laravel application with Filament CMS and Meilisearch-powered search.

Case Study: Better Addiction Care

Role: Lead developer
Timeline: June–September 2026
Stack: Laravel 10, Filament v3, PHP 8.1, MySQL, Redis, Meilisearch, Tailwind CSS, Blade, Vite
Live Site: https://betteraddictioncare.com
Repo: https://github.com/devbetteraddictioncare/addictiondirectory

Overview

Better Addiction Care is a nationwide directory platform that helps people find addiction treatment centers, support group meetings, and recovery resources. The site serves confidential, vetted information about rehab facilities across all 50 states, educational articles on substance abuse, insurance verification tools, and location-based search for AA/NA meetings. Content editors manage thousands of listings, articles, and dynamically generated pages through a Filament admin panel with a custom page builder.

I led development on the platform during a four-month engagement, working with a Laravel 10 foundation that had accumulated technical debt from rapid feature expansion. The codebase supported ~250 models, complex domain-scoped routing, legacy Bootstrap templates coexisting with newer Tailwind components, and a mix of static and dynamically generated URLs.

The Challenge

The platform faced three core technical challenges:

  1. Complex URL resolution. The site needed to serve static custom pages, template-driven location pages (state, city, listing detail), article archives, and legacy section views—all through a single routing layer that worked across production, staging, and local development domains.

  2. Content management at scale. Editors managed treatment center listings with dozens of pivot relationships (conditions treated, insurance accepted, treatment modalities), generated SEO-optimized pages for every state and city, and built custom landing pages with a flexible block system. The admin panel needed to support bulk operations, media management, and content previews without performance degradation.

  3. Search and discovery. Users needed fast, relevant search across listings filtered by location, insurance, treatment type, and condition. The existing MySQL full-text search was slow and couldn't handle the faceted filtering required for a directory of this scale.

What I Built

URL Resolution and Routing Architecture

I redesigned the URL resolution pipeline to support three layers: static pages win first (via PageOverride middleware checking for published Page records), then template-based pages match by template_type (state, city, listing, article), and finally legacy catch-all routes in DynamicUrlController handle older section views. This architecture let editors create custom pages that override default templates without breaking existing URLs.

Routes are defined per-domain in routes/web.php (production, staging, local), and all public routes must be registered in each group before the /{first} catch-all. Local development runs on 127.0.0.1 because route matching is domain-scoped—localhost won't match. This constraint required careful developer documentation, which I added to CLAUDE.md as an architecture reference.

Filament Admin and Page Builder

The admin panel runs on Filament v3 at /admin and includes custom resources for listings, articles, pages, meetings, and taxonomy management. I extended Filament with:

  • Block-based page builder for landing pages, using Filament's repeater fields with custom Blade components. Editors can add hero sections, feature grids, testimonials, and embedded forms without touching code.
  • Filament Curator for media management with WebP conversion via Glide and gd, integrated with Spatie Media Library.
  • Filament TipTap Editor for rich-text article content with custom shortcodes for dynamic content injection (facility links, insurance logos, CTAs).
  • Bulk operations for updating listings, regenerating sitemaps, and reindexing search without blocking the UI.

The page builder supports both Bootstrap 5 (legacy) and Tailwind CSS (newer blocks) in the same view layer, letting editors gradually migrate content to the new design system.

Meilisearch Integration

I integrated Laravel Scout with Meilisearch for high-performance search across treatment center listings. The search index supports:

  • Faceted filtering by state, city, insurance provider, conditions treated, and treatment modalities
  • Geolocation search with radius filtering using GeoIP2 for IP-to-location fallback
  • Typo tolerance and relevance tuning to handle common misspellings in substance names and city searches

Reindexing is triggered manually via php artisan scout:import "App\Models\Listing" and documented in docs/meilisearch.md. Meilisearch runs in the Docker Compose stack during local development (via Laravel Sail) and as a separate service in production.

Data Import and Maintenance Tooling

I built custom Artisan commands for data import, export, and maintenance workflows:

  • CSV import via league/csv for bulk listing uploads from third-party sources
  • Sitemap generation (php artisan sitemaps:create) for multi-file XML sitemaps covering all listings, articles, and dynamic pages
  • Image warming (php artisan glide:warm) to pre-generate WebP variants before deploy, avoiding lazy-load delays
  • Activity logging via spatie/laravel-activitylog and z3d0x/filament-logger for audit trails on listing updates

These commands are documented in docs/operations-log.md, which serves as a deploy checklist listing migrations, environment variables, and post-deploy steps in reverse chronological order.

Technical Highlights

The platform runs on Laravel Forge with zero-downtime deploys behind Cloudflare. Each release starts from a fresh directory, so the Forge deploy script must regenerate sitemaps and warm the image cache after every deploy. I documented this requirement and added it to the standard deploy checklist.

Redis handles session storage, cache, and queue jobs. Mailpit intercepts outbound mail in local development (via Sail). Cloudflare provides CDN, DDoS protection, and rate limiting in production.

Integrations include:

  • CallTrackingMetrics for sponsored helpline tracking
  • Google APIs (Places, reCAPTCHA) for location validation and spam prevention
  • OpenAI (via openai-php/laravel) for content assistance tooling
  • Spatie Google Fonts for self-hosted web fonts

The test suite (php artisan test) covers unit and feature tests for URL resolution, search filtering, and listing import workflows. Code style is enforced with Laravel Pint (vendor/bin/pint).

Outcome

[add outcome metrics: search performance improvement, editor productivity gains, uptime during migration]

The refactored architecture gave editors full control over URL structure and page layout without developer intervention. The Meilisearch integration replaced slow MySQL full-text queries with sub-100ms faceted search responses. The operations log and developer documentation (across nine files in docs/) reduced onboarding time for new team members and provided a clear deploy checklist for production releases.

The platform continues to serve as a nationwide resource for people seeking addiction treatment, with content managed entirely through the Filament admin panel and search powered by Meilisearch.

Screenshots

Better Addiction Care on desktop

Better Addiction Care on mobile