# Getting Started with @nestjsvn/swagger-sse

This guide will help you get up and running with `@nestjsvn/swagger-sse` in your NestJS application.

## Table of Contents

1. [Installation](#installation)
2. [Basic Setup](#basic-setup)
3. [Creating Your First SSE Endpoint](#creating-your-first-sse-endpoint)
4. [Using the CLI Plugin](#using-the-cli-plugin)
5. [Swagger UI Integration](#swagger-ui-integration)
6. [Advanced Configuration](#advanced-configuration)
7. [Testing Your Implementation](#testing-your-implementation)
8. [Troubleshooting](#troubleshooting)

## Installation

Install the package using npm or yarn:

```bash
npm install @nestjsvn/swagger-sse
# or
yarn add @nestjsvn/swagger-sse
```

### Peer Dependencies

Make sure you have the required peer dependencies installed:

```bash
npm install @nestjs/common @nestjs/swagger
# or
yarn add @nestjs/common @nestjs/swagger
```

## Basic Setup

### 1. Update Your Main Application File

Replace the standard `SwaggerModule.setup()` with `setupSsePlugin()`:

```typescript
// main.ts
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { setupSsePlugin } from '@nestjsvn/swagger-sse';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('My API')
    .setDescription('API with SSE support')
    .setVersion('1.0')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  
  // Use setupSsePlugin instead of SwaggerModule.setup
  setupSsePlugin(app, document, 'api-docs');

  await app.listen(3000);
}
bootstrap();
```

### 2. Enable CORS (if needed)

If your frontend is on a different domain, enable CORS:

```typescript
// main.ts
app.enableCors({
  origin: ['http://localhost:3000', 'https://yourdomain.com'],
  credentials: true,
});
```

## Creating Your First SSE Endpoint

### 1. Define Your Event DTOs

Create TypeScript classes for your event data:

```typescript
// events/dto/user-events.dto.ts
export class UserCreatedDto {
  userId: string;
  username: string;
  email: string;
  createdAt: Date;
}

export class UserUpdatedDto {
  userId: string;
  username: string;
  email: string;
  updatedAt: Date;
}
```

### 2. Create Your SSE Controller

```typescript
// events/events.controller.ts
import { Controller, Sse } from '@nestjs/common';
import { Observable, interval, map } from 'rxjs';
import { ApiSse } from '@nestjsvn/swagger-sse';
import { UserCreatedDto, UserUpdatedDto } from './dto/user-events.dto';

@Controller('events')
export class EventsController {
  @Sse('user-stream')
  @ApiSse({
    summary: 'User events stream',
    description: 'Real-time stream of user-related events',
    events: {
      'user-created': UserCreatedDto,
      'user-updated': UserUpdatedDto,
    },
  })
  streamUserEvents(): Observable<MessageEvent> {
    return interval(2000).pipe(
      map((i) => ({
        data: JSON.stringify({
          userId: `user-${i}`,
          username: `User${i}`,
          email: `user${i}@example.com`,
          createdAt: new Date(),
        }),
        type: 'user-created',
      } as MessageEvent))
    );
  }
}
```

### 3. Register Your Controller

```typescript
// app.module.ts
import { Module } from '@nestjs/common';
import { EventsController } from './events/events.controller';

@Module({
  controllers: [EventsController],
})
export class AppModule {}
```

## Using the CLI Plugin

For automatic documentation generation, enable the CLI plugin:

### 1. Update nest-cli.json

```json
{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "deleteOutDir": true,
    "plugins": [
      "@nestjs/swagger",
      {
        "name": "@nestjsvn/swagger-sse/plugin",
        "options": {
          "eventNamingConvention": "kebab-case",
          "introspectComments": true
        }
      }
    ]
  }
}
```

### 2. Use Zero-Configuration Endpoints

With the plugin enabled, you can create SSE endpoints without explicit `@ApiSse` decorators:

```typescript
@Controller('notifications')
export class NotificationsController {
  /**
   * Streams notification events
   * @summary Real-time notification stream
   * @description Provides live updates for user notifications
   */
  @Sse('updates')
  streamNotifications(): Observable<MessageEvent<NotificationDto>> {
    // The plugin will automatically generate documentation
    // based on the return type and JSDoc comments
    return this.notificationService.getStream();
  }
}
```

## Swagger UI Integration

### 1. Access Your Documentation

Navigate to `http://localhost:3000/api-docs` to see your Swagger UI with SSE support.

### 2. Using the SSE Interface

1. **Find your SSE endpoint** in the Swagger UI
2. **Expand the endpoint** to see the SSE-specific interface
3. **Click "Connect"** to establish the SSE connection
4. **View real-time events** in the event log
5. **Disconnect** when finished

### 3. SSE-Specific UI Elements

The enhanced Swagger UI includes:

- **Connection Status Indicator**: Shows connected/disconnected/error states
- **Connect/Disconnect Buttons**: Control SSE connection
- **Real-time Event Log**: Displays incoming events with timestamps
- **Event Type Filtering**: Filter events by type
- **Clear Log Button**: Clear the event history
- **JSON Formatting**: Pretty-printed event data

## Advanced Configuration

### 1. Custom Event Types

Handle complex event scenarios:

```typescript
@ApiSse({
  summary: 'Multi-type event stream',
  events: {
    'user-created': UserCreatedDto,
    'user-updated': UserUpdatedDto,
    'user-deleted': { userId: string },
    'system-alert': SystemAlertDto,
  },
  defaultEvent: GenericEventDto,
})
streamEvents(): Observable<MessageEvent> {
  return merge(
    this.userEvents$,
    this.systemEvents$,
    this.alertEvents$
  );
}
```

### 2. Authentication

Secure your SSE endpoints:

```typescript
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
@ApiSse({
  summary: 'Authenticated event stream',
  security: [{ bearer: [] }],
  events: {
    'private-event': PrivateEventDto,
  },
})
streamPrivateEvents(@Request() req): Observable<MessageEvent> {
  return this.eventService.getPrivateEvents(req.user.id);
}
```

### 3. Query Parameters

Filter events based on parameters:

```typescript
@ApiSse({
  summary: 'Filtered event stream',
  events: {
    'filtered-event': FilteredEventDto,
  },
})
streamFilteredEvents(
  @Query('userId') userId?: string,
  @Query('eventType') eventType?: string,
): Observable<MessageEvent> {
  return this.eventService.getFilteredEvents({ userId, eventType });
}
```

### 4. Error Handling

Include error events in your stream:

```typescript
@ApiSse({
  events: {
    'data-update': DataUpdateDto,
    'error': ErrorEventDto,
  },
})
streamWithErrorHandling(): Observable<MessageEvent> {
  return this.dataService.watchData().pipe(
    map(data => ({ type: 'data-update', data: JSON.stringify(data) })),
    catchError(error => of({ 
      type: 'error', 
      data: JSON.stringify({ message: error.message, code: error.code }) 
    }))
  );
}
```

## Testing Your Implementation

### 1. Manual Testing

1. Start your application: `npm run start:dev`
2. Open Swagger UI: `http://localhost:3000/api-docs`
3. Test SSE endpoints using the interactive interface

### 2. Automated Testing

Run the included test suites:

```bash
# Unit tests
npm run test

# Unit tests with watch mode
npm run test:watch

# Test coverage
npm run test:coverage
```

**Note**: E2E and performance testing infrastructure is planned but not yet implemented in the current package.json scripts. The project currently focuses on comprehensive unit testing.

## Troubleshooting

### Common Issues

#### 1. SSE Connection Fails

**Problem**: Connection button shows error state immediately.

**Solutions**:
- Check that your SSE endpoint is accessible
- Verify CORS configuration if frontend is on different domain
- Ensure the endpoint returns proper `text/event-stream` content type

#### 2. Events Not Appearing

**Problem**: Connection succeeds but no events are displayed.

**Solutions**:
- Verify your Observable is emitting MessageEvent objects
- Check that event data is properly JSON stringified
- Ensure event types match those defined in `@ApiSse`

#### 3. Plugin Not Working

**Problem**: Automatic documentation generation isn't working.

**Solutions**:
- Verify `nest-cli.json` configuration
- Ensure plugin is listed after `@nestjs/swagger`
- Check TypeScript compilation for errors

#### 4. Performance Issues

**Problem**: UI becomes slow with many events.

**Solutions**:
- Implement event log size limits
- Use event filtering
- Consider pagination for historical events

### Getting Help

- **Documentation**: Check the [API Reference](./api-reference.md)
- **Examples**: See the [examples directory](../examples/)
- **Issues**: Report bugs on [GitHub Issues](https://github.com/nestjsx/swagger-sse/issues)
- **Discussions**: Join [GitHub Discussions](https://github.com/nestjsx/swagger-sse/discussions)

## Next Steps

- Explore [Advanced Usage Patterns](./advanced-usage.md)
- Learn about [Performance Optimization](./performance.md)
- Check out [Real-world Examples](../examples/)
- Read the [API Reference](./api-reference.md)