Public content feed for the Khal Zidichov Chodorov shul app. The app reads
the bulletin and calendar PDFs from this repo over raw.githubusercontent.com.
This repo is the A→B bridge of the publishing pipeline:
Office Bulletin Maker ──▶ Publish tool ──PUT (GitHub API)──▶ THIS REPO ──raw──▶ App
Why GitHub raw (not Netlify / *.github.io): raw.githubusercontent.com passes the
shul's content-filter VPN on-device; *.github.io is unreliable per-subdomain and
Netlify production deploys cost credits. (Architecture approved Jun 2026.)
/bulletins/<file>.(pdf|png|jpg) weekly/periodic bulletins — PDF *or* image
/calendars/<file>.(pdf|png|jpg) monthly calendars — PDF *or* image
/manifest.json pointer to the CURRENT bulletin + calendar
/events.json OPTIONAL one-off events (array; missing = none)
/schedule.json OPTIONAL davening schedule (overrides baked; missing = baked)
Both PDFs and images (PNG/JPG) are supported — the office often produces a
calendar as a single image. The renderer decides how to display by the file
extension in manifest.json (.pdf → PDF viewer; .png/.jpg → image view),
so always keep the extension on file.
Old files may stay in the folders for history; the app only reads whatever
manifest.json points at.
The app fetches only this file first, then downloads the files it names. It's
dual-key: a bulletins[] feed (newest first) and a legacy single bulletin
(= the latest), so both new feed readers and old single-bulletin readers work.
{
"bulletins": [
{ "file": "bulletins/bulletin-2026-06-13.pdf", "date": "2026-06-13", "title": "Parshas Shelach" },
{ "file": "bulletins/bulletin-2026-06-06.pdf", "date": "2026-06-06", "title": "Parshas Beha'aloscha" }
],
"bulletin": { "file": "bulletins/bulletin-2026-06-13.pdf", "date": "2026-06-13", "title": "Parshas Shelach" },
"calendar": { "file": "calendars/june-calendar-2026.png", "month": "2026-06" },
"updated": "2026-06-13T15:04:00.000Z"
}| Field | Meaning |
|---|---|
bulletins[] |
full bulletin feed, newest first; each {file, date, title?} |
bulletin |
legacy single = bulletins[0] (the latest), same shape |
*.file |
repo-relative path to the file (PDF or image) |
*.date |
bulletin issue date, YYYY-MM-DD |
*.title |
optional bulletin parsha/name |
calendar.file |
repo-relative path to the current calendar (PDF or image) |
calendar.month |
calendar month, YYYY-MM |
updated |
ISO 8601 timestamp of the last publish |
The file extension on
filetells the app whether to render it as a PDF or an image — keep it accurate. The publish tool maintainsbulletins[]+bulletintogether (append, re-sort newest-first, update the legacy key) — never hand-edit.
An empty/absent feed means "none published yet" — the app shows its last cached copy, or an empty state.
A flat array of one-off events the app's native agenda calendar shows alongside the auto-generated recurring davening. Optional — a missing or empty file is fine.
[
{ "date": "2026-06-19", "title": "Hachnasas Sefer Torah", "time": "7:30 PM", "type": "special" },
{ "date": "2026-07-04", "title": "Avos u'Banim resumes" }
]date (YYYY-MM-DD) and title are required; time and type are optional. The
recurring weekly davening is generated by the app and needs nothing here.
The authoritative weekly davening doc. The app ships a baked schedule as the offline
fallback; when schedule.json is present it overrides that (feeding the agenda,
the schedule screen, and the home "Up next" card). Published whole-document (replace,
not mutate).
{
"version": 1,
"updated": "<ISO-8601>",
"sections": [
{ "tefillah": "shacharis", "hebrew": "שחרית", "rows": [
{ "time": "6:45 AM", "days": "Mon-Fri", "location": "Main Bais Medrash" }
]},
{ "tefillah": "mincha", "hebrew": "מנחה", "rows": [
{ "zman": "shkia", "offsetMin": -10, "days": "Sun-Thu", "location": "Main Bais Medrash" }
]}
]
}A row is either wall-clock ("time": "H:MM AM/PM") or zman-relative
("zman": "shkia" + signed "offsetMin") — never both. "days" is one day
(Sun..Sat) or a hyphen range (Sun-Thu, may wrap Sat→Sun). Zman→clock resolution
is done app-side (kosher_dart).
https://raw.githubusercontent.com/Turetsky/khalzc-content/main/
e.g. the manifest is at
https://raw.githubusercontent.com/Turetsky/khalzc-content/main/manifest.json.
Note:
raw.githubusercontent.comcaches for ~5 min (CDN). A publish appears in the app within a few minutes, not instantly.
Use the Publish to App tool (web/publish.html in the app repo). It commits
the PDF and rewrites manifest.json via the GitHub Contents API using a
fine-grained token scoped to this repo (Contents: Read & write). Do not commit any
token to this repo.
Owner note: this repo is currently under the Turetsky account and is
transferable to officekhalzc later — update the fetch base + the publish tool's
OWNER constant if it moves.