尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Calendario público y curado de inauguraciones de arte — automatizado con GitHub Actions + Claude API + Supabase.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗A free, curated calendar of contemporary art openings and exhibitions across Chile. Live at caldearte.com · Instagram @caldearte.oficial
Caldearte finds visual-art exhibitions, openings and artistic interventions in all 16 regions of Chile. It curates them against an explicit editorial policy and publishes them as a calendar, a weekly newsletter, and Instagram and Facebook carousels. Almost all of this is automated: GitHub Actions run the pipelines, Claude does the reading and judging, and Supabase stores the result. Two human curators set the editorial line and review what the machine does.
The site and its content are in Chilean Spanish. This README, the code and most of the docs are in English.
flowchart LR
subgraph Sources
A["~230 known web sources<br/>(museums, galleries, agendas)"]
B["~140 Instagram accounts<br/>(via Apify)"]
C["Google Alerts feed"]
D["Venue submissions<br/>(form on the site)"]
end
A & B & C --> P["Deterministic prefilters<br/>dates · dedup · account × category rules"]
P --> H["Claude Haiku 4.5<br/>scope · 5 sensitivity axes · institutional filter<br/>grounded extraction · image choice · sensitivity tags"]
H -- approved & new --> M["Second opinion (MiniMax M3)<br/>can veto an approval before insert"]
M --> DB[("Supabase<br/>Postgres + Storage")]
D -- curated with the same policy --> DB
DB --> W["caldearte.com<br/>Next.js on Vercel"]
DB --> S["Instagram + Facebook<br/>carousels (Sun/Tue/Thu/Fri ~19:30)"]
DB --> N["Weekly newsletter<br/>(Resend)"]
DB --> G["Daily digest<br/>for the curators"]
approved or rejected against the written policy. The same call extracts dates, venue and artists, and it must quote the source verbatim for each, so nothing gets invented. It also picks the image and tags sensitive content.The full operational policy is in docs/curation-policy.md, and its prompt-facing version is in packages/curation-policy. In short:
Scope. Visual-art exhibitions (painting, drawing, sculpture, printmaking, photography, installation and similar) and genuine artistic interventions, in a physical place in Chile.
Five sensitivity axes, excluded by default:
An event on one of these axes is included only if it takes an explicit, unambiguous critical stance. Neutral documentation or "exploring the topic" does not qualify.
Institutional filter. Places of worship, right-wing and far-right party headquarters, and police or military institutions are excluded as venues, whatever they show.
Sensitive but included. Nudity, denunciations of violence, and memory and dictatorship themes stay in the calendar but are tagged. Their images are blurred by default, and a "family mode" hides them entirely.
These are editorial decisions made by the two curators. Changes to the policy require human review and are never made automatically.
Each of these came from a real incident, documented in docs/:
cookies() read pushed the site to 94% of a monthly hosting limit. GitHub's scheduled workflows drift and sometimes don't fire, so a watchdog re-dispatches overdue jobs.| Path | What it is |
|---|---|
apps/web | The public site, admin mode and API routes (Next.js App Router, deployed on Vercel). Includes the flyer renderer used for social posts. |
apps/curator | Every scheduled pipeline: event discovery (web, headless browser, Instagram, Google Alerts), social publishing, newsletter, daily digest, Instagram insights, Apify usage snapshots, and the weekly security audit. |
packages/curation-policy | The curation policy as code: prompt text, URL safety checks, the vision check. |
packages/shared-types | Generated Supabase database types shared by both apps. |
supabase/migrations | The database schema, including the seed of all 346 Chilean comunas. Every merge to main that touches this folder is applied to production by CI. |
supabase/functions | Edge Functions: newsletter confirm/unsubscribe, venue submissions, admin actions and analytics. |
.github/workflows | Cron jobs, the migration deploy, the cron watchdog and the security audit. |
docs | Design docs and decision logs (see Documentation). |
All times are UTC (Chile is UTC−3 or UTC−4).
| Workflow | When | What it does |
|---|---|---|
event-discovery.yml | Sun & Wed 06:07 | Bright-source discovery and curation |
headless-bright-sources.yml | Sun & Wed 07:12 | Sources that need a real browser |
instagram-bright-sources.yml | Mon–Sat 08:17 | Instagram discovery via Apify |
google-alerts-bright-source.yml | Sun 09:22 | Google Alerts feed |
weekly-newsletter.yml | Sun 10:27 | Weekly digest to subscribers, per region |
publish-social.yml | Sun, Tue, Thu, Fri — starts ~11:30, waits until 19:30 Santiago | Instagram and Facebook carousels about the next day(s) |
daily-digest.yml | Daily 10:30 | Summary email for the curators |
apify-usage-snapshot.yml | Daily 09:33 | Records Apify usage against the free tier |
instagram-insights.yml | Mon 20:45 | Snapshot of the account's own metrics |
security-audit.yml | Tue 13:20 | Secret/PII scan of tracked files + pnpm audit |
cron-watchdog.yml | Every 4 h | Re-dispatches any of the above that is overdue |
deploy-migrations.yml | On push to main | supabase db push to production when migrations change |
Minutes are off the hour on purpose: GitHub's scheduler is congested at :00.
api_usage_log.next/og.AI spend over the last 30 days (October 2026) was about US$10. Everything else runs on free tiers. The cost policy, the budget ceiling and how they're enforced are in docs/architecture.md and docs/region-discovery.md.
Requirements: Node.js 22+, pnpm 10 (corepack enable), Docker and the Supabase CLI.
pnpm install
supabase start # local Postgres with every migration applied
pnpm dev # the site on http://localhost:3000
pnpm test # unit tests for every workspace
supabase start prints a local API URL and anon key. Put them in apps/web/.env.local (never committed):
| Variable | Used by | Purpose |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY | web | Read the public views |
SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY | curator, web (server) | Pipeline writes, admin actions |
ANTHROPIC_API_KEY | curator, web | Curation (pipelines and venue submissions), newsletter intros |
OPENROUTER_API_KEY | curator | Second-opinion model |
APIFY_TOKEN | curator | Instagram scraping |
RESEND_API_KEY | curator, web | |
INSTAGRAM_*, FACEBOOK_* | curator | Social publishing (optional) |
AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET, ADMIN_EMAIL | web | Admin sign-in (optional) |
Each pipeline is also a script in apps/curator/package.json, for example pnpm --filter @caldearte/curator discover-events. Run them against your local database, not production. Social publishing supports DRY_RUN=true.
| Doc | Covers |
|---|---|
docs/overview.md | Vision, scope, what counts as a valid event, content sensitivity |
docs/curation-policy.md | The editorial policy, axis by axis, with real cases |
docs/architecture.md | Stack, admin mode, caching, SEO, free-tier incidents, cron watchdog |
docs/data-model.md | Every table, row-level security, where secrets live |
docs/region-discovery.md | Discovery pipelines, sources, prompts, audits and cost governance: the long, detailed decision log |
docs/roadmap.md | Phases, status and what's next |
docs/risks.md | Known risks and what was done about them |
docs/personas.md | Who the site is for |
The docs are working logs as much as specifications. They keep the reasoning and the dead ends, not just the final state.
Please report vulnerabilities privately through GitHub's private vulnerability reporting, not in a public issue. See SECURITY.md.
This is a small, two-person project. Code contributions aren't being accepted for now, but bug reports through issues are welcome.
Copyright © 2026 Caldearte. All rights reserved.
The source is public for transparency and reference: anyone can read how the calendar is built and curated. No license is granted to copy, modify or redistribute it. For any other use, get in touch through the site.