Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/components/event-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export function AllYouNeedToKnowSection({
<MapPinIcon className="h-10 w-10 sm:h-12 sm:w-12 text-primary flex-shrink-0 mt-1 lg:mt-0" />
<div className="min-w-0 flex-1">
<h3 className="text-lg sm:text-xl lg:text-2xl xl:text-3xl font-medium leading-tight">
{event.shortLocation}
{event.shortLocation || "Location details on Luma"}
</h3>
<p className="text-sm sm:text-base lg:text-lg xl:text-xl text-muted-foreground mt-1 break-words">
{event.streetAddress || event.shortLocation}
Expand Down
8 changes: 7 additions & 1 deletion app/src/lib/luma/public-calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { TZDate } from "@date-fns/tz";

export const ALL_THINGS_WEB_CALENDAR_ID = "cal-3AAimKnRVQEId4r";
const CALENDAR_TIMEZONE = "America/Los_Angeles";
export const LUMA_LOCATION_PLACEHOLDER_PATTERN =
"^https?://(www[.])?(luma[.]com|lu[.]ma)/event/evt-[A-Za-z0-9]+/?([?#].*)?$";
const locationPlaceholder = new RegExp(LUMA_LOCATION_PLACEHOLDER_PATTERN, "i");

export type PublicLumaEvent = {
lumaEventId: string;
Expand Down Expand Up @@ -89,7 +92,10 @@ export function parsePublicLumaCalendar(text: string): PublicLumaEvent[] {
name: event.summary.trim(),
startDate,
endDate,
location: event.location?.trim() || null,
location:
event.location && !locationPlaceholder.test(event.location.trim())
? event.location.trim() || null
: null,
isDraft,
},
sequence: event.sequence,
Expand Down
13 changes: 10 additions & 3 deletions app/src/lib/luma/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { sql } from "drizzle-orm";
import type { PgDatabase, PgQueryResultHKT } from "drizzle-orm/pg-core";
import { eventsTable } from "@/lib/schema";
import { fetchPublicLumaEvents, type PublicLumaEvent } from "./public-calendar";
import { mergeVenueField } from "./venue-recovery";

function eventSlug(event: PublicLumaEvent): string {
const date = new TZDate(event.startDate, "America/Los_Angeles");
Expand Down Expand Up @@ -52,9 +53,15 @@ export async function syncPublicLumaEvents(
startDate: sql`excluded.start_date`,
endDate: sql`excluded.end_date`,
isDraft: sql`excluded.is_draft`,
streetAddress: sql`coalesce(excluded.street_address, ${eventsTable.streetAddress})`,
shortLocation: sql`coalesce(excluded.short_location, ${eventsTable.shortLocation})`,
fullAddress: sql`coalesce(excluded.full_address, ${eventsTable.fullAddress})`,
streetAddress: mergeVenueField(
"streetAddress",
sql`excluded.street_address`,
),
shortLocation: mergeVenueField(
"shortLocation",
sql`excluded.short_location`,
),
fullAddress: mergeVenueField("fullAddress", sql`excluded.full_address`),
},
})
.returning({ slug: eventsTable.slug, isDraft: eventsTable.isDraft });
Expand Down
26 changes: 26 additions & 0 deletions app/src/lib/luma/venue-archive.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"lumaEventId": "evt-deGtRGSvYsWMqAc",
"streetAddress": "444 De Haro St #218",
"shortLocation": "Convex HQ",
"fullAddress": "444 De Haro St #218, San Francisco, CA 94107, USA"
},
{
"lumaEventId": "evt-7CaqG4UZsbIQb6s",
"streetAddress": "100 1st St #2400",
"shortLocation": "Vercel HQ",
"fullAddress": "100 First Plaza, 100 1st St #2400, San Francisco, CA 94105"
},
{
"lumaEventId": "evt-dbF3WPClKyxWQ7n",
"streetAddress": "45 Fremont St",
"shortLocation": "Sentry, SF",
"fullAddress": "45 Fremont St, San Francisco, CA 94105"
},
{
"lumaEventId": "evt-HtDmTqndK1vA1Z4",
"streetAddress": "500 Terry A Francois Blvd",
"shortLocation": "Meraki HQ",
"fullAddress": "Cisco Meraki, 500 Terry A Francois Blvd, San Francisco, CA 94158"
}
]
22 changes: 22 additions & 0 deletions app/src/lib/luma/venue-recovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { sql, type SQL } from "drizzle-orm";
import { eventsTable } from "@/lib/schema";
import { LUMA_LOCATION_PLACEHOLDER_PATTERN } from "./public-calendar";
import archivedVenues from "./venue-archive.json";

type VenueField = "streetAddress" | "shortLocation" | "fullAddress";

// Recover only placeholder values overwritten by the first public-feed sync.
// The archive contains public venue data captured before that sync on 2026-09-16.
export function mergeVenueField(field: VenueField, incoming: SQL): SQL {
const archivedValue = sql`case ${eventsTable.lumaEventId} ${sql.join(
archivedVenues.map(
(venue) => sql`when ${venue.lumaEventId} then ${venue[field]}`,
),
sql` `,
)} else null end`;
return sql`coalesce(${incoming}, case
when ${eventsTable[field]} ~* ${LUMA_LOCATION_PLACEHOLDER_PATTERN}
then ${archivedValue}
else ${eventsTable[field]}
end)`;
}
109 changes: 109 additions & 0 deletions app/tests/luma-sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,24 @@ describe("public Luma calendar", () => {
expect(rows[0].name).toBe("Updated title");
});

test("ignores Luma event-page location placeholders but keeps online venues", () => {
for (const location of [
"https://luma.com/event/evt-test",
"https://lu.ma/event/evt-test/",
"HTTPS://WWW.LUMA.COM/event/evt-test?ref=calendar",
]) {
const input = event().replace("Sentry\\, San Francisco", location);
expect(parsePublicLumaCalendar(calendar(input))[0].location).toBeNull();
}
const online = event().replace(
"Sentry\\, San Francisco",
"https://zoom.us/j/123",
);
expect(parsePublicLumaCalendar(calendar(online))[0].location).toBe(
"https://zoom.us/j/123",
);
});

test("withholds private and cancelled entries regardless of value casing", () => {
for (const property of [
"STATUS:cancelled",
Expand Down Expand Up @@ -342,4 +360,95 @@ describe("Luma synchronization against Postgres", () => {
expect(updated.isDraft).toBe(true);
expect(updated.recordingUrl).toBe(original.recordingUrl);
});

test("missing public venue details preserve a useful stored venue", async () => {
const [original] = await db
.insert(eventsTable)
.values({
...seed,
streetAddress: "500 Terry A Francois Blvd",
shortLocation: "Meraki HQ",
fullAddress: "Cisco Meraki, San Francisco",
})
.returning();
respond(
calendar(
event().replace(
"Sentry\\, San Francisco",
"https://luma.com/event/evt-test",
),
),
);
await syncPublicLumaEvents(db);
const [updated] = await db.select().from(eventsTable);
expect(updated.streetAddress).toBe(original.streetAddress);
expect(updated.shortLocation).toBe(original.shortLocation);
expect(updated.fullAddress).toBe(original.fullAddress);
});

test("recovers archived venue fields once, preserves later edits, and accepts genuine Luma venue updates", async () => {
const id = "evt-HtDmTqndK1vA1Z4";
const placeholder = `https://luma.com/event/${id}`;
const [original] = await db
.insert(eventsTable)
.values({
...seed,
lumaEventId: id,
streetAddress: placeholder,
shortLocation: placeholder,
fullAddress: placeholder,
})
.returning();
respond(
calendar(event(id).replace("Sentry\\, San Francisco", placeholder)),
);
await syncPublicLumaEvents(db);
const [recovered] = await db.select().from(eventsTable);
expect(recovered.id).toBe(original.id);
expect(recovered.streetAddress).toBe("500 Terry A Francois Blvd");
expect(recovered.shortLocation).toBe("Meraki HQ");
expect(recovered.fullAddress).toBe(
"Cisco Meraki, 500 Terry A Francois Blvd, San Francisco, CA 94158",
);
await syncPublicLumaEvents(db);
const [repeated] = await db.select().from(eventsTable);
expect(repeated.streetAddress).toBe(recovered.streetAddress);
await db.update(eventsTable).set({ shortLocation: "Edited venue label" });
await syncPublicLumaEvents(db);
expect((await db.select().from(eventsTable))[0].shortLocation).toBe(
"Edited venue label",
);
respond(calendar(event(id)));
await syncPublicLumaEvents(db);
expect((await db.select().from(eventsTable))[0].fullAddress).toBe(
"Sentry, San Francisco",
);
});

test("clears unrecoverable placeholders and imports unknown venues without inventing an address", async () => {
await db.insert(eventsTable).values({
...seed,
streetAddress: "https://lu.ma/event/evt-test",
shortLocation: "https://lu.ma/event/evt-test",
fullAddress: "https://lu.ma/event/evt-test",
});
respond(
calendar(
...["evt-test", "evt-new"].map((id) =>
event(id).replace(
"Sentry\\, San Francisco",
`https://luma.com/event/${id}`,
),
),
),
);
await syncPublicLumaEvents(db);
const rows = await db.select().from(eventsTable);
expect(rows).toHaveLength(2);
for (const row of rows) {
expect(row.streetAddress).toBeNull();
expect(row.shortLocation).toBeNull();
expect(row.fullAddress).toBeNull();
}
});
});
Loading