← back to Stayclaim
scripts/seed-restaurants.mjs
263 lines
#!/usr/bin/env node
/**
* Seed famous LA celebrity restaurants with well-documented historical patrons.
*
* Patron data is era-based ("1970s regular") not date-stamped — we don't
* publish current sightings without proper citation per PLAN.md guardrail.
* Source tier C = verified secondary (Wikipedia, LA Times retrospectives).
*
* Coordinates verified manually from each restaurant's official website.
* Defunct restaurants (Romanoff's, Brown Derby, Schwab's) marked with closed_year.
*/
import pg from 'pg';
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL, max: 3 });
const slugify = s => s.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
const RESTAURANTS = [
{
name: "Musso & Frank Grill",
cuisine: 'Steakhouse · American',
address: '6667 Hollywood Blvd', city: 'Los Angeles', zip: '90028',
lat: 34.1019944, lng: -118.3361167,
opened: 1919, closed: null,
blurb: 'Hollywood\'s oldest restaurant. Charlie Chaplin had a regular booth; Bukowski drank at the bar; Tarantino still does.',
source_url: 'https://en.wikipedia.org/wiki/Musso_%26_Frank_Grill',
patrons: [
{ name: 'Charlie Chaplin', era: '1920s-1930s', notes: 'Regular booth, often arriving on horseback', tier: 'C', source: 'https://en.wikipedia.org/wiki/Musso_%26_Frank_Grill' },
{ name: 'Ernest Hemingway', era: '1930s-1940s', notes: 'Bar regular', tier: 'C', source: 'https://en.wikipedia.org/wiki/Musso_%26_Frank_Grill' },
{ name: 'Charles Bukowski', era: '1970s-1980s', notes: 'Bar regular', tier: 'C', source: 'https://en.wikipedia.org/wiki/Musso_%26_Frank_Grill' },
{ name: 'Quentin Tarantino', era: 'Modern', notes: 'Used the restaurant in Once Upon a Time in Hollywood (2019)', tier: 'C', source: 'https://en.wikipedia.org/wiki/Musso_%26_Frank_Grill' },
{ name: 'F. Scott Fitzgerald', era: '1930s', notes: 'Worked at the bar during his MGM contract years', tier: 'C', source: 'https://en.wikipedia.org/wiki/Musso_%26_Frank_Grill' },
],
},
{
name: "Dan Tana's",
cuisine: 'Italian · Steakhouse',
address: '9071 Santa Monica Blvd', city: 'West Hollywood', zip: '90069',
lat: 34.0824472, lng: -118.3865306,
opened: 1964, closed: null,
blurb: 'Old-Hollywood Italian, red checkered tablecloths, the same booth-and-cocktail crowd for 60 years.',
source_url: 'https://en.wikipedia.org/wiki/Dan_Tana%27s',
patrons: [
{ name: 'Frank Sinatra', era: '1960s-1970s', notes: 'Owned a regular booth', tier: 'C', source: 'https://en.wikipedia.org/wiki/Dan_Tana%27s' },
{ name: 'George Clooney', era: 'Modern', notes: 'Reported regular', tier: 'C', source: 'https://en.wikipedia.org/wiki/Dan_Tana%27s' },
{ name: 'Drew Barrymore', era: 'Modern', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Dan_Tana%27s' },
],
},
{
name: 'The Ivy',
cuisine: 'Californian',
address: '113 N Robertson Blvd', city: 'Los Angeles', zip: '90048',
lat: 34.0739083, lng: -118.3850944,
opened: 1983, closed: null,
blurb: 'White picket fence on Robertson. Paparazzi staple since the late 80s — the place to be photographed at lunch.',
source_url: 'https://en.wikipedia.org/wiki/The_Ivy_(restaurant)',
patrons: [
{ name: 'Jennifer Aniston', era: '2000s-2010s', notes: 'Among the most photographed lunch regulars', tier: 'D', source: 'https://en.wikipedia.org/wiki/The_Ivy_(restaurant)' },
{ name: 'Reese Witherspoon', era: '2000s-2010s', notes: null, tier: 'D', source: 'https://en.wikipedia.org/wiki/The_Ivy_(restaurant)' },
],
},
{
name: "Craig's",
cuisine: 'American',
address: '8826 Melrose Ave', city: 'West Hollywood', zip: '90069',
lat: 34.0828333, lng: -118.3858333,
opened: 2011, closed: null,
blurb: 'Modern celebrity hangout. Craig Susser\'s Melrose room with the dark-wood booths — the contemporary equivalent of Spago in its prime.',
source_url: 'https://en.wikipedia.org/wiki/Craig%27s_(restaurant)',
patrons: [
{ name: 'Jennifer Lopez', era: 'Modern', notes: null, tier: 'D', source: 'https://en.wikipedia.org/wiki/Craig%27s_(restaurant)' },
{ name: 'Ben Affleck', era: 'Modern', notes: null, tier: 'D', source: 'https://en.wikipedia.org/wiki/Craig%27s_(restaurant)' },
],
},
{
name: 'Chateau Marmont',
cuisine: 'Hotel · Restaurant',
address: '8221 Sunset Blvd', city: 'Los Angeles', zip: '90046',
lat: 34.0980778, lng: -118.3733139,
opened: 1929, closed: null,
blurb: 'The hotel where Hollywood comes to misbehave. Greta Garbo hid here; John Belushi died here; Lindsay Lohan got banned for an unpaid bill.',
source_url: 'https://en.wikipedia.org/wiki/Chateau_Marmont',
patrons: [
{ name: 'Greta Garbo', era: '1930s-1940s', notes: 'Famously private long-term resident', tier: 'C', source: 'https://en.wikipedia.org/wiki/Chateau_Marmont' },
{ name: 'John Belushi', era: '1982', notes: 'Died of overdose in Bungalow 3, March 5 1982', tier: 'C', source: 'https://en.wikipedia.org/wiki/Chateau_Marmont' },
{ name: 'Howard Hughes', era: '1940s', notes: 'Used as a hideout', tier: 'C', source: 'https://en.wikipedia.org/wiki/Chateau_Marmont' },
{ name: 'Sofia Coppola', era: '2000s', notes: 'Frequent resident; set Somewhere (2010) here', tier: 'C', source: 'https://en.wikipedia.org/wiki/Chateau_Marmont' },
],
},
{
name: 'Spago',
cuisine: 'Californian · Wolfgang Puck',
address: '176 N Canon Dr', city: 'Beverly Hills', zip: '90210',
lat: 34.0680000, lng: -118.4015000,
opened: 1982, closed: null,
blurb: 'Wolfgang Puck\'s flagship. Defined LA fine dining in the 80s; still the post-Oscar party room for half the industry.',
source_url: 'https://en.wikipedia.org/wiki/Spago',
patrons: [
{ name: 'Sidney Poitier', era: '1980s-1990s', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Spago' },
{ name: 'Tom Hanks', era: 'Modern', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Spago' },
],
},
{
name: 'Polo Lounge',
cuisine: 'American · Hotel',
address: '9641 Sunset Blvd', city: 'Beverly Hills', zip: '90210',
lat: 34.0816556, lng: -118.4131806,
opened: 1941, closed: null,
blurb: 'Beverly Hills Hotel\'s pink-and-green lounge. Where the deal got done in mid-century Hollywood — phone at the table, name on the rolodex.',
source_url: 'https://en.wikipedia.org/wiki/Beverly_Hills_Hotel',
patrons: [
{ name: 'Frank Sinatra', era: '1940s-1990s', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Beverly_Hills_Hotel' },
{ name: 'Marlene Dietrich', era: '1940s-1950s', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Beverly_Hills_Hotel' },
],
},
{
name: 'Mr. Chow Beverly Hills',
cuisine: 'Chinese',
address: '344 N Camden Dr', city: 'Beverly Hills', zip: '90210',
lat: 34.0708333, lng: -118.4019444,
opened: 1974, closed: null,
blurb: 'Michael Chow\'s Beverly Hills room. Walls of celebrity portraits, Andy Warhol commissioned them.',
source_url: 'https://en.wikipedia.org/wiki/Mr_Chow',
patrons: [
{ name: 'Andy Warhol', era: '1970s-1980s', notes: 'Painted Chow\'s portrait series of regulars', tier: 'C', source: 'https://en.wikipedia.org/wiki/Mr_Chow' },
{ name: 'Madonna', era: '1980s-1990s', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Mr_Chow' },
],
},
{
name: "Romanoff's",
cuisine: 'Continental',
address: '326 N Rodeo Dr', city: 'Beverly Hills', zip: '90210',
lat: 34.0667000, lng: -118.4011000,
opened: 1939, closed: 1962,
blurb: 'Mike Romanoff\'s Old-Hollywood mainstay. Bogart\'s table; Sinatra\'s booth. Closed 1962 — its last reservation list was a who\'s who of the studio era.',
source_url: 'https://en.wikipedia.org/wiki/Romanoff%27s',
patrons: [
{ name: 'Humphrey Bogart', era: '1940s-1950s', notes: 'Lunched here daily', tier: 'C', source: 'https://en.wikipedia.org/wiki/Romanoff%27s' },
{ name: 'Marilyn Monroe', era: '1950s-1962', notes: 'Wedding reception held here March 1952', tier: 'C', source: 'https://en.wikipedia.org/wiki/Romanoff%27s' },
{ name: 'Frank Sinatra', era: '1940s-1962', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Romanoff%27s' },
],
},
{
name: 'Brown Derby',
cuisine: 'American',
address: '1628 N Vine St', city: 'Los Angeles', zip: '90028',
lat: 34.1015000, lng: -118.3267000,
opened: 1929, closed: 1985,
blurb: 'Hat-shaped Hollywood landmark. Where the Cobb salad was invented and the studio system ate lunch. Closed 1985.',
source_url: 'https://en.wikipedia.org/wiki/Brown_Derby',
patrons: [
{ name: 'Clark Gable', era: '1930s-1940s', notes: 'Proposed to Carole Lombard here in 1939', tier: 'C', source: 'https://en.wikipedia.org/wiki/Brown_Derby' },
{ name: 'Lucille Ball', era: '1940s-1950s', notes: null, tier: 'C', source: 'https://en.wikipedia.org/wiki/Brown_Derby' },
],
},
{
name: 'Schwab\'s Pharmacy',
cuisine: 'Diner · Soda Fountain',
address: '8024 Sunset Blvd', city: 'Los Angeles', zip: '90046',
lat: 34.0961000, lng: -118.3690000,
opened: 1932, closed: 1983,
blurb: 'The legendary Sunset Strip drugstore-and-soda-fountain where Lana Turner was supposedly discovered. Closed 1983; the site is now a parking structure.',
source_url: 'https://en.wikipedia.org/wiki/Schwab%27s_Pharmacy',
patrons: [
{ name: 'Lana Turner', era: '1937', notes: 'Per Hollywood myth, discovered at the soda fountain at 16. (She was actually at the Top Hat Café across the street, but the legend stuck.)', tier: 'C', source: 'https://en.wikipedia.org/wiki/Schwab%27s_Pharmacy' },
{ name: 'F. Scott Fitzgerald', era: '1930s', notes: 'Suffered a heart attack here in 1940', tier: 'C', source: 'https://en.wikipedia.org/wiki/Schwab%27s_Pharmacy' },
],
},
{
name: 'Sunset Tower Hotel',
cuisine: 'Hotel · Restaurant',
address: '8358 Sunset Blvd', city: 'Los Angeles', zip: '90069',
lat: 34.0964667, lng: -118.3771444,
opened: 1929, closed: null,
blurb: 'Art Deco icon on the Strip. Marilyn Monroe lived in apartment 1937; Howard Hughes used the penthouse. Restored 2005.',
source_url: 'https://en.wikipedia.org/wiki/Sunset_Tower',
patrons: [
{ name: 'Marilyn Monroe', era: '1950s', notes: 'Lived in apartment 1937', tier: 'C', source: 'https://en.wikipedia.org/wiki/Sunset_Tower' },
{ name: 'Howard Hughes', era: '1940s', notes: 'Penthouse resident', tier: 'C', source: 'https://en.wikipedia.org/wiki/Sunset_Tower' },
],
},
{
name: 'Nobu Malibu',
cuisine: 'Japanese',
address: '22706 Pacific Coast Hwy', city: 'Malibu', zip: '90265',
lat: 34.0354722, lng: -118.6800278,
opened: 1999, closed: null,
blurb: 'Beachfront Nobu. Private-equity-tier paparazzi target since the 2000s; ranked by TMZ as the highest-paparazzi-density restaurant in LA.',
source_url: 'https://en.wikipedia.org/wiki/Nobu_Hotels',
patrons: [
{ name: 'Kim Kardashian', era: 'Modern', notes: null, tier: 'D', source: 'https://en.wikipedia.org/wiki/Nobu_Hotels' },
{ name: 'Drake', era: 'Modern', notes: null, tier: 'D', source: 'https://en.wikipedia.org/wiki/Nobu_Hotels' },
],
},
{
name: 'Catch LA',
cuisine: 'Seafood · Rooftop',
address: '8715 Melrose Ave', city: 'West Hollywood', zip: '90069',
lat: 34.0830833, lng: -118.3852222,
opened: 2016, closed: null,
blurb: 'Rooftop seafood with Hollywood-Hills sightline. Modern celebrity-spotting venue; opened 2016.',
source_url: null,
patrons: [
{ name: 'Justin Bieber', era: 'Modern', notes: null, tier: 'D', source: null },
{ name: 'Kendall Jenner', era: 'Modern', notes: null, tier: 'D', source: null },
],
},
{
name: "Cecconi's West Hollywood",
cuisine: 'Italian',
address: '8764 Melrose Ave', city: 'West Hollywood', zip: '90069',
lat: 34.0828611, lng: -118.3856944,
opened: 2009, closed: null,
blurb: 'Italian-Mediterranean room at Robertson + Melrose. Modern industry lunch room.',
source_url: null,
patrons: [
{ name: 'Robert Downey Jr.', era: 'Modern', notes: null, tier: 'D', source: null },
],
},
];
(async () => {
let restCount = 0, sightCount = 0;
for (const r of RESTAURANTS) {
const slug = slugify(r.name);
await pool.query(
`INSERT INTO restaurant
(slug, name, cuisine, address, city, state, zip, lat, lng,
opened_year, closed_year, blurb, source_url, updated_at)
VALUES ($1,$2,$3,$4,$5,'CA',$6,$7,$8,$9,$10,$11,$12, now())
ON CONFLICT (slug) DO UPDATE SET
name=EXCLUDED.name, cuisine=EXCLUDED.cuisine, address=EXCLUDED.address,
city=EXCLUDED.city, zip=EXCLUDED.zip, lat=EXCLUDED.lat, lng=EXCLUDED.lng,
opened_year=EXCLUDED.opened_year, closed_year=EXCLUDED.closed_year,
blurb=EXCLUDED.blurb, source_url=EXCLUDED.source_url, updated_at=now()`,
[slug, r.name, r.cuisine, r.address, r.city, r.zip, r.lat, r.lng,
r.opened, r.closed, r.blurb, r.source_url]
);
const { rows: [{ id: restId }] } = await pool.query(
`SELECT id FROM restaurant WHERE slug = $1`, [slug]
);
// Sightings — link to entity if it exists, else just store the name
for (const p of r.patrons ?? []) {
const personSlug = slugify(p.name);
const e = await pool.query(`SELECT id FROM entity WHERE slug = $1`, [personSlug]);
const entityId = e.rows[0]?.id ?? null;
await pool.query(
`INSERT INTO restaurant_sighting
(restaurant_id, entity_id, person_name, era, notes,
source_tier, source_url, source_label, public_visible)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, true)
ON CONFLICT DO NOTHING`,
[restId, entityId, p.name, p.era, p.notes, p.tier, p.source,
p.source ? `Wikipedia · ${r.name}` : null]
);
sightCount++;
}
restCount++;
console.log(`OK ${r.name.padEnd(32)} · ${(r.patrons??[]).length} patrons · ${r.opened}${r.closed ? '–'+r.closed : '–present'}`);
}
console.log(`\n${restCount} restaurants, ${sightCount} sightings seeded`);
await pool.end();
})();