Skip to content

Latest commit

 

History

15 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Feed Medic

Your autonomous Merchant Center guardian

Gemini 3.5 Flash · Genkit · Vertex AI · Cloud Run · Firestore

Live demo · Demo video: [VIDEO_URL] (replace before submission)


The problem

Google Merchant Center silently disapproves products for feed errors — missing prices, invalid GTINs, titles over 150 characters, promotional text baked into images. Each disapproved SKU stops serving on Shopping ads and free listings. In this 50-SKU demo catalog, the dashboard surfaces €1,219/day in revenue at risk from pending feed errors — invisible loss before anyone opens a spreadsheet. Feed Medic exists to catch those errors early, propose fixes, and learn your brand rules — before disapprovals hit your P&L.


What Feed Medic does

Feed Medic runs an autonomous compliance pipeline with a human marketer always in the loop:

  1. Scans autonomously — Cloud Scheduler triggers a full catalog scan every 6 hours via POST /api/scan.
  2. Diagnoses with Gemini — the diagnoseProduct Genkit flow checks each product against Merchant Center rules (title length, GTIN, price, description, image promos).
  3. Proposes fixes with confidence scores — every issue becomes a structured fix with an English explanation, a suggested correction, and a 0–1 confidence score shown in the dashboard.
  4. Human-in-the-loop approval queue — nothing is auto-published. The agent never applies corrections to your feed; every fix waits in pending_approval until a marketer approves or rejects it. Confidence scores help you defer on borderline cases rather than risk a bad publish.
  5. Learns brand rules from rejections — when you reject a fix and explain why, the learnBrandRule flow turns your feedback into a reusable rule stored in Firestore and injected into every future diagnosis.

Every agent action is logged to agent_logs with a reasoning trace — full audit trail from scan to approval.


The killer feature: brand rules learning

Most feed tools apply generic Google rules. Feed Medic learns your brand voice from rejection feedback.

Example from the demo catalog:

Step What happens
Before PROD-003 is flagged for TITLE_TOO_LONG. Gemini proposes shortening the title but keeps promotional words (Promo, Soldes).
You reject Reason: "Never use promotional words like Promo or Soldes in my titles."
Agent learns learnBrandRule writes a rule to brand_rules (e.g. no promotional words in titles).
After Re-diagnose PROD-012 and PROD-025 — titles are shortened and promo words are stripped, without you repeating the instruction.

Run the proof yourself after a rejection:

npm run rediagnose:demo   # PROD-012 + PROD-025

Multimodal image analysis

Text-only feed audits miss a common Merchant Center failure mode: promotional overlays burned into product photos (-50% SOLDES, Livraison Gratuite, etc.).

The analyzeProductImage Genkit flow sends product images to Gemini Vision (same Gemini 3.5 Flash model via Vertex AI). Detected overlay text is stored on the fix, highlighted in the approval UI, and surfaced as PROMO_IN_IMAGE corrections — with clickable thumbnails in the dashboard.

npm run scan:images   # 6 local images, ~2 min

Architecture

Architecture

Source diagram (editable): docs/architecture.mmd — export at mermaid.live if you want to tweak styling.

Component Region Role
Cloud Scheduler europe-west1 Fires feed-medic-scan every 6 h → POST /api/scan with x-cron-secret.
Cloud Run europe-west1 Hosts the Next.js app (dashboard + API routes). Scale-to-zero between scans.
Firestore europe-west1 products, fixes, brand_rules, agent_logs — single source of truth.
Secret Manager global (GCP) Stores CRON_SECRET for the scan endpoint (prod rules deny client Firestore access).
Genkit flows — diagnoseProduct, analyzeProductImage, learnBrandRule — typed I/O, structured JSON.
Vertex AI / Gemini 3.5 Flash global endpoint All LLM + vision calls via ADC. Model runs on global (not regional — required for this model).

Local vs production: one codebase, env-driven. Local dev uses the Firestore emulator + browser Firestore client. Production uses Cloud Firestore + REST API routes (/api/dashboard, approve/reject, delete rule).


Tech stack & hackathon requirements

Requirement How Feed Medic meets it
Gemini 3.5 Flash ✓ Model gemini-3.5-flash on Vertex AI (agent/diagnose.ts, agent/analyze-image.ts, agent/learn-rule.ts).
Genkit ✓ Flows defined with ai.defineFlow, Zod schemas, @genkit-ai/google-genai Vertex plugin.
Google Cloud ✓ Cloud Run (hosting), Firestore (data), Cloud Scheduler (cron scan), Secret Manager (cron auth), Vertex AI (Gemini).

App stack: Next.js 16 · React 19 · TypeScript · Firebase Admin + client SDK · Recharts · Tailwind CSS 4.


Run it yourself (spin-up instructions)

These steps are written for someone cloning the repo on a fresh machine. No guessing required.

Prerequisites

Tool Version Purpose
Node.js 20+ App and scripts
gcloud CLI latest Vertex AI auth (application-default login)
GCP project any Vertex AI API enabled; billing on. Set GOOGLE_CLOUD_PROJECT in .env.local.

Forkers: set GOOGLE_CLOUD_PROJECT (and Cloud Run env vars) to your own GCP project id — no hardcoded project in source code.

1. Clone and install

git clone https://github.com/orlane-create/feed-medic.git
cd feed-medic
npm install

2. Configure environment

cp .env.example .env.local

Default .env.local points the dashboard at the local Firestore emulator. No API keys needed.

3. Authenticate Vertex AI (one time per machine)

gcloud auth application-default login
gcloud config set project feed-medic-505908   # must match GOOGLE_CLOUD_PROJECT in .env.local

Ensure the Vertex AI API is enabled on your project.

4. Start Firestore emulator (terminal 1)

npm run emulators:start

Keep this running. Emulator UI: http://localhost:4010/firestore/demo-no-project/data

5. Seed agent data (terminal 2 — first time only)

Choose one path:

Fast demo (~2 min, 15 Gemini calls) — populates the approval queue only:

npm run reseed:fixes

Full catalog scan (~10 min, 50 products) — complete pipeline:

npm run scan:feed

Optional — sync local product thumbnails for the dashboard:

npm run sync:local-images

6. Start the dashboard (terminal 2 or 3)

npm run dev

Open http://localhost:3000. You should see pending fixes, KPIs, and the agent log.

7. Demo loop (repeatable, no extra Gemini cost)

npm run demo:reset

Refresh the browser. See DEMO.md for the full 10-minute demo script.

Deploy to Google Cloud

Assumes project feed-medic-505908, region europe-west1, and gcloud authenticated.

A. Create Firestore (once)

gcloud firestore databases create \
  --location=europe-west1 \
  --type=firestore-native \
  --project=feed-medic-505908

B. Deploy production security rules

npm run firestore:rules:deploy

C. Create cron secret (once)

openssl rand -hex 32 | gcloud secrets create CRON_SECRET \
  --data-file=- \
  --project=feed-medic-505908

Grant the Cloud Run service account access to Firestore, Vertex AI, and Secret Manager (Console → IAM, or gcloud projects add-iam-policy-binding).

D. Deploy Cloud Run

gcloud run deploy feed-medic-dashboard \
  --source . \
  --region europe-west1 \
  --project feed-medic-505908 \
  --allow-unauthenticated \
  --min-instances 0 \
  --max-instances 2 \
  --timeout 900 \
  --memory 1Gi \
  --cpu 1 \
  --set-env-vars "NEXT_PUBLIC_USE_FIRESTORE_EMULATOR=false,NEXT_PUBLIC_FIREBASE_PROJECT_ID=feed-medic-505908,FIREBASE_PROJECT_ID=feed-medic-505908,GOOGLE_CLOUD_PROJECT=feed-medic-505908" \
  --set-secrets "CRON_SECRET=CRON_SECRET:latest"

E. Seed production from local emulator (optional)

With the emulator running and demo data loaded:

npm run seed:production -- --confirm feed-medic-505908

F. Schedule autonomous scans (once)

CRON_VAL=$(gcloud secrets versions access latest --secret=CRON_SECRET --project=feed-medic-505908)

gcloud scheduler jobs create http feed-medic-scan \
  --location=europe-west1 \
  --project=feed-medic-505908 \
  --schedule "0 */6 * * *" \
  --uri "https://YOUR_CLOUD_RUN_URL/api/scan" \
  --http-method POST \
  --headers "x-cron-secret=${CRON_VAL}"

Replace YOUR_CLOUD_RUN_URL with the URL printed by gcloud run deploy.


Simulated vs real

Layer Status Details
Merchant Center connector Simulated Product catalog is data/products.json — same field shape as the Content API for Shopping, but no live MC account.
Gemini / Vertex AI Real Live model calls with structured Genkit outputs.
Firestore Real (prod) / Emulator (local) Same schema either way.
Cloud Run + Scheduler Real Public URL, cron-triggered scans.
Human approvals Real Approve/reject writes to Firestore and triggers rule learning.

_test_expected_error

15 of 50 catalog products include a _test_expected_error field (e.g. "TITLE_TOO_LONG") so we can validate detection accuracy in demos. This field is never sent to Gemini — stripTestField() removes it before every AI call (agent/diagnose.ts, data/README.md). The remaining 35 products are compliant baselines to guard against false positives.


Cost efficiency

Designed for hackathon budgets and solo-operator scale-to-zero:

Service Typical monthly cost Why it stays low
Cloud Run ~€2–8 min-instances=0; dashboard idle most of the day; scan bursts only every 6 h.
Firestore ~€1–5 Small demo dataset (50 products); reads via API polling in prod.
Vertex AI (Gemini 3.5 Flash) ~€2–8 ~50 products × 4 scans/day × structured short outputs; skip already-scanned products.
Cloud Scheduler ~€0.10 One job, 4 runs/day.
Secret Manager ~€0.06 One secret (CRON_SECRET).
Total estimate ~€6–22 / month No always-on GPU, no API-key free-tier roulette, no duplicate infra.

Frugal design choices: resume-safe scans (skip scan_status=scanned), batch size 5 with pauses, human gate before any fix goes live, emulator for free local iteration, production seed script copies demo data without re-running Gemini.


Project structure

feed-medic/
├── agent/              # Genkit flows (diagnose, vision, learn-rule)
├── app/                # Next.js pages + API routes
├── components/         # Dashboard UI
├── data/               # Simulated product catalog (products.json)
├── docs/               # Architecture diagram + Devpost draft
├── hooks/              # Dashboard data (emulator snapshots vs API poll)
├── lib/                # Firestore config, feed scan, fix actions, metrics
├── scripts/            # CLI: scan, seed, demo reset, production seed
├── DEMO.md             # 10-minute demo script for video rehearsals
├── Dockerfile          # Cloud Run standalone build
└── firebase.json       # Emulator config (dev rules)

License

Hackathon submission — see repository owner for reuse terms.


Built solo by a growth marketer using AI-assisted coding, for the Google All Things Agentic Hackathon.

Build log: I'm a marketer, not a developer — I built an autonomous AI agent that learns my brand rules

About

Feed Medic : Autonomous AI Agent for Google Merchant Center. Built for the All Things Agentic Hackathon.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages