Skip to content

My Meetups - Open Community Groups#942

Open
tegioz wants to merge 6 commits into
linuxfoundation:mainfrom
tegioz:tegioz/meetups-ocg
Open

My Meetups - Open Community Groups#942
tegioz wants to merge 6 commits into
linuxfoundation:mainfrom
tegioz:tegioz/meetups-ocg

Conversation

@tegioz

@tegioz tegioz commented Jun 15, 2026

Copy link
Copy Markdown

Hi!

I'm one of the maintainers of Open Community Groups 👋

This PR introduces a new My Meetups section, as requested by @caniszczyk. It works pretty similar to the My Events section, but it lists meetups from Open Community Groups. You can see it in action in the video below.

My Meetups feeds from Snowflake, querying some dynamic tables we've prepared. @skalepp has helped us by creating them in the LF Snowflake instance. So far we've only been able to test it locally, using our own Auth0/Snowflake accounts, but it seems like it's working fine 🙂

/cc @jeefy @cynthia-sg

lfx-ss-meetups.mov

Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
Copilot AI review requested due to automatic review settings June 15, 2026 11:29
@tegioz tegioz requested a review from a team as a code owner June 15, 2026 11:29
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ed3d0ad8-f212-466f-ba91-1cc199c679ef

📥 Commits

Reviewing files that changed from the base of the PR and between 4499d34 and 6d388a7.

📒 Files selected for processing (7)
  • apps/lfx-one/public/assets/docs/search-index.json
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-list/meetups-list.component.ts
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-table/meetups-table.component.ts
  • apps/lfx-one/src/server/controllers/meetups.controller.ts
  • apps/lfx-one/src/server/services/meetups.service.ts
  • packages/shared/src/constants/meetups.constants.ts
  • packages/shared/src/interfaces/meetups.interface.ts
✅ Files skipped from review due to trivial changes (1)
  • apps/lfx-one/public/assets/docs/search-index.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/shared/src/interfaces/meetups.interface.ts
  • apps/lfx-one/src/server/controllers/meetups.controller.ts
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-table/meetups-table.component.ts
  • apps/lfx-one/src/server/services/meetups.service.ts
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-list/meetups-list.component.ts

Walkthrough

Adds a full-stack "My Meetups" feature enabling users to browse their upcoming and past meetups. Shared domain types and constants are defined, a Snowflake-backed server service builds parameterized SQL queries for upcoming/past meetups with optional search and community/role/status filtering, Express API endpoints validate and serve the data, and an Angular HTTP service, route configuration, and multi-component dashboard UI (with search, filters, tabs, and pagination) complete the feature.

Changes

My Meetups Feature

Layer / File(s) Summary
Shared types, interfaces, and constants
packages/shared/src/interfaces/meetups.interface.ts, packages/shared/src/interfaces/index.ts, packages/shared/src/constants/meetups.constants.ts, packages/shared/src/constants/index.ts
Defines MeetupTabId, MeetupStatusFilter, MeetupSortOrder, MeetupSortField, MeetupSortChangeEvent, MyMeetup, MyMeetupsResponse, MeetupFilterOptionsResponse, GetMyMeetupsParams, GetMyMeetupsOptions, MeetupRow, MeetupFilterRow plus pagination limits, sort field allowlists, Snowflake schema defaults, OCG base URL, empty response sentinels, and barrel re-exports.
Server Snowflake data service
apps/lfx-one/src/server/services/meetups.service.ts
Resolves and validates the Snowflake schema, builds parameterized SQL for upcoming/past meetups with optional search/community/role/status filters and ranking logic for upcoming, executes queries with error-safe row mapping, and provides getMeetupFilters to partition filter catalog values.
Express controller, router, and server registration
apps/lfx-one/src/server/controllers/meetups.controller.ts, apps/lfx-one/src/server/routes/meetups.route.ts, apps/lfx-one/src/server/server.ts
Adds MeetupsController with authenticated getMyMeetups and getMeetupFilters handlers, parseMeetupsOptions to validate and normalize query params, an Express router wiring GET / and GET /filters, and server registration under /api/meetups.
Angular HTTP service, route config, and app wiring
apps/lfx-one/src/app/shared/services/meetups.service.ts, apps/lfx-one/src/app/modules/meetups/meetups.routes.ts, apps/lfx-one/src/app/app.routes.ts, apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
Adds Angular MeetupsService with HttpParams-typed requests, a lazy-loaded auth-guarded route constant, top-level meetups route and me/meetups redirect, and a "My Meetups" sidebar entry under My Engagement.
MeetupsTableComponent — sortable paginated table
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-table/meetups-table.component.ts, meetups-table.component.html
Renders a paginated lfx-table with sortable columns (name, community, date, location), ARIA sort states, per-field sort icon CSS classes, a conditional status column for upcoming rows, safe URL row selection via http/https protocol validation, and pageChange/sortChange outputs.
MeetupsTopBarComponent — search and filter controls
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-top-bar/meetups-top-bar.component.ts, meetups-top-bar.component.html
Provides a reactive FormGroup-backed search input with debounced output, community/role/status dropdowns populated from getMeetupFilters(), syncInputToControl to keep form in sync with parent signals without feedback loops, and status control auto-clear when showStatusFilter is false.
MeetupsListComponent — dual-tab data fetching and pagination
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-list/meetups-list.component.ts, meetups-list.component.html
Manages independent upcoming/past loading, pagination, and sort signals; a debounced reactive pipeline calls MeetupsService.getMyMeetups per active tab with transient retry and optional PrimeNG error toast; filter changes reset both tabs' offsets; template renders table or tab-specific empty-state cards.
MeetupsDashboardComponent — top-level orchestration
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/meetups-dashboard.component.ts, meetups-dashboard.component.html
Holds activeTab and filter signals, delegates showFiltersBar to MeetupsListComponent via viewChild, and resets all filters on tab switch. Template renders page header, tab pills, conditional top bar, and lfx-meetups-list with wired event handlers.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant Dashboard as MeetupsDashboardComponent
  participant TopBar as MeetupsTopBarComponent
  participant List as MeetupsListComponent
  participant AngularSvc as MeetupsService (Angular)
  participant Server as Express /api/meetups
  participant Snowflake as Database

  User->>Dashboard: navigate to /meetups
  Dashboard->>TopBar: render with filter inputs
  TopBar->>AngularSvc: getMeetupFilters()
  AngularSvc->>Server: GET /api/meetups/filters
  Server->>Snowflake: execute filters SQL
  Snowflake-->>Server: MeetupFilterRow[]
  Server-->>AngularSvc: MeetupFilterOptionsResponse
  AngularSvc-->>TopBar: communityOptions, roleOptions

  User->>TopBar: enter search / select filter
  TopBar->>Dashboard: searchQueryChange / communityChange / roleChange / statusChange
  Dashboard->>List: update filter signals
  List->>AngularSvc: getMyMeetups(params)
  AngularSvc->>Server: GET /api/meetups?...
  Server->>Snowflake: execute upcoming/past SQL
  Snowflake-->>Server: MeetupRow[]
  Server-->>AngularSvc: MyMeetupsResponse
  AngularSvc-->>List: signal updated
  List-->>User: render MeetupsTableComponent
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

deploy-preview, enhancement

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: introduction of a 'My Meetups' feature for Open Community Groups.
Description check ✅ Passed The description is directly related to the changeset, explaining the purpose, context, and implementation details of the new My Meetups feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds “My Meetups” functionality end-to-end (shared types/constants, backend API + Snowflake queries, and Angular UI) to let authenticated users browse/filter upcoming and past meetups.

Changes:

  • Introduces shared meetups interfaces and constants (paging, sorting, filter defaults).
  • Adds backend /api/meetups + /api/meetups/filters endpoints backed by Snowflake queries and row mapping.
  • Adds Angular meetups module (routes, dashboard, filters/search top bar, list/table rendering with pagination & sorting).

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/shared/src/interfaces/meetups.interface.ts Adds shared meetups data contracts for API/UI.
packages/shared/src/interfaces/index.ts Re-exports meetups interfaces for shared consumption.
packages/shared/src/constants/meetups.constants.ts Centralizes meetups defaults/validation constants and empty responses.
packages/shared/src/constants/index.ts Re-exports meetups constants.
apps/lfx-one/src/server/services/meetups.service.ts Implements Snowflake-backed meetups fetching, filtering, sorting, and mapping.
apps/lfx-one/src/server/server.ts Mounts new /api/meetups router.
apps/lfx-one/src/server/routes/meetups.route.ts Defines meetups API routes.
apps/lfx-one/src/server/controllers/meetups.controller.ts Parses/validates query params and enforces authentication for meetups endpoints.
apps/lfx-one/src/app/shared/services/meetups.service.ts Angular HTTP client wrapper for meetups endpoints.
apps/lfx-one/src/app/modules/meetups/meetups.routes.ts Adds Angular meetups page routing with auth guard.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/meetups-dashboard.component.ts Dashboard state management for tabs and filters.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/meetups-dashboard.component.html Dashboard layout: tabs, filters bar, list/table.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-top-bar/meetups-top-bar.component.ts Search + filter controls and loading filter options from API.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-top-bar/meetups-top-bar.component.html Renders search and filter dropdowns.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-table/meetups-table.component.ts Meetups table with sort icons, ARIA sort mapping, and row click navigation.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-table/meetups-table.component.html Table markup, sortable headers, empty state row.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-list/meetups-list.component.ts Orchestrates fetching, paging, sorting, and empty-state behavior per tab.
apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-list/meetups-list.component.html Conditional rendering for upcoming/past tables and empty states.
apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts Adds “My Meetups” item to main navigation.
apps/lfx-one/src/app/app.routes.ts Adds /meetups route and /me/meetups redirect.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/lfx-one/src/server/services/meetups.service.ts
Comment thread apps/lfx-one/src/server/controllers/meetups.controller.ts
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/lfx-one/src/app/shared/services/meetups.service.ts (1)

24-24: ⚡ Quick win

Use !== undefined check for consistency with other numeric/boolean params.

Line 24 uses a truthy check (if (params.pageSize)), which would skip pageSize: 0. While 0 is likely invalid for pagination, this pattern is inconsistent with the checks for isPast (line 18) and offset (line 25), both of which use !== undefined. For defensive programming and consistency, use the same pattern.

♻️ Suggested change for consistency
-    if (params.pageSize) httpParams = httpParams.set('pageSize', String(params.pageSize));
+    if (params.pageSize !== undefined) httpParams = httpParams.set('pageSize', String(params.pageSize));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/lfx-one/src/app/shared/services/meetups.service.ts` at line 24, The
pageSize parameter check on line 24 uses a truthy check (`if (params.pageSize)`)
which is inconsistent with the `!== undefined` checks used for isPast on line 18
and offset on line 25. Replace the truthy check with `if (params.pageSize !==
undefined)` to maintain consistency across all parameter validation checks and
to properly handle edge cases like pageSize: 0.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/lfx-one/src/server/controllers/meetups.controller.ts`:
- Around line 80-110: In the parseMeetupsOptions method, apply the .trim()
method to the community and role query parameter assignments (currently on the
lines that return undefined if not present) to match the consistent trimming
behavior already applied to searchQuery. This ensures that leading and trailing
whitespace in these filter values is removed, preventing filter mismatches
caused by user input inconsistencies.

---

Nitpick comments:
In `@apps/lfx-one/src/app/shared/services/meetups.service.ts`:
- Line 24: The pageSize parameter check on line 24 uses a truthy check (`if
(params.pageSize)`) which is inconsistent with the `!== undefined` checks used
for isPast on line 18 and offset on line 25. Replace the truthy check with `if
(params.pageSize !== undefined)` to maintain consistency across all parameter
validation checks and to properly handle edge cases like pageSize: 0.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 18a350fc-f81c-403d-adeb-52e137276d50

📥 Commits

Reviewing files that changed from the base of the PR and between 01e036c and bd2c41a.

📒 Files selected for processing (20)
  • apps/lfx-one/src/app/app.routes.ts
  • apps/lfx-one/src/app/layouts/main-layout/main-layout.component.ts
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-list/meetups-list.component.html
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-list/meetups-list.component.ts
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-table/meetups-table.component.html
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-table/meetups-table.component.ts
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-top-bar/meetups-top-bar.component.html
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/components/meetups-top-bar/meetups-top-bar.component.ts
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/meetups-dashboard.component.html
  • apps/lfx-one/src/app/modules/meetups/meetups-dashboard/meetups-dashboard.component.ts
  • apps/lfx-one/src/app/modules/meetups/meetups.routes.ts
  • apps/lfx-one/src/app/shared/services/meetups.service.ts
  • apps/lfx-one/src/server/controllers/meetups.controller.ts
  • apps/lfx-one/src/server/routes/meetups.route.ts
  • apps/lfx-one/src/server/server.ts
  • apps/lfx-one/src/server/services/meetups.service.ts
  • packages/shared/src/constants/index.ts
  • packages/shared/src/constants/meetups.constants.ts
  • packages/shared/src/interfaces/index.ts
  • packages/shared/src/interfaces/meetups.interface.ts

Comment thread apps/lfx-one/src/server/controllers/meetups.controller.ts
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
Copilot AI review requested due to automatic review settings June 15, 2026 12:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 5 comments.

Comment thread packages/shared/src/constants/meetups.constants.ts Outdated
Comment thread packages/shared/src/constants/meetups.constants.ts
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
@caniszczyk

Copy link
Copy Markdown

@tegioz thanks, if there was another system that wanted to populate meetups say from another source like meetup.com or luma, how would they go about doing that? just make sure the data is structured properly and fetched via meetups.service.ts?

@tegioz

tegioz commented Jun 15, 2026

Copy link
Copy Markdown
Author

No worries @caniszczyk 🙂

If the data from those sources was also stored in Snowflake, we could update the meetups dynamic tables to include data from the other providers as well, in addition to the OCG raw data tables, to present a common facade/view for meetups. This new feature is based on that data abstraction already, to hide the particularities of the OCG raw data, and speed the queries up. It'd be interesting to include a provider field (i.e. OCG, Luma, etc), and eventually display it in the UI.

That'd be on the data side. On the LFX Self Serve app side, we may need to extend some types for additional participation roles supported by the other providers, or adjust some filters (i.e. some concepts like the community in OCG may not be available in other providers) and their sources. There are some OCG specific bits and comments that we could make more generic as well, to make it easier to accommodate additional providers in the future.

niravpatel27
niravpatel27 previously approved these changes Jun 15, 2026
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
Copilot AI review requested due to automatic review settings June 15, 2026 18:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.

Comment thread apps/lfx-one/src/server/services/meetups.service.ts
Comment thread apps/lfx-one/src/server/controllers/meetups.controller.ts Outdated
Comment thread apps/lfx-one/src/server/services/meetups.service.ts
Comment thread packages/shared/src/constants/meetups.constants.ts Outdated
Signed-off-by: Sergio Castaño Arteaga <tegioz@icloud.com>
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.

4 participants