The Worker needs a Notion integration token and an explicit database allowlist. The allowlist controls database selection in the admin interface; the Notion integration itself must also have access to each database.
Required page properties
Linked pages use fixed property names:
| Property | Type | Status options |
|---|---|---|
Voting Status | Status | Not started, In Voting, Done |
Results Link | URL | — |
Name | Title or rich text | — |
Description | Rich text or text | — |
Attachments | Files and media | — |
See Notion integration for which direction each property moves and the current route constraints.
1. Connect the integration
Create or select a Notion integration, then share each eligible database with it. Copy the integration token for NOTION_API_KEY.
Use actual Notion database ids in the allowlist. Names such as NOTION_DB_ID_ANY_VOTING are not variable references in this parser; if entered literally, the Worker sends that literal string to Notion as the database id.
2. Set Worker values
npx wrangler secret put NOTION_API_KEY
npx wrangler secret put NOTION_DATABASE_ALLOWLISTFor local development, put both values in .dev.vars and do not commit that file.
3. Format the allowlist
JSON is the clearest format:
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Council elections"
}
]name is optional; the Worker displays the id when it is absent.
The parser also accepts comma-separated id:name pairs:
a1b2c3d4-e5f6-7890-abcd-ef1234567890:Council electionsOr ids without display names:
a1b2c3d4-e5f6-7890-abcd-ef1234567890,11111111-2222-3333-4444-555555555555An empty or missing allowlist produces an empty database list.
4. Run locally
npm ci
npm run devOpen the new-election admin page and confirm the database selector is populated. The relevant JSON check is:
GET /admin/notion/databasesA configured response has this shape:
{
"databases": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Council elections"
}
]
}Then query a selected database:
GET /admin/notion/databases/:databaseId/pagesIf the first route works but page lookup fails, check that NOTION_API_KEY is available and the database has been shared with that integration.
5. Deploy
npm run deployAfter deployment, repeat the authenticated database and page checks against the production Worker before linking an election.
Current limits
- The allowlist parser checks configured ids but does not verify that a selected page’s parent matches the submitted database id during linking.
- Page search with
querytargets a property literally namedtitle; browsing without a query still discovers a title-type property for display. - Property names and status values are not configurable through the current routes.
Sources
Verified against ihnyc-rc-vote commit 2451aa1.
src/utils/notion.tssrc/routes/admin.tssrc/templates/admin-election-new.tsx.dev.vars.example