Work · Own product

MyPetCerts: modernizing a 10-year-old live SaaS

My own SaaS, live since 2016. Its Grails 6.2.3 / Java 17 rebuild is in final cutover prep, and I rehearsed the production cutover end to end: one pass, about 17 minutes, zero schema failures.

  1. 2.5.6
  2. 3.3.18
  3. 4.1.4
  4. 6.2.3
Framework upgrade path, Grails 2.5.6 → 6.2.3, with Java 8 → 17

MyPetCerts is a B2B2C platform for emotional-support-animal (ESA) and psychiatric-service-dog (PSD) certification. It connects consumers, licensed therapists and affiliates.

The problem

I built MyPetCerts in 2016 and have run it ever since. By 2025 its Grails 2.5.6 / Java 8 stack was held together with workarounds: a hand-patched AWS SDK, a Hibernate downgrade, and a server OS past end of life.

I needed to move a 10-year-old live app onto a supported stack. I couldn’t afford a big-bang rewrite, or any risk to live customers and payments.

What I built: the modernization

  • A stepwise framework upgrade: 2.5.6 → 3.3.18 → 4.1.4 → 6.2.3, plus Java 8 → 17. Every Grails 2 plugin was upgraded, replaced or rewritten in-house. For example, Quartz → Spring scheduling, the cache plugin → Caffeine, and the REST client → Micronaut HTTP client.
  • A security upgrade that didn’t lock anyone out: I moved to Spring Security 5.7, turned on CSRF protection, and kept ~25K legacy password hashes working through the encoder change.
  • Clean layering: I moved all 60 persistence calls out of controllers (48 saves, 12 deletes) into a transactional service layer.
  • Data safety: schema changes now run through versioned Liquibase migrations with strict schema validation. Date handling moved to java.time with an explicit UTC timezone. Data migrations run as standalone scripts that never boot the app.
  • A deploy pipeline: GitHub Actions → S3 → SSM. Deploys are health-checked with automatic rollback (proven on staging), and production has a manual approval gate.
  • A test suite from nothing: 55 empty stubs → ~6,600 test cases across 228 Spock specs.

The platform

  • A therapist-reviewed assessment workflow with state-specific compliance rules.
  • 14 dedicated Stripe services in the v2 rebuild: subscriptions, Connect payouts to affiliates, invoices, transfers and verified webhooks.
  • Server-side conversion tracking to GA4, Google Ads and the Facebook Conversions API.
  • An audit-trail subsystem, and ~38 data tables moved to server-side processing.

Results

  • The production cutover was rehearsed end to end on a restored copy of the production database. It passed in one go in about 17 minutes, with zero schema failures.
  • Scale: 91 domain classes, 123 controllers and 105 services. About 200K lines of Groovy/GSP application code, plus ~115K lines of tests.
  • ~6,600 test cases built from 55 empty stubs. A coverage-gated, AI-assisted test-generation workflow (Claude Code) found 7 real production bugs along the way.
  • Live since 2016, and white-labeled for another pet-documentation company (2019–20).

My role

Everything: product and domain design, back end and front end, AWS infrastructure, payments, the modernization, deployment and operations. I also run the business.

Tell me what version you're on and what's breaking.

I'll tell you what the path looks like.