Case study
live
Weekend Plant
A gardening content site: aggregated plant data from disjointed industry sources, AI-filled gaps with human review, deep-research garden-skill guides, an SEO-first publishing pipeline, and scheduled social auto-posting.
The problem
Gardening content is hard for three reasons: plant data is scattered across dozens of disjointed industry sources (each incomplete, inconsistent, or contradictory), deeply-researched skill guides take hours of reading per article, and none of that reaches anyone without a steady drumbeat on social. The site had to address all three without triplicating the admin surface.
What I did
- 01
Aggregated disjointed industry plant data into one normalized library
Pulled plant data from several industry sources and merged it into a single normalized profile per plant. Conflicts resolve via a scoring model; gaps are identified and queued for the next step so each plant ends up with a comprehensive record rather than a patchwork of half-filled fields.
- 02
Filled the gaps with AI, and kept a human in the loop
OpenAI and Google GenAI propose values for missing fields and rewrite inconsistent ones; an admin reviews and accepts them in-form. Nothing ships without human signoff, so the library stays accurate rather than filler.
- 03
Built scientifically-accurate garden skills guides with deep-research drafting
Each garden skills guide starts from deep online research, with AI drafting the skeleton and pulling citations before a human refines for accuracy and voice. The authoring pipeline is shared with plant profiles and plant combinations so it doesn't get rebuilt per content type.
- 04
Built for SEO from the metadata up
Every plant profile, garden-skills guide, and combination page renders server-side with route-level metadata, OpenGraph cards, and JSON-LD structured data sized to the content type. The sitemap regenerates from the live catalog rather than being hand-maintained, with `lastModified` driven from the content's edit timestamp so search engines pick up real changes instead of stale ones.
- 05
Auto-posted plants and skills to Facebook + Instagram on a schedule
A scheduled pipeline picks plants and skills from the catalog, formats each for the target network's quirks, and publishes through the Meta Graph API. The social accounts stay active across both content types without a content calendar to maintain.
- 06
Built an image pipeline that handles the messy realities
FormData → resize and optimize (including HEIC) → Cloudflare R2, all in one module. Bulk-upload scripts for source images, and an auto hero-crop selector that scores candidate crops instead of defaulting to center.
- 07
Collapsed three content types into one shared authoring pipeline
Generic `ContentCard` and `ContentForm` components driven by field configs, with shared CRUD helpers, admin auth, rate limiting, and AI generation. Content-type-specific code only exists where the models genuinely differ, so adding a new type mostly means adding a field config.
The outcome
Weekend Plant ships a plant library with aggregated and AI-filled data, scientifically-researched garden skills guides, and plant-combination suggestions, all authored from one admin with AI assist. Plants and skills auto-post to Facebook and Instagram on a schedule.
Under the hood
Next.js 16 + TypeScript + MongoDB + NextAuth, with OpenAI and Google GenAI in the authoring loop and the Meta Graph API for scheduled social posts. Vitest for logic modules (CRUD, rate limit, cache, API helpers) with a shared mock-DB factory; Playwright for end-to-end. Brevo for transactional mail, with bounce tracking and auto-suppression (3 bounces / 30 days) plus a complaint blacklist. The color system derives from a single anchor via a script that verifies WCAG AA contrast across all 23 text/background pairings, the same approach used on this portfolio.