Current boundary
The Pub scheduler, tenders, shifts, assignments, submissions, and announcements have moved from Notion to D1. Notion remains the source for events only. The retired database schemas below are historical reference; do not recreate them for a current deployment.
Current event source
- The worker reads events from Notion via
NOTION_DATABASE_ID - All other data (tenders, shifts, assignments, announcements) now lives in D1 and is managed through the admin UI at
/admin - If
NOTION_API_KEYis not configured,/api/eventsfalls back to placeholder data instead of live Notion results
Sources: worker.js (CONFIG section), wrangler.toml
Credentials
wrangler secret put NOTION_API_KEYThe integration token must have read access to every database the worker touches.
Retired tender QR write-back
The Notion QR write-back route has been removed now that tenders are D1-native. Do not configure the retired NOTION_QR_SYNC_API_KEY or TENDER_QR_SYNC_TOKEN, and do not call /api/sync-tender-qrs.
Current tender QR state lives in CONTENT_DB.pub_tenders (qr_r2, qr_link, and the legacy Short.io link id where present). The TV receives a same-origin URL under /api/image/tender-qr/:id; existing printed Short.io redirects continue to work independently.
Events database (NOTION_DATABASE_ID)
Drives both todayEvents and weekEvents in the API response.
Required properties
| Notion property | Type | Notes |
|---|---|---|
Name | Title | Event name |
Event Start | Date | Start date/time, ideally with timezone |
Event End | Date | End date/time, optional but recommended |
Include on Pub TV | Checkbox | Must be checked for the event to appear |
Optional properties
| Notion property | Type | Notes |
|---|---|---|
Location | Rich text or Select | Displayed inline with the time on the TV and iPad board. No longer used for filtering — any location value (or none) is fine. |
Duration (hrs) | Number | Used to estimate end time if Event End is not set |
Source Email Subject | Rich text | Scanned for RC-Direct or RC-Affiliate substrings |
TV include gate
The
Include on Pub TVcheckbox is the sole gate. Location is no longer required to contain"pub"— events at any location can appear on the display.
Sources: worker.js (PROP_TV_INCLUDE, PROP_SOURCE_EMAIL_SUBJECT, PROP_LOCATION)
Historical scheduler databases
Shifts database (NOTION_SHIFTS_DATABASE_ID)
This database formerly drove the Pub-tender footer and weekly hours grid. The current deployment sets CONTENT_SOURCE_SHIFTS=d1; the Worker retains this Notion path for migration history and explicit fallback modes.
Required properties
| Notion property | Type | Notes |
|---|---|---|
Date/Time | Date with end | Full shift window including setup and cleanup |
Not in Pub | Checkbox | If checked, the shift is excluded from the pub display |
Optional properties
| Notion property | Type | Notes |
|---|---|---|
Operational Timeframe | Date with end | Narrower serving window used for hours display and footer state |
Last Call | Number | Minutes before operational end to enter the last-call state |
Shift Status | Select or Status | Informational only; not currently used in rendering |
Assignments DB | Relation | Links shifts to assignment rows |
Shift state logic
Full shift window: |------------------------------------|
Operational timeframe: |----------------------|
Last call window: |---|
setup active last-call closedSources: worker.js (fetchPubTenderFromNotion, deriveShiftNote)
Assignments relation
The Shifts DB links to an Assignments DB via the Assignments DB relation. Each assignment row links to individual Pub Tender pages via the Pub Tenders DB relation.
flowchart LR SHIFT["Shifts DB page"] -- "Assignments DB" --> ASSIGN["Assignment page"] ASSIGN -- "Pub Tenders DB" --> TENDER["Pub Tender page"] TENDER -- "Name (always)" --> FOOTER["TV footer"] TENDER -- "Picture / QR when opted in" --> SLIDE["TV tender slide"]
Sources: worker.js (fetchTenderInfoFromAssignment, fetchTenderInfoFromAssignmentPage)
Pub Tender database (NOTION_PUB_TENDERS_DATABASE_ID)
This optional variable formerly pointed directly at the tender directory database used by GET /api/tenders.
In Notion mode, the Worker can discover that database by following:
Shifts DB -> Assignments DB -> Pub Tenders DB
The current deployment sets CONTENT_SOURCE_TENDERS=d1; it does not use this discovery path for live tender data.
Required properties
| Notion property | Type | Notes |
|---|---|---|
Name | Title | Tender’s full display name |
Active | Checkbox | Must be checked for the tender to appear in /api/tenders and /tenders/ |
Optional properties
| Notion property | Type | Notes |
|---|---|---|
Tender ID | Text / Unique ID / Rich text | Required for stable /tenders/?tender=<id> links and automated QR sync |
Bio | Rich text | Used in the directory modal on /tenders/ |
Picture | Files and media | Used in both the directory and TV tender slides |
Meet your Tender | Checkbox | Must be checked for the tender to appear in TV tender slides |
QR | Files and media | Pre-rendered QR image shown on TV tender slides |
Zelle | Rich text / URL / Phone / Email | Used by the /tenders/ modal payment button |
Venmo | Rich text / URL | Used by the /tenders/ modal payment button |
QR Link | URL / Rich text | Written by the QR sync flow when available |
Short.io Link ID | Rich text / Text | Written by the QR sync flow when available |
Page URL | URL | General profile URL metadata |
URL | URL | Alternate URL metadata |
Link | URL | Alternate URL metadata |
Historical property behavior
| Property | Used by | Current behavior |
|---|---|---|
Active | /api/tenders | Gates directory inclusion |
Meet your Tender | /api/events → TV slides | Gates whether the tender becomes a TV profile slide |
Tender ID | /tenders/?tender=<id>, QR sync | Canonical id for deep links and Short.io slug generation |
Bio | /api/tenders | Shown in the /tenders/ modal |
Picture | Both | Used in the directory and TV |
QR | TV slides, QR sync | TV reads only the QR image file; QR sync writes the SVG here |
Zelle | /tenders/ modal | Frontend converts email to mailto: and phone-like values to tel: |
Venmo | /tenders/ modal | Frontend accepts either a full Venmo URL or an @handle-style value |
PayPal / Paypal / PayPal URL / Paypal URL | /tenders/ modal | Frontend accepts a full PayPal URL or a PayPal handle-style value |
QR Link / Short.io Link ID | QR sync | Used to track or update existing Short.io links |
Page URL / QR Link / URL / Link | Directory metadata | Used to resolve pageUrl on tender objects |
Current QR behavior on TV
The Notion properties above are historical. The current TV renders the D1-backed
qrImageUrlserved from/api/image/tender-qr/:id; there is no Notion QR write-back endpoint.
Meet your Tender gate
If
Meet your Tenderis unchecked, the tender can still appear in/tenders/ifActiveis checked and can still appear by first name in the TV footer if assigned to the active shift. The checkbox only gates the TV profile slide.
Property name casing
The
Meet your Tendercheckbox lookup is case-insensitive.
Sources: worker.js (fetchTenderInfoFromAssignmentPage, transformTenderDirectoryPage, extractUrlPropertyByNames)
Announcements database (NOTION_ANNOUNCEMENTS_DATABASE_ID)
This database formerly drove TV announcement slides and /announcements/. The current deployment sets CONTENT_SOURCE_ANNOUNCEMENTS=d1.
Required properties
| Notion property | Type | Notes |
|---|---|---|
Name | Title | Fallback announcement text if Content is empty |
Include on Pub TV | Checkbox | Must be checked for the announcement to be returned |
Optional properties
| Notion property | Type | Notes |
|---|---|---|
Content | Rich text | Preferred announcement text source |
Priority | Select | Optional styling hint; currently used for high slides |
Duration | Number | Optional slide duration in seconds |
Picture / Image / PNG | Files and media | Optional announcement image used by both /tv/ and /announcements/ |
No date filtering
Announcements are not currently filtered by date. Archive or remove stale rows to keep the display clean.
Announcement image routing
The worker rewrites announcement images to same-origin
/api/image/announcement/:pageIdURLs before handing them to the frontend. This helps embedded TV browsers handle the images more reliably.
Sources: worker.js (fetchAnnouncementsFromNotion)
Current content-source configuration
[vars]
NOTION_DATABASE_ID = "<32-char hex ID from Events DB URL>"
CONTENT_SOURCE_EVENTS = "notion"
CONTENT_SOURCE_SHIFTS = "d1"
CONTENT_SOURCE_TENDERS = "d1"
CONTENT_SOURCE_ANNOUNCEMENTS = "d1"The event database id is the 32-character hex string in its Notion URL before the ? query string. Legacy Notion database variables remain in the current repository for compatibility, but a current deployment should follow the CONTENT_SOURCE_* switches rather than treating those bindings as live sources.