An open API service indexing awesome lists of open source software.

https://github.com/linuxfoundation/lfx-v2-meeting-service

LFX v2 Platform Meeting Service
https://github.com/linuxfoundation/lfx-v2-meeting-service

Last synced: about 2 months ago
JSON representation

LFX v2 Platform Meeting Service

Awesome Lists containing this project

README

          

# ITX Meeting Proxy Service

The ITX Meeting Proxy Service is a lightweight stateless proxy that forwards meeting-related requests to the ITX Zoom API service. It provides a thin authentication and authorization layer for the Linux Foundation's LFX platform.

## ๐Ÿš€ Quick Start

### For Deployment (Helm)

```bash
# Install the proxy service
helm upgrade --install lfx-v2-meeting-service ./charts/lfx-v2-meeting-service \
--namespace lfx \
--create-namespace \
--set image.tag=latest \
--set app.environment.ITX_BASE_URL.value="https://api.itx.linuxfoundation.org" \
--set app.environment.ITX_CLIENT_ID.value="your-client-id" \
--set-file app.environment.ITX_CLIENT_PRIVATE_KEY.value=path/to/private.key
```

### For Local Development

1. **Prerequisites**
- Go 1.24+ installed
- Make installed

2. **Clone and Setup**

```bash
git clone https://github.com/linuxfoundation/lfx-v2-meeting-service.git
cd lfx-v2-meeting-service

# Install dependencies
make deps
```

3. **Configure Environment**

```bash
# Copy the example environment file and configure it
cp .env.example .env
# Edit .env with ITX credentials
```

Required environment variables:

```bash
ITX_ENABLED=true
ITX_BASE_URL=https://api.dev.itx.linuxfoundation.org
ITX_CLIENT_ID=your-client-id
ITX_CLIENT_PRIVATE_KEY="$(cat path/to/private.key)"
ITX_AUTH0_DOMAIN=linuxfoundation-dev.auth0.com
ITX_AUDIENCE=https://api.dev.itx.linuxfoundation.org/
```

4. **Run the Service**

```bash
# Run with default settings
make run

# Or run with debug logging
make debug
```

## ๐Ÿ—๏ธ Architecture

The service is a stateless HTTP proxy built using a clean architecture pattern:

- **API Layer**: Goa-generated HTTP handlers and OpenAPI specifications
- **Service Layer**: Request validation and ITX client orchestration
- **Domain Layer**: Core request/response models
- **Infrastructure Layer**: ITX HTTP client with OAuth2 authentication

### Key Features

- **Stateless Proxy**: No data persistence, all state managed by ITX service
- **ITX Meeting Operations**: Create, read, update, delete meetings via ITX
- **ITX Registrant Operations**: Manage meeting registrants via ITX
- **ITX Past Meeting Operations**: Full CRUD operations for past meeting records via ITX
- **ITX Past Meeting Summary Operations**: Retrieve and update AI-generated meeting summaries
- **ITX Meeting Attachment Operations**: Full CRUD operations for meeting attachments with presigned URL support
- **ITX Past Meeting Attachment Operations**: Full CRUD operations for past meeting attachments with presigned URL support
- **JWT Authentication**: Secure API access via Heimdall integration
- **ID Mapping**: Optional v1/v2 ID translation via NATS (can be disabled)
- **OpenAPI Documentation**: Auto-generated API specifications

## ๐Ÿ“ Project Structure

```bash
lfx-v2-meeting-service/
โ”œโ”€โ”€ cmd/ # Application entry points
โ”‚ โ””โ”€โ”€ meeting-api/ # Main API server
โ”œโ”€โ”€ charts/ # Helm chart for Kubernetes deployment
โ”‚ โ””โ”€โ”€ lfx-v2-meeting-service/
โ”œโ”€โ”€ design/ # Goa API design files
โ”‚ โ”œโ”€โ”€ meeting-svc.go # Service definition
โ”‚ โ””โ”€โ”€ itx_types.go # ITX type definitions
โ”œโ”€โ”€ gen/ # Generated code (DO NOT EDIT)
โ”‚ โ”œโ”€โ”€ http/ # HTTP transport layer
โ”‚ โ””โ”€โ”€ meeting_service/ # Service interfaces
โ”œโ”€โ”€ internal/ # Private application code
โ”‚ โ”œโ”€โ”€ domain/ # Business domain layer
โ”‚ โ”‚ โ”œโ”€โ”€ models/ # Domain models
โ”‚ โ”‚ โ”œโ”€โ”€ errors.go # Domain-specific errors
โ”‚ โ”‚ โ”œโ”€โ”€ itx_proxy.go # ITX proxy interface
โ”‚ โ”‚ โ””โ”€โ”€ id_mapper.go # ID mapper interface
โ”‚ โ”œโ”€โ”€ infrastructure/ # Infrastructure layer
โ”‚ โ”‚ โ”œโ”€โ”€ auth/ # JWT authentication
โ”‚ โ”‚ โ”œโ”€โ”€ proxy/ # ITX HTTP client
โ”‚ โ”‚ โ””โ”€โ”€ idmapper/ # NATS-based ID mapping
โ”‚ โ”œโ”€โ”€ middleware/ # HTTP middleware
โ”‚ โ””โ”€โ”€ service/ # Service layer implementation
โ”‚ โ”œโ”€โ”€ auth_service.go # Auth service
โ”‚ โ””โ”€โ”€ itx/ # ITX services
โ”œโ”€โ”€ pkg/ # Public packages
โ”‚ โ”œโ”€โ”€ models/itx/ # ITX request/response models
โ”‚ โ””โ”€โ”€ utils/ # Utility functions
โ”œโ”€โ”€ Dockerfile # Container build configuration
โ”œโ”€โ”€ Makefile # Build and development commands
โ””โ”€โ”€ go.mod # Go module definition
```

## ๐Ÿ“ก Event Processing

The service includes a comprehensive event processing system for v1โ†’v2 data synchronization. It watches NATS JetStream KV buckets for meeting-related data changes and publishes events to both indexer and FGA-sync services.

**Features:**

- 10 meeting-related event types (meetings, registrants, RSVPs, past meetings, participants, recordings, summaries)
- RRULE occurrence calculation for recurring meetings
- v1 user enrichment and Auth0 mapping
- Dual publishing architecture (indexer + FGA-sync)
- Parent-child dependency handling with retry logic

For complete details, see **[Event Processing Documentation](docs/event-processing.md)**.

## ๐Ÿ› ๏ธ Development

### Prerequisites

- Go 1.24+
- Make
- Git

### Getting Started

1. **Install Dependencies**

```bash
make deps
```

2. **Generate API Code**

```bash
make apigen
```

Generates HTTP transport, client, and OpenAPI documentation from design files.

3. **Build the Application**

```bash
make build
```

Creates the binary in `bin/meeting-api`.

### Development Workflow

#### Running the Service

```bash
# Run with default settings
make run

# Run with debug logging
make debug

# Build and run binary
make build
./bin/meeting-api
```

#### Code Quality

**Always run these before committing:**

```bash
# Format code
make fmt

# Run linter
make lint

# Run all tests
make test

# Check everything (format + lint + tests)
make check
```

#### API Development

When modifying the API:

1. **Update Design Files** in `design/` directory
2. **Regenerate Code**:

```bash
make apigen
```

3. **Verify Generation**:

```bash
make verify
```

4. **Run Tests** to ensure nothing breaks:

```bash
make test
```

### Available Make Targets

| Target | Description |
|--------|-------------|
| `make all` | Complete build pipeline (clean, deps, apigen, fmt, lint, test, build) |
| `make deps` | Install dependencies, tools, and git hooks |
| `make install-hooks` | Install git hooks (pre-commit gofmt check) |
| `make apigen` | Generate API code from design files |
| `make build` | Build the binary |
| `make run` | Run the service locally |
| `make debug` | Run with debug logging |
| `make test` | Run unit tests |
| `make test-verbose` | Run tests with verbose output |
| `make test-coverage` | Generate HTML coverage report |
| `make lint` | Run code linter |
| `make fmt` | Format code |
| `make check` | Verify formatting and run linter |
| `make verify` | Ensure generated code is up to date |
| `make clean` | Remove build artifacts |
| `make docker-build` | Build Docker image |
| `make helm-install` | Install Helm chart |
| `make helm-uninstall` | Uninstall Helm chart |

## ๐Ÿงช Testing

### Running Tests

```bash
# Run all tests
make test

# Run with verbose output
make test-verbose

# Generate coverage report
make test-coverage
```

## ๐Ÿš€ Deployment

### Helm Chart

The service includes a Helm chart for Kubernetes deployment.

#### Prerequisites: Kubernetes Secret

Before installing the chart, create the `meeting-secrets` secret in the `lfx` namespace. The `auth0_client_id` and `auth0_client_private_key` values are in 1Password under the **LFX V2** vault, in the note **LFX Platform Chart Values Secrets - Local Development**.

```bash
kubectl create secret generic meeting-secrets -n lfx \
--from-literal=auth0_client_id="" \
--from-file=auth0_client_private_key=./path/to/private.key
```

#### Option 1: Install from GHCR (no local code changes)

Use this if you just want to run the service without modifying its code. The image is pulled directly from the container registry:

```bash
make helm-install

# Or using Helm directly
helm upgrade --install lfx-v2-meeting-service ./charts/lfx-v2-meeting-service \
--namespace lfx \
--create-namespace
```

#### Option 2: Install from a Local Build (active development)

Use this if you are making changes to the service code. First, copy the example local values file (it is gitignored):

```bash
cp charts/lfx-v2-meeting-service/values.local.example.yaml \
charts/lfx-v2-meeting-service/values.local.yaml
```

Then, whenever you make a code change and want to apply it:

```bash
# Rebuild the local image
make docker-build

# Install/upgrade the chart using the local image
make helm-install-local

# Or using Helm directly
helm upgrade --install lfx-v2-meeting-service ./charts/lfx-v2-meeting-service \
--namespace lfx \
--create-namespace \
--values ./charts/lfx-v2-meeting-service/values.local.yaml
```

### Docker

```bash
# Build Docker image
make docker-build

# Run with Docker
docker run -p 8080:8080 \
-e ITX_ENABLED=true \
-e ITX_BASE_URL=https://api.itx.linuxfoundation.org \
-e ITX_CLIENT_ID=your-client-id \
-e ITX_CLIENT_PRIVATE_KEY="$(cat path/to/private.key)" \
linuxfoundation/lfx-v2-meeting-service:latest
```

## ๐Ÿ“– API Documentation

The service automatically generates OpenAPI documentation:

- **OpenAPI 2.0**: `gen/http/openapi.yaml`
- **OpenAPI 3.0**: `gen/http/openapi3.yaml`
- **JSON formats**: Also available in `gen/http/`

Access the documentation at: `http://localhost:8080/openapi.json`

### Available Endpoints

#### Health Checks

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/livez` | GET | Liveness check |
| `/readyz` | GET | Readiness check |

#### ITX Meeting Operations

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/itx/meetings` | POST | Create meeting via ITX |
| `/itx/meetings/{meeting_id}` | GET | Get meeting details |
| `/itx/meetings/{meeting_id}` | PUT | Update meeting |
| `/itx/meetings/{meeting_id}` | DELETE | Delete meeting |
| `/itx/meetings/{meeting_id}/join_link` | GET | Get join link for user |
| `/itx/meetings/{meeting_id}/responses` | POST | Submit meeting RSVP (accepted/declined/maybe) |
| `/itx/meetings/{meeting_id}/occurrences/{occurrence_id}` | PATCH | Update occurrence |
| `/itx/meetings/{meeting_id}/occurrences/{occurrence_id}` | DELETE | Delete occurrence |
| `/itx/meeting_count` | GET | Get meeting count |

#### ITX Registrant Operations

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/itx/meetings/{meeting_id}/registrants` | POST | Add registrant |
| `/itx/meetings/{meeting_id}/registrants` | GET | List registrants |
| `/itx/meetings/{meeting_id}/registrants/{registrant_uid}` | GET | Get registrant |
| `/itx/meetings/{meeting_id}/registrants/{registrant_uid}` | PATCH | Update registrant |
| `/itx/meetings/{meeting_id}/registrants/{registrant_uid}` | PUT | Update registrant status |
| `/itx/meetings/{meeting_id}/registrants/{registrant_uid}` | DELETE | Delete registrant |

#### ITX Past Meeting Operations

| Endpoint | Method | Description |
|------------------------------------------|--------|----------------------|
| `/itx/past_meetings` | POST | Create past meeting |
| `/itx/past_meetings/{past_meeting_id}` | GET | Get past meeting |
| `/itx/past_meetings/{past_meeting_id}` | PUT | Update past meeting |
| `/itx/past_meetings/{past_meeting_id}` | DELETE | Delete past meeting |

#### ITX Meeting Attachment Operations

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/itx/meetings/{meeting_id}/attachments` | POST | Create meeting attachment |
| `/itx/meetings/{meeting_id}/attachments/{attachment_id}` | GET | Get attachment metadata |
| `/itx/meetings/{meeting_id}/attachments/{attachment_id}` | PUT | Update attachment |
| `/itx/meetings/{meeting_id}/attachments/{attachment_id}` | DELETE | Delete attachment |
| `/itx/meetings/{meeting_id}/attachments/presign` | POST | Generate presigned upload URL |
| `/itx/meetings/{meeting_id}/attachments/{attachment_id}/download` | GET | Get download URL |

#### ITX Past Meeting Attachment Operations

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/itx/past_meetings/{meeting_and_occurrence_id}/attachments` | POST | Create past meeting attachment |
| `/itx/past_meetings/{meeting_and_occurrence_id}/attachments/{attachment_id}` | GET | Get attachment metadata |
| `/itx/past_meetings/{meeting_and_occurrence_id}/attachments/{attachment_id}` | PUT | Update attachment |
| `/itx/past_meetings/{meeting_and_occurrence_id}/attachments/{attachment_id}` | DELETE | Delete attachment |
| `/itx/past_meetings/{meeting_and_occurrence_id}/attachments/presign` | POST | Generate presigned upload URL |
| `/itx/past_meetings/{meeting_and_occurrence_id}/attachments/{attachment_id}/download` | GET | Get download URL |

## ๐Ÿ”ง Configuration

The service can be configured via environment variables:

### Required Configuration

| Variable | Description | Example |
|----------|-------------|---------|
| `ITX_BASE_URL` | Base URL for ITX service | `https://api.itx.linuxfoundation.org` |
| `ITX_CLIENT_ID` | OAuth2 client ID for ITX | `your-client-id` |
| `ITX_CLIENT_PRIVATE_KEY` | RSA private key in PEM format for ITX OAuth2 M2M authentication | `"$(cat path/to/private.key)"` |
| `ITX_AUTH0_DOMAIN` | Auth0 domain for ITX OAuth2 | `linuxfoundation.auth0.com` |
| `ITX_AUDIENCE` | OAuth2 audience for ITX | `https://api.itx.linuxfoundation.org/` |

### Authentication Configuration

| Variable | Description | Default |
|----------|-------------|---------|
| `JWKS_URL` | JWKS URL for JWT verification | `http://lfx-platform-heimdall.lfx.svc.cluster.local:4457/.well-known/jwks` |
| `JWT_AUDIENCE` | JWT token audience | `lfx-v2-meeting-service` |
| `JWT_AUTH_DISABLED_MOCK_LOCAL_PRINCIPAL` | Mock principal for local dev | `""` |

### Optional Configuration

| Variable | Description | Default |
|----------|-------------|---------|
| `LOG_LEVEL` | Log level (debug, info, warn, error) | `info` |
| `LOG_ADD_SOURCE` | Add source location to logs | `true` |
| `LFX_ENVIRONMENT` | LFX environment (dev, staging, prod) | `prod` |
| `ID_MAPPING_DISABLED` | Disable v1/v2 ID mapping | `false` |
| `NATS_URL` | NATS server URL (for ID mapping) | `nats://lfx-platform-nats.lfx.svc.cluster.local:4222` |

### ID Mapping

The service supports optional ID mapping between v1 and v2 systems via NATS:

- **Enabled** (default): Set `ID_MAPPING_DISABLED=false` and provide `NATS_URL`
- **Disabled**: Set `ID_MAPPING_DISABLED=true` to pass IDs through unchanged

### Tracing Configuration

The service supports distributed tracing via OpenTelemetry:

| Variable | Description | Default |
|----------|-------------|---------|
| `OTEL_SERVICE_NAME` | Service name for traces | `lfx-v2-meeting-service` |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint | `""` |
| `OTEL_TRACES_EXPORTER` | Traces exporter (otlp/none) | `none` |
| `OTEL_TRACES_SAMPLE_RATIO` | Sampling ratio (0.0-1.0) | `1.0` |

## ๐Ÿค Contributing

1. **Fork** the repository
2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)
3. **Make changes** and ensure tests pass (`make test`)
4. **Run quality checks** (`make check`)
5. **Commit** changes (`git commit -m 'Add amazing feature'`)
6. **Push** to branch (`git push origin feature/amazing-feature`)
7. **Create** a Pull Request

### Code Standards

- Follow Go conventions and best practices
- Maintain test coverage
- Write clear, self-documenting code
- Update documentation for API changes
- Run `make check` before committing

## ๐Ÿ“„ License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.