Skip to content

feat: catalog api#63

Open
sorodrigo wants to merge 20 commits into
mainfrom
feat/catalog-api
Open

feat: catalog api#63
sorodrigo wants to merge 20 commits into
mainfrom
feat/catalog-api

Conversation

@sorodrigo

@sorodrigo sorodrigo commented Jun 30, 2026

Copy link
Copy Markdown
Member

feat: convention-driven catalog API (replaces /meta)

Summary

Replaces the hand-curated metadata layer with a convention-driven catalog derived from ixmp4 variable names, served by a new Hono/Cloudflare-Workers + D1 API in api/. The old /meta god-endpoint is gone — the catalog is split into cost-scoped slices (/geographies, /catalog, curation) that load only on the pages that use them.

What changed

API (api/) — four layers, edges-do-I/O, core-is-pure:

  • routes/* thin HTTP adapters → views/* per-chart resolvers (impact-time, scenarios, unavoidable-risk) → conventions.ts/tabulate.ts/util.ts (pure language) → platform.ts/instances.ts (ixmp4 connection).
  • Geographies come from D1 (Drizzle); indicators + scenarios are derived live from the ixmp4 variable-name convention (Indicator | Period | Temporal | Spatial | Value) — no curation.

Endpoints (no more /meta):

  • /geographies (+ /geographies/types) — selectable place tree (D1, cheap)
  • /catalog — indicators + parameter dimensions + scenario universe (the expensive ixmp4 scan)
  • /study-locations, /likelihoods — transitional curation
  • /impact-time, /scenarios, /indicators, /tags, /unavoidable-risk (stub)

Frontend — the data slices load per section (impacts, adaptation, methodology/key-terms, embed, and the landing quick-start), not on the global layout, so static pages no longer pay for the ixmp4 scan. Stores read $page.data.geographies / .catalog / .curation via loadGeographies / loadCatalog / loadCuration.

DB migrations — adds 0002_past_blink.sql (geo_id column on geographies, ISO3 for countries) bridging the name-based catalog to map geo-shapes. Local + remote provide-catalog D1 have been migrated through 0002 and reseeded.

Running locally

Prereqs: Node, Bun, and Wrangler (npm i -g wrangler or via npx). Then npm install.

1. Environment files

cp .env.example .env            # frontend (Vite) vars — see table below
cp .dev.vars.example .dev.vars  # API secrets (ixmp4 creds)

2. Set up the local D1 (new — required)

npm run db:migrate   # applies 0000→0002 to local provide-catalog (creates geo_id column)
npm run db:seed      # imports geographies + ISO3 geoIds, then loads api/db/seed.sql

3. Run the API (pick one)

  • Workers runtime (recommended, matches prod): npm run dev:api → Wrangler on :8787, local D1. Set VITE_API_URL=http://localhost:8787/api.
  • Bun runtime: npm run dev:api:nodeserver.ts on :8080 (uses bun:sqlite, auto-applies migrations on boot, reads .dev.vars). Set VITE_API_URL=http://localhost:8080/api.

4. Run the frontend

npm run dev          # Vite (mode=staging) on :5173

5. Tests

npm test             # bun test api/  (routes + pure view/convention functions)
npx svelte-check     # frontend type/markup check

Environment variables

Frontend (.env)

Var Purpose
VITE_API_URL New catalog API base — point at the runtime you chose (http://localhost:8787/api for Wrangler, :8080 for Bun). What the catalog/geographies/scenarios calls hit.
VITE_DATA_API_URL Legacy Climate Analytics API (impact-time, unavoidable-risk, geo-shape, avoiding-*) — still used.
VITE_HEROKU_URL Strapi CMS base (editorial indicator/scenario descriptions).
VITE_STRAPI_LOCALE Strapi content locale (en).
VITE_MAPBOX_STYLE_*, VITE_APP_URL Mapbox styles / app URL for the map + embed views (set if exercising maps).

API secrets (.dev.vars) — consumed by the Worker / server.ts

Var Purpose
IXMP4_USERNAME / IXMP4_PASSWORD Credentials for the ixmp4 provide-internal instance the catalog reads from.

The D1 binding (provide-catalog, binding: DB) lives in wrangler.jsonc; migrations_dir is ./api/db/migrations.

Notes / follow-ups

  • unavoidable-risk is a stub (ensemble data not yet on provide-internal); GMT band is an interim reuse of the chart's own region (no World region in ixmp4 yet).
  • Landing-page stories/caseStudies resolution is dead/legacy and slated for a separate cleanup.

sorodrigo and others added 13 commits April 6, 2026 22:58
…eat/catalog-api

* 'main' of https://github.com/upbeat-works/provide:
  Add Advanced Filters panel to indicator selection modal (#54)
  feat: add /projects/provide page (#53)
  feat: restyle html-content .btn links to match button design (#52)
  Add LinkSection to explore and avoid impact pages (#50)
  Merge Key concepts into Methodology as tabbed Key terms page (#41)
  Replace Lato with Geist font and update UI type styles (#46)
  feat: add avoid impacts CTA to explore page (#51)
  refactor: redesign footer as 3-column layout (#49)
  fix: align active border indicator styles across nav components (#48)
  Replace SVG grain filter with PNG texture and soft-light blend (#47)
  rename Explore label to Explorer (#45)
  rename: nav label to Case Studies, page hero title to Adaptation (#44)
  Surface reference context sentence in threshold-levels section (#39)
  restore indicator filters to avoid page (#38)
  remove sticky from contact page (#37)
@sorodrigo sorodrigo changed the title Feat/catalog api feat: catalog api Jun 30, 2026
@upbeat-works upbeat-works deleted a comment from cursor Bot Jun 30, 2026
…eat/catalog-api

* 'main' of https://github.com/upbeat-works/provide:
  fix: update hero background tiles SVG paths (#61)
  fix: remove sticky positioning from filters bar in PageLayout (#60)
  fix: correct typo in hero CTA button text (#59)
  refactor: extract scroll-spy logic into reusable createScrollSpy utility (#58)
  fix: prevent null CMS titles showing in case study side menu (#57)
  fix: apply theme-stronger colour to contact page heading (#56)
  fix height issues for modal with filtered list (#55)
* main:
  feat: use sqlite for cms
  feat: adds cms
…eat/catalog-api

# By Ed Brett (8) and Rodrigo Solís (1)
# Via GitHub
* 'main' of https://github.com/upbeat-works/provide:
  feat: add filter bar to case studies landing page (#71)
  feat: uppercase case study card titles, show topic tag only when present
  feat: rename Case Study Dynamic display name to Case Study
  revert: keep case-study-dynamic as-is to avoid losing production data
  feat: remove unused Strapi content types, rename Case Study Dynamic to Case Study
  fix: fall back to original image url for non-Cloudinary uploads (#68)
  feat: redesign case study city page (#67)
  feat: case studies landing page (#66)
  fix: cms content

# Conflicts:
#	src/lib/components/controls/ScenarioSelection/ScenarioList.svelte
#	src/routes/(default)/+page.server.js
#	src/routes/(default)/adaptation/+page.server.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants