Skip to content

Latest commit

 

History

History
130 lines (103 loc) · 6.42 KB

File metadata and controls

130 lines (103 loc) · 6.42 KB

Cloudflare runtime configuration

Canonical repository reference for the API Worker, Pages gateway and D1 bindings. For commands, use local development or deployment.

Current resources

Purpose Name ID / URL
Active D1, binding DB studyplanner-db 80ca9092-ddc6-454a-b04a-8ccae85ef2f5
Previous test D1, not the active binding studyplaner-db-test 297f7a28-9069-431d-b989-49acf2537513
API Worker studyplanner-api https://studyplanner-api.ben-tischberger.workers.dev
MCP Worker studyplanner-mcp Reached through the Pages MCP service binding
Pages project studyplaner https://studyplaner.pages.dev

The production database cutover was approved on integrate_new_db. Do not switch the DB binding again, recreate either database, or treat the previous database as a routine deletion target.

Browser and gateway routing

Deployed browsers call same-origin /api/* on the Pages host. The Pages Function proxies those requests to the API Worker over HTTP (STUDYPLANNER_API_ORIGIN) so the studyplanner_session cookie is first-party. Safari/iOS blocks the cookie when the app on pages.dev talks to workers.dev directly. VITE_API_BASE_URL remains in Pages config only as a localhost Vite override; apiBaseUrl.ts ignores it on deployed hosts.

The source of truth is frontend/src/shared/utils/apiBaseUrl.ts:

  • On localhost/127.0.0.1, a non-empty VITE_API_BASE_URL overrides API routing; otherwise they use http://localhost:8787.
  • Deployed hosts always use same-origin /api/*, even if VITE_API_BASE_URL is set.

The checked Pages config includes a direct Worker URL as public build configuration. An actual build's environment determines whether that override is present; local Vite builds do not read Wrangler's [vars].

Pages Functions forward /api/* to the API and /mcp, /messages, /sse, /privacy and /app/catalog-results.html to MCP. In frontend/functions/_shared/proxy.ts an explicit STUDYPLANNER_API_ORIGIN or STUDYPLANNER_MCP_ORIGIN takes precedence over a service binding. The checked production API origin is the public API Worker; MCP uses its service binding. Local gateway fallback ports are 8787 and 8788.

Runtime guardrails

  • Keep backend/wrangler.toml at compatibility_date 2025-05-20 and entrypoint on_fetch. Raising the date requires a cold remote development check first; the previous attempted bump failed on every request. See the retained load-test investigation.
  • Run npm run db:verify-config before deploys or after Cloudflare config changes. The GitHub workflow runs this check and should be required on main.
  • D1 names and UUIDs are public config. AUTH_TOKEN_SECRET is a real secret. Use ignored backend/.dev.vars locally and a Worker secret in production.
  • Authentication uses HttpOnly cookies and CSRF protection. See authentication for session invalidation and deletion behavior.
  • Temporary diagnostics, feedback and stale rate-limit records are cleaned up during normal requests; no separate retention cron is required.

Catalog refresh

Refresh the existing production D1 in place with reviewed ALMA output, after the required approval/backup.

Adding or updating a semester (preferred): scrape only that semester and import it incrementally. Every other period is left untouched and verified:

cd data_collection
uv run python -m alma.cli --details --latest --out output\latest\courses_multi_semester.json
cd ..
python backend/scripts/import_alma_json_to_d1.py --input data_collection/output/latest/courses_multi_semester.json --incremental
python backend/scripts/import_alma_json_to_d1.py --input data_collection/output/latest/courses_multi_semester.json --incremental --apply

--latest scrapes only the newest semester ALMA lists, across the Informatik catalog and every degree program in PROGRAM_BRANCH_CHAINS. Without --apply the incremental run is a dry run (reads the D1, writes the SQL). It lists the courses added, removed, or changed (title, times, rooms, dates) against the D1; --skip-if-unchanged stops there when nothing changed. With --apply it replaces only the input's periods and keeps re-imported course, parallel-group and appointment ids (saved plans store hidden tutorial slots by appointment id), then compares a before/after snapshot and exits non-zero if any other period, reviews, or external links changed. Deploy the Worker afterwards so isolates drop cached catalog responses.

Full rebuild:

python backend/scripts/import_alma_json_to_d1.py --input <courses_multi_semester.json> --apply --skip-create --skip-swap --skip-migrate

Replace the input placeholder with the actual JSON path. Keep every period that must survive in the input: the full rebuild deletes and replaces all catalog rows. Read the importer docstring for remote-import limits and retry behavior.

Numeric courses.id values are reassigned during a full rebuild (an incremental import keeps existing ids). New user-generated records must use the stable ALMA course number, falling back to unit_id, following course_catalog.normalize_review_key(). Reviews and external links follow this rule and must remain outside SEEDED_TABLES_DELETE_ORDER. Existing legacy ID-based planner/favorite references require care when reseeding.

The tracked SQLite export is a local bootstrap source for catalog and curriculum tooling. Export it with --skip-schema so an existing migration is not rewritten; do not treat that dump as a current production backup.

Simulated semester

The app_settings key simulated_current_semester_label is returned by GET /api/config and read at frontend boot. The existing scripts target production:

npm run sim:status
npm run sim:on
npm run sim:off

sim:on sets SS 2025, making WS 2025/26 the upcoming winter semester. sim:off restores date-derived behavior. These settings affect all visitors after reload, without redeployment. This historical semester is a test fixture, not a claim about the latest available catalog.

To choose another simulated semester, change the value in the root package.json sim:on script to an SS <year> or WS <year>/<yy> label before running it. The setting is stored in app_settings as simulated_current_semester_label; migration 0025 introduced that table and the toggle. Returning visitors may need one page reload to pick up a change.