Skip to content
menu-verification logo

Menu Verification Skill

menu-verification

Use this skill to verify whether restaurants actually have Planted products on their current menu. Crawls restaurant websites, parses PDF menus, and updates venue verification status in Firestore.

SKILL.md

Full skill instructions

Menu Verification Skill

This skill verifies whether discovered venues actually have Planted products on their current menus. It's essential for maintaining data quality - press releases and discovery don't guarantee ongoing availability.

When This Skill Activates

Triggers on:

  • Verifying newly discovered venues
  • Re-checking venues marked as unverified
  • Validating venues from press releases
  • Auditing existing venue data quality

Quick Start

Run the Verification Agent

cd planted-availability-db/​packages/​scrapers

# Verify all unverified venues with websites
node verify-menu-agent.cjs

# Verify a specific venue by ID
node verify-menu-agent.cjs --venue-id=VENUE_ID_HERE

What the Agent Does

  1. Finds unverified venues with websites in Firestore
  2. Crawls the website including subpages (/​restaurant, /​en, /​de, etc.)
  3. Discovers PDF links on the pages
  4. Tries common PDF paths directly (/​media/​menu.pdf, /​speisekarte.pdf, etc.)
  5. Parses PDF content using pdf-parse library
  6. Searches for Planted keywords (planted, plant-based, geschnetzeltes, etc.)
  7. Updates Firestore with verification status and any dishes found

Verification Statuses

StatusMeaning
verified_on_menuPlanted products confirmed on current menu
not_found_on_menuNo Planted products found after thorough check
unverifiedNot yet checked
needs_manual_checkWebsite couldn't be crawled, needs human verification

Manual Verification Workflow

For venues the agent can't verify automatically:

1. Check the Website Directly

# Get venue details
node -e "
const admin = require('firebase-admin');
admin.initializeApp({ credential: admin.credential.cert('../​../​service-account.json') });
const db = admin.firestore();
db.collection('venues').doc('VENUE_ID').get().then(d => console.log(JSON.stringify(d.data(), null, 2)));
"

2. Look for PDF Menus

Common PDF locations to check:

  • /​media/​menu.pdf, /​media/​speisekarte.pdf
  • /​downloads/​menu.pdf
  • /​restaurant/​menu.pdf
  • Language variants: _en.pdf, _de.pdf, _d.pdf

3. Search for Planted Keywords

In PDFs or HTML, search for:

  • planted (brand name)
  • plant-based, plant based, pflanzenbasiert
  • geschnetzeltes (common planted dish)
  • planted chicken, planted kebab, planted steak

4. Update the Venue

# Mark as verified with planted products
node -e "
const admin = require('firebase-admin');
admin.initializeApp({ credential: admin.credential.cert('../​../​service-account.json') });
const db = admin.firestore();
db.collection('venues').doc('VENUE_ID').update({
  status: 'active',
  verification_status: 'verified_on_menu',
  verification_date: new Date(),
  verification_method: 'manual',
  verification_note: 'Found X planted dishes on menu PDF',
  updated_at: new Date()
});
"

# Or mark as not found
node -e "
const admin = require('firebase-admin');
admin.initializeApp({ credential: admin.credential.cert('../​../​service-account.json') });
const db = admin.firestore();
db.collection('venues').doc('VENUE_ID').update({
  status: 'unverified',
  verification_status: 'not_found_on_menu',
  verification_date: new Date(),
  verification_method: 'manual',
  verification_note: 'No planted products found on menu',
  updated_at: new Date()
});
"

Adding Dishes from Verified Menus

When planted products are found:

node -e "
const admin = require('firebase-admin');
admin.initializeApp({ credential: admin.credential.cert('../​../​service-account.json') });
const db = admin.firestore();

const dish = {
  venue_id: 'VENUE_ID',
  name: 'Planted Geschnetzeltes mit Rösti',
  description: 'Swiss-style planted strips with hash browns',
  price: { amount: 32.00, currency: 'CHF' },
  planted_products: ['planted.geschnetzeltes'],
  status: 'active',
  source: 'menu_verification',
  created_at: new Date(),
  updated_at: new Date()
};

db.collection('dishes').add(dish).then(ref => console.log('Added dish:', ref.id));
"

Planted Product SKUs

Common product identifiers:

  • planted.chicken - Planted Chicken
  • planted.geschnetzeltes - Planted Geschnetzeltes (strips)
  • planted.kebab - Planted Kebab
  • planted.steak - Planted Steak
  • planted.pulled - Planted Pulled
  • planted.schnitzel - Planted Schnitzel

Removing Invalid Venues

If a venue doesn't have planted products and was added in error:

# Delete venue (and its dishes)
node -e "
const admin = require('firebase-admin');
admin.initializeApp({ credential: admin.credential.cert('../​../​service-account.json') });
const db = admin.firestore();

const venueId = 'VENUE_ID';

// Delete dishes first
db.collection('dishes').where('venue_id', '==', venueId).get()
  .then(snap => {
    const batch = db.batch();
    snap.docs.forEach(doc => batch.delete(doc.ref));
    return batch.commit();
  })
  .then(() => db.collection('venues').doc(venueId).delete())
  .then(() => console.log('Deleted venue and dishes'));
"

Agent Configuration

The verify-menu-agent.cjs searches for these patterns:

Subpages Crawled

const SUBPAGE_PATTERNS = [
  '/​restaurant', '/​en', '/​de', '/​bar', '/​cuisine', '/​kulinarik'
];

PDF Paths Tried

const COMMON_PDF_PATHS = [
  '/​media/​menu.pdf', '/​media/​speisekarte.pdf',
  '/​media/​restaurant_mo_-_fr_d.pdf', // Kronenhalle pattern
  '/​downloads/​menu.pdf', '/​menu.pdf'
];

Keywords Searched

const PLANTED_KEYWORDS = [
  'planted', 'plant-based', 'plant based', 'pflanzenbasiert',
  'planted chicken', 'planted kebab', 'planted geschnetzeltes'
];

Dependencies

The agent requires:

npm install pdf-parse  # For PDF text extraction

Example Session

$ node verify-menu-agent.cjs

=== Menu Verification Agent ===
Found 3 unverified venues with websites

Checking: Kronenhalle (https://www.kronenhalle.com)
  Crawling homepage...
  Found 2 PDF links
  Parsing: restaurant_mo_-_fr_d.pdf (12 pages)
  FOUND: "Planted Geschnetzeltes «Kronenhalle» mit Rösti"
  FOUND: "Planted Steak mit Sanddorn"
  Status: verified_on_menu (2 dishes added)

Checking: Lindenhofkeller (https://www.lindenhofkeller.ch)
  Crawling homepage + subpages...
  Found 3 PDF links
  Parsing: drinks.pdf (31 pages) - no planted
  Parsing: lunch.pdf (4 pages) - no planted
  Parsing: dinner.pdf (6 pages) - no planted
  Status: not_found_on_menu

=== Summary ===
Verified: 1
Not found: 1
Errors: 0

Troubleshooting

PDF Not Parsing

  • Check if pdf-parse is installed: npm ls pdf-parse
  • Some PDFs are image-based (scanned) - need manual check
  • Compressed PDFs may fail - try downloading manually

Website Blocking

  • Some sites block automated crawlers
  • Try with different User-Agent
  • May need manual verification

No Menu Found

  • Check if restaurant uses third-party menu systems
  • Look for iframe embeds
  • Check delivery platform listings instead

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View