Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/algorithm-catalog-compact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Algorithm Catalog β€” compact request files

# Mirrors dse-hub-compact.yml. Submissions arrive as uniquely-named files under
# algorithm-catalog/data/requests/ (that uniqueness is what makes two people submitting at the same
# time conflict-free). Once merged, this folds them into the canonical data and deletes the folded
# files, so data/requests/ stays small no matter how many activations get filed.
#
# [skip ci] on the commit stops this push from re-triggering the validate workflow.

on:
push:
branches: [main]
paths:
- "algorithm-catalog/data/requests/**"
workflow_dispatch:

jobs:
compact:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "24"

- name: Apply requests and compact
run: node algorithm-catalog/scripts/compact.mjs

- name: Commit compacted canonicals (if changed)
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add algorithm-catalog/data/
if git diff --cached --quiet; then
echo "Nothing to commit."
else
git commit -m "chore: compact algorithm-catalog requests into canonical data [skip ci]"
git push
fi
59 changes: 59 additions & 0 deletions .github/workflows/algorithm-catalog-validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Algorithm Catalog β€” validate

# THE STANDARDS GATE.
#
# The rules live once in algorithm-catalog/src/rules.ts (which the form enforces while you type)
# and are mirrored in scripts/validate_data.py. This workflow is the third layer: it re-checks
# every committed request/event/algorithm on the PR, and runs the parity test that proves the two
# copies of the rules still agree. A submission that slips past the form still cannot land.
#
# No install step anywhere in the `validate` job β€” both scripts are stdlib-only Python 3.

on:
pull_request:
paths:
- "algorithm-catalog/**"
push:
branches: [main]
paths:
- "algorithm-catalog/**"
workflow_dispatch:

permissions:
contents: read

jobs:
validate:
name: Data + rules parity
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# Cross-checks algorithms/events/hazards/requests: hazard + product references resolve,
# thumbnails exist on disk, STAC names and dates and bboxes obey the same rules as the form.
- name: Validate committed data
run: python3 algorithm-catalog/scripts/validate_data.py

# Runs one fixture table through BOTH rule implementations and fails if they disagree, so
# rules.ts and validate_data.py can never silently drift apart.
- name: Rules parity (rules.ts vs validate_data.py)
run: python3 algorithm-catalog/scripts/rules_parity_test.py

build:
name: Typecheck + build
runs-on: ubuntu-latest
defaults:
run:
working-directory: algorithm-catalog
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: "24"

- run: npm ci

- run: npm run typecheck

- run: npm run build
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,14 @@ leave-dashboard/dist/
!cost-dashboard/tsconfig.json
!cost-dashboard/tsconfig.node.json
!cost-dashboard/public/data/*.json

# Algorithm Catalog: dashboard config + the committed catalog data (algorithms/events/hazards)
# and the submitted request files β€” re-included past the global *.json ignore. Unlike dse-hub
# (which relies on `git add -f`), these negations mean a plain `git add algorithm-catalog/`
# picks the data up, so a future contributor can't silently drop it from a commit.
!algorithm-catalog/package.json
!algorithm-catalog/package-lock.json
!algorithm-catalog/tsconfig.json
!algorithm-catalog/tsconfig.node.json
!algorithm-catalog/data/*.json
!algorithm-catalog/data/requests/*.json
33 changes: 32 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,20 @@ Netlify reads the `netlify.toml` **inside that base dir**, so the sites stay iso
`.github/workflows/aws-pricing.yml` (weekly + dispatch; regions accumulate). A "Where these prices
come from" panel hyperlinks every service to its AWS pricing page + raw price list + version. See
`docs/AWS_PRICING.md`.
- `algorithm-catalog/` β€” Vite React SPA; `algorithm-catalog/netlify.toml` (base=`algorithm-catalog`,
build, publish `dist`). A catalog of the **NASA Disasters product algorithms** (from
`Disasters-Learning-Portal/disasters-product-algorithms@dev`). **HDS (NASA Horizon Design System)
over USWDS, light-only.** Three tabs: **πŸ“ Submit** (the request form, default landing),
**πŸŒ€ Events** (event catalog = canonical `events.json` + submitted requests), **πŸ›° Algorithms**
(filter by hazard / sensor / product / modality / date / event / AOI, via two entry modes β€”
"start from hazard" vs "start from sensor & product" β€” sharing one filter state). **No
generator/Action** β€” data is hand-curated `data/{algorithms,events,hazards}.json` bundled at BUILD
(plus `data/requests/*.json` overlaid via `import.meta.glob`, dse-hub's merge pattern). Submitting
opens a **prefilled new-file PR** (`new/main?filename=&value=`), same as leave-dashboard/dse-hub.
**The standard is enforced automatically**: `src/rules.ts` holds the rules (the
`YYYYMM_Hazard_Location` regex is lifted verbatim from upstream `dps/_validate.sh:29-36`),
mirrored 1:1 in `scripts/validate_data.py`, kept honest by `scripts/rules_parity_test.py`, and
gated in CI by `.github/workflows/algorithm-catalog-validate.yml`. See `docs/ALGORITHM_CATALOG.md`.

## Theming (light/dark β€” the fte / leave / pr dashboards; dse-hub is USWDS light-only)
Each dashboard themes through **CSS custom properties**: light values live in `:root`, a
Expand Down Expand Up @@ -123,7 +137,20 @@ sets the attribute before first paint + `<meta name="color-scheme" content="dark
- **Root `.gitignore` has `*.json`.** `git add <dir>` **silently skips** needed JSON β€” each dashboard's
`package.json`/`tsconfig*.json`, `dse-hub/data/*.json`, `leave-dashboard/public/data/*.json`. You must
**`git add -f`** them (that's how the sibling dashboards' JSON got committed). A `dse-hub` change touching
data won't be in the commit unless force-added.
data won't be in the commit unless force-added. **Exception: `algorithm-catalog/` has explicit `!`
negation lines** in the root `.gitignore`, so a plain `git add algorithm-catalog/` does pick its JSON
up β€” prefer that route for new apps. Check with `git check-ignore --no-index -v <path>` (plain
`git check-ignore` lies about already-tracked files).
- **STAC event names need EXACTLY 2 underscores, and the catalog is deliberately stricter than
upstream here.** Upstream `dps/_validate.sh:29-36` ends its regex with `.+`, so the LOCATION slot
swallows extra underscores: `202501_Tropical_Cyclone_CA` passes there but silently parses as
hazard=`Tropical`, location=`Cyclone_CA`, and writes a wrong `HAZARD` GeoTIFF tag.
`algorithm-catalog/src/rules.ts` ends with `_[^_]+$` instead, so 3+ underscores is a hard **error**
(rule `underscore-count`) and the form won't submit. This also rejects `202501_Flood_CA_extra`,
which upstream `tests/integration/test_dps_validate.sh:41-48` explicitly accepts β€” a knowing
divergence, and the safe direction: everything we accept, DPS accepts too. Multi-word hazards and
locations are CamelCase (`TropicalCyclone`, `WinterWx`). The catalog serializes hazard **ids**
(= those tokens), never display labels.

## Key files
`action.yml`, `pr-finder/action.yml`, `pr-finder/generate_pr_finder.py`,
Expand All @@ -137,3 +164,7 @@ DSE Hub: `dse-hub/src/{App,tabs,tz,TzContext,ChangesContext,changes,changesData}
`dse-hub/src/meetings/{MeetingTracker,MeetingCalendar,recurrence,drafts,data}.{tsx,ts}`,
`dse-hub/src/pi/{PiRoadmap,data,pi}.{tsx,ts}`, `dse-hub/data/{meetings,pis}.json`,
`dse-hub/scripts/compact.mjs`, `.github/workflows/dse-hub-compact.yml`, `docs/DSE_HUB.md`.
Algorithm Catalog: `algorithm-catalog/src/{types,rules,data,tabs,App}.{ts,tsx}`,
`algorithm-catalog/src/{filters,catalog,events,request}/`, `algorithm-catalog/data/*.json`,
`algorithm-catalog/scripts/{validate_data.py,rules_parity_test.py,compact.mjs}`,
`.github/workflows/algorithm-catalog-{validate,compact}.yml`, `docs/ALGORITHM_CATALOG.md`.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ diff. Intentionally open β€” it will grow to host other VEDA Actions experiments
### πŸ—“οΈ **Leave Dashboard:** https://veda-leave-dashboard.netlify.app
### 🧭 **DSE Hub:** https://veda-dse-hub.netlify.app
### πŸ’΅ **AWS Cost Calculator (Disasters Hub):** https://veda-aws-dashboard.netlify.app
### πŸ›°οΈ **Algorithm Catalog:** _(Netlify site pending β€” base dir `algorithm-catalog`)_

## Use this action in another repo
The report is a **reusable composite action** (`action.yml`). Any repo can import it β€” just point
Expand Down Expand Up @@ -56,6 +57,9 @@ action (`uses: ./`) and then publishes to a `fte-report/<pi>` branch + opens a l
| `.github/workflows/leave-tracker.yml` | self-consumer that publishes the leave report to the `leave-tracker/report` branch |
| `leave-dashboard/` | React SPA (Netlify) β€” calendar of who's out, person-picker, team-risk heatmap, add-person-via-PR β€” [live](https://veda-leave-dashboard.netlify.app) |
| `docs/LEAVE_TRACKER.md` | Leave Tracker data model, color map, overrides, gotchas |
| `algorithm-catalog/` | React SPA (Netlify) β€” filter the NASA Disasters product algorithms by hazard / date / event / sensor / product, and submit a new activation request as a prefilled PR. **No Action** β€” hand-curated JSON bundled at build. |
| `.github/workflows/algorithm-catalog-validate.yml` | **the standards gate**: fails a PR whose event name isn't `YYYYMM_Hazard_Location` (same regex DPS enforces), plus typecheck + build |
| `docs/ALGORITHM_CATALOG.md` | Algorithm Catalog data model, the two entry modes, standards enforcement, gotchas |

## Quickstart

Expand Down
6 changes: 6 additions & 0 deletions algorithm-catalog/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
dist
*.local
.DS_Store
__pycache__/
*.pyc
Loading
Loading