Skip to content

feat(teched): list all-day activities like Developer Garage (issue #2392 item 6) - #2400

Merged
jung-thomas merged 1 commit into
DEVfrom
feat/teched-allday-activities-2392
Sep 17, 2026
Merged

jung-thomas merged 1 commit into
DEVfrom
feat/teched-allday-activities-2392

Conversation

@jung-thomas

Copy link
Copy Markdown
Contributor

Summary

  • Adds allDay Boolean to TechEdSessions (DB model).
  • Fetcher issues a best-effort per-venue POST to the RainFocus all-day catalog tab, parses rows via parseAllDayActivity (lenient: synthesised code when absent, room from location/venue fallback, allDay: true), merges into data.sessions; dropPast never drops an all-day row.
  • Normalize carries allDay through content hash; seed includes the column; /build/teched feed emits allDay with the shared isAllDay() helper.
  • upcoming=true filter uses tagged-template CQL with an explicit OR allDay = true OR scheduledEnd is null carve-out (timeless rows survive).
  • /teched/ island splits filteredAllDay / filteredTimed; renders a distinct <section aria-label="All-day activities"> with an "All-day" badge above the timed grid.

OPEN ITEM — live request params unconfirmed

The all-day tab request params (RAINFOCUS_TE26_ALLDAY_FILTER = 1742815606768001gh9v, RAINFOCUS_ALLDAY_TAB_PARAM = tab.alldayactivities) are based on Tom's Berlin browser capture but have not been confirmed against the live API. Parsing, model, seed, feed, and UI are proven against test/fixtures/teched/rainfocus-alldayactivities.json (synthetic fixture). A mismatch simply yields 0 all-day rows and never breaks the regular session ingest. Tune the env vars when a live capture is available.

Test plan

  • test/unit/teched-allday.test.js — parseAllDayActivity, dedup, fetchAllTechEdSessions all-day tab, normalizeSession allDay flag (new file).
  • test/unit/srv/build-teched-allday.test.js — allDay flows through seed → /build/teched; upcoming=true keeps all-day rows despite NULL scheduledEnd (new file).
  • hugo-apps/src/teched-sessions-grid/__tests__/App.allday.test.ts — all-day section renders, excluded from timed grid, badge, detail panel, filter (new file).
  • test/unit/teched-normalize.test.js — extended with allDay flag coverage.
  • All 32 teched unit tests pass. All 28 island tests (existing + new) pass.
  • Full unit suite: 1361 test files pass; 8 pre-existing failures (missing parsers.bundle.mjs build artifact + missing graphology in fresh-worktree node_modules — unrelated to this PR).

Deferred code-review findings (deliberate, noted for follow-up)

# Finding Decision
#2 iCal endpoint gap for all-day (graceful 404 today) Out of scope for this unit; OPEN ITEM noted
#3 NULL-first ordering on SQLite vs HANA divergence Latent; catalog << 1000-row cap; safe to defer
#5 UI card markup duplicated for all-day section Deliberate — preserves scoped CSS + existing tests; do not redesign the grid
#6 parseAllDayActivity duplicates some parseSession logic Deliberate — lenient all-day parser must not perturb the proven regular-session path
#7 Mass UPDATE on first ingest (all rows get allDay=false written) One-time benign; expected on schema addition; recovers automatically

All-day activities (Developer Garage, AI Showfloor Expo, etc.) live
under a SEPARATE RainFocus catalog tab (`tab.alldayactivities=<id>`),
NOT in the regular `type=session` feed. This PR wires them in end-to-end.

**Model** (`db/external/teched.cds`)
- Add `allDay Boolean default false` to `TechEdSessions`.

**Fetcher** (`srv/lib/teched/rainfocus-fetcher.js`)
- New `parseAllDayActivity(item, venue)` — lenient parser (synthesises
  `allday-<sourceId>` code when absent, room from `location`/`venue`
  fallback, `allDay: true`).
- `fetchAllTechEdSessions` issues a best-effort per-venue all-day POST
  (own try/catch; `allDayFilter` env-configurable; empty ⇒ skipped).
- `parseVenuePayload` accepts `allDayItems`; dedup via `seenSourceIds`
  (regular session wins on collision).
- `dropPast` never drops a row where `s.allDay === true`.
- Defaults: Berlin filter `1742815606768001gh9v` (Tom's capture),
  Virtual unset; tab param `tab.alldayactivities`.

**Normalize** (`srv/lib/teched/normalize.js`)
- `normalizeSession` maps `allDay: raw.allDay === true` (part of hash).

**Seed** (`srv/lib/teched/seed-core.js`)
- `SESSION_COLS` includes `'allDay'`.

**Feed** (`srv/lib/teched-feed.js`)
- SELECT includes `allDay`; emits `allDay: isAllDay(r.allDay)`.
- Shared `isAllDay(v)` helper (coerces `true`/`1` → boolean).
- `upcoming=true` filter uses tagged-template CQL (safe ISO binding)
  with explicit `OR allDay = true OR scheduledEnd is null` carve-out
  so timeless all-day rows survive the filter.

**UI** (`hugo-apps/src/teched-sessions-grid/App.vue`, `filter.ts`)
- `allDay?: boolean` on `TechEdSession` interface.
- `filteredAllDay` / `filteredTimed` computed splits.
- Distinct `<section aria-label="All-day activities">` with "All-day"
  badge rendered above the timed grid; timed grid unaffected.

- `test/unit/teched-allday.test.js` — parseAllDayActivity, dedup,
  fetchAllTechEdSessions all-day tab, normalizeSession allDay flag.
- `test/unit/srv/build-teched-allday.test.js` — allDay flows through
  seed → /build/teched; upcoming filter keeps all-day rows.
- `hugo-apps/src/teched-sessions-grid/__tests__/App.allday.test.ts` —
  all-day section renders, excluded from timed grid, badge, detail
  panel, filter across both sections.
- `test/unit/teched-normalize.test.js` — allDay flag coverage extended.
- `test/fixtures/teched/rainfocus-alldayactivities.json` — synthetic
  raw all-day tab capture (live params unconfirmed — see OPEN ITEM).
- `test/fixtures/teched/teched-allday-feed.json` — derived feed shape.

The exact live RainFocus request param name/value for the all-day tab
is NOT yet confirmed against the real API. Parsing, model, seed, feed,
and UI are proven against the synthetic fixture. Tune
`RAINFOCUS_TE26_ALLDAY_FILTER` / `RAINFOCUS_ALLDAY_TAB_PARAM` when a
live capture is available — a mismatch yields 0 all-day rows and never
breaks the regular session ingest.

- #2 iCal all-day gap: graceful 404 out of scope for this unit.
- #3 NULL-first ordering on SQLite vs HANA: catalog << 1000 cap, latent.
- #5/#6 UI/parser duplication: deliberate (scoped CSS + tested parseSession).
- #7 mass UPDATE on first ingest: one-time benign, expected behaviour.
@jung-thomas
jung-thomas force-pushed the feat/teched-allday-activities-2392 branch from 6c8b2bf to dee90c1 Compare September 17, 2026 17:42
@jung-thomas
jung-thomas merged commit 0c43c3c into DEV Sep 17, 2026
8 checks passed
@jung-thomas
jung-thomas deleted the feat/teched-allday-activities-2392 branch September 17, 2026 17:46
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.

1 participant