Skip to content

platform-openapi

Multi-tenant Swagger/OpenAPI documentation system with feature-scoped discovery, customizable themes, and automatic endpoint registration.

Package: @breadstone/archipel-platform-openapi

npm install @breadstone/archipel-platform-openapi

Quick Start

typescript
import { Module, Controller, Get, Param } from '@nestjs/common';
import { SwaggerFeature, Api } from '@breadstone/archipel-platform-openapi';

@SwaggerFeature({
  name: 'users',
  title: 'My App API — Users',
  description: 'User CRUD and profile operations.',
  tag: 'Users',
  tags: ['Users'],
})
@Module({
  controllers: [UserController],
})
export class UserModule {}

@Controller('api/v1/users')
export class UserController {
  @Api({
    tags: 'Users',
    summary: 'Get user by ID',
    responses: [{ status: 200, description: 'User found', type: UserResponse }],
  })
  @Get(':id')
  public async getUser(@Param('id') id: string): Promise<UserResponse> {
    // ...
  }
}

Feature-Scoped Documentation

The key concept is per-feature Swagger documents — each feature or module gets its own Swagger UI page, so teams can work independently without cluttering a single monolithic spec.

@SwaggerFeature Decorator

Associates a module with a named feature group:

typescript
import { SwaggerFeature } from '@breadstone/archipel-platform-openapi';

@SwaggerFeature({
  name: 'orders',
  title: 'My App API — Orders',
  description: 'Order management and fulfillment.',
  tag: 'Orders',
  tags: ['Orders'],
})
@Module({
  controllers: [OrderController],
})
export class OrderModule {}

@Api Decorator

Enriches individual endpoints with OpenAPI metadata:

typescript
import { Api } from '@breadstone/archipel-platform-openapi';

@Api({
    summary: 'Create a new order',
    operation: { description: 'Creates an order and initiates payment processing.' },
    responses: [
        { status: 201, description: 'Order created successfully' },
        { status: 400, description: 'Invalid order data' },
        { status: 402, description: 'Payment required' },
    ],
})
@Post()
public async createOrder(@Body() body: CreateOrderDto): Promise<OrderResponse> { /* ... */ }

Multi-Document Service

Generate separate Swagger documents per feature:

typescript
import { SwaggerMultiDocumentService } from '@breadstone/archipel-platform-openapi';

@Injectable()
export class DocsController {
  constructor(private readonly _swaggerDocs: SwaggerMultiDocumentService) {}

  public generateAll(): Map<string, OpenAPIObject> {
    return this._swaggerDocs.generateAll();
    // Returns a map: 'User Management' → OpenAPI spec, 'Orders' → OpenAPI spec, ...
  }
}

Bootstrap Setup

typescript
import {
  SwaggerFeatureDiscovery,
  SwaggerFeatureRegistry,
  SwaggerMultiDocumentService,
} from '@breadstone/archipel-platform-openapi';
import { ConfigService, ContentTemplateEngine, HostService, ResourceManager } from '@breadstone/archipel-platform-core';

async function bootstrap(): Promise<void> {
  const app = await NestFactory.create(AppModule);

  const configService = app.get(ConfigService);
  const hostService = app.get(HostService);
  const resourceManager = app.get(ResourceManager);
  const contentTemplateEngine = app.get(ContentTemplateEngine);

  // 1. Discover features
  const featureRegistry = new SwaggerFeatureRegistry();
  const discovery = new SwaggerFeatureDiscovery();
  discovery.registerDiscoveredFeatures(featureRegistry);
  discovery.registerDefaultFeatures(featureRegistry);

  // 2. Setup multi-document Swagger UI
  const swaggerService = new SwaggerMultiDocumentService(
    app,
    configService,
    hostService,
    featureRegistry,
    resourceManager,
    contentTemplateEngine,
  );
  await swaggerService.setupMultipleSwaggerDocuments();

  await app.listen(3000);
}

Discovery & Registry

SwaggerFeatureDiscovery

Reads the global store populated by @SwaggerFeature() decorators and registers features into a SwaggerFeatureRegistry:

typescript
import { SwaggerFeatureDiscovery, SwaggerFeatureRegistry } from '@breadstone/archipel-platform-openapi';

const featureRegistry = new SwaggerFeatureRegistry();
const discovery = new SwaggerFeatureDiscovery();

discovery
  .registerDiscoveredFeatures(featureRegistry)
  .registerDefaultFeatures(featureRegistry);

SwaggerFeatureRegistry

Holds the finalized, immutable list of features. After all features are registered, call finalize():

typescript
import { SwaggerFeatureRegistry } from '@breadstone/archipel-platform-openapi';

const registry = new SwaggerFeatureRegistry();

registry.registerFeature({
  name: 'admin',
  title: 'My App API — Admin',
  description: 'Admin-only endpoints.',
  tag: 'Admin',
  tags: ['Admin'],
  path: 'docs/admin',
});

registry.finalize();
const features = registry.getFeatures(); // sorted, read-only copy

Exports Summary

ExportTypeDescription
ApiDecoratorOpenAPI endpoint metadata
SwaggerFeatureDecoratorFeature-scoped Swagger grouping
SwaggerFeatureDiscoveryServiceAuto-discover features
SwaggerFeatureRegistryServiceManage feature configs
SwaggerMultiDocumentServiceServiceGenerate per-feature specs
SwaggerThemeUtilityTheme customization (CSS/JS cached after first load)
IFeatureSwaggerConfigInterfaceFeature config shape

Released under the MIT License.