All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 15m54s
229 lines
5.9 KiB
TypeScript
229 lines
5.9 KiB
TypeScript
// src/config/swagger.ts
|
|
/**
|
|
* @file OpenAPI/Swagger configuration for API documentation.
|
|
* Implements ADR-018: API Documentation Strategy.
|
|
*
|
|
* This file configures swagger-jsdoc to generate an OpenAPI 3.0 specification
|
|
* from JSDoc annotations in route files. The specification is used by
|
|
* swagger-ui-express to serve interactive API documentation.
|
|
*/
|
|
import swaggerJsdoc from 'swagger-jsdoc';
|
|
|
|
const options: swaggerJsdoc.Options = {
|
|
definition: {
|
|
openapi: '3.0.0',
|
|
info: {
|
|
title: 'Flyer Crawler API',
|
|
version: '1.0.0',
|
|
description:
|
|
'API for the Flyer Crawler application - a platform for discovering grocery deals, managing recipes, and tracking budgets.',
|
|
contact: {
|
|
name: 'API Support',
|
|
},
|
|
license: {
|
|
name: 'Private',
|
|
},
|
|
},
|
|
servers: [
|
|
{
|
|
url: '/api',
|
|
description: 'API server',
|
|
},
|
|
],
|
|
components: {
|
|
securitySchemes: {
|
|
bearerAuth: {
|
|
type: 'http',
|
|
scheme: 'bearer',
|
|
bearerFormat: 'JWT',
|
|
description: 'JWT token obtained from /auth/login or /auth/register',
|
|
},
|
|
},
|
|
schemas: {
|
|
// Standard success response wrapper (ADR-028)
|
|
SuccessResponse: {
|
|
type: 'object',
|
|
properties: {
|
|
success: {
|
|
type: 'boolean',
|
|
example: true,
|
|
},
|
|
data: {
|
|
type: 'object',
|
|
description: 'Response payload - structure varies by endpoint',
|
|
},
|
|
},
|
|
required: ['success', 'data'],
|
|
},
|
|
// Standard error response wrapper (ADR-028)
|
|
ErrorResponse: {
|
|
type: 'object',
|
|
properties: {
|
|
success: {
|
|
type: 'boolean',
|
|
example: false,
|
|
},
|
|
error: {
|
|
type: 'object',
|
|
properties: {
|
|
code: {
|
|
type: 'string',
|
|
description: 'Machine-readable error code',
|
|
example: 'VALIDATION_ERROR',
|
|
},
|
|
message: {
|
|
type: 'string',
|
|
description: 'Human-readable error message',
|
|
example: 'Invalid request parameters',
|
|
},
|
|
},
|
|
required: ['code', 'message'],
|
|
},
|
|
},
|
|
required: ['success', 'error'],
|
|
},
|
|
// Common service health status
|
|
ServiceHealth: {
|
|
type: 'object',
|
|
properties: {
|
|
status: {
|
|
type: 'string',
|
|
enum: ['healthy', 'degraded', 'unhealthy'],
|
|
},
|
|
latency: {
|
|
type: 'number',
|
|
description: 'Response time in milliseconds',
|
|
},
|
|
message: {
|
|
type: 'string',
|
|
description: 'Additional status information',
|
|
},
|
|
details: {
|
|
type: 'object',
|
|
description: 'Service-specific details',
|
|
},
|
|
},
|
|
required: ['status'],
|
|
},
|
|
// Achievement schema
|
|
Achievement: {
|
|
type: 'object',
|
|
properties: {
|
|
achievement_id: {
|
|
type: 'integer',
|
|
example: 1,
|
|
},
|
|
name: {
|
|
type: 'string',
|
|
example: 'First-Upload',
|
|
},
|
|
description: {
|
|
type: 'string',
|
|
example: 'Upload your first flyer',
|
|
},
|
|
icon: {
|
|
type: 'string',
|
|
example: 'upload-cloud',
|
|
},
|
|
points_value: {
|
|
type: 'integer',
|
|
example: 25,
|
|
},
|
|
created_at: {
|
|
type: 'string',
|
|
format: 'date-time',
|
|
},
|
|
},
|
|
},
|
|
// User achievement (with achieved_at)
|
|
UserAchievement: {
|
|
allOf: [
|
|
{ $ref: '#/components/schemas/Achievement' },
|
|
{
|
|
type: 'object',
|
|
properties: {
|
|
user_id: {
|
|
type: 'string',
|
|
format: 'uuid',
|
|
},
|
|
achieved_at: {
|
|
type: 'string',
|
|
format: 'date-time',
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
// Leaderboard entry
|
|
LeaderboardUser: {
|
|
type: 'object',
|
|
properties: {
|
|
user_id: {
|
|
type: 'string',
|
|
format: 'uuid',
|
|
},
|
|
full_name: {
|
|
type: 'string',
|
|
example: 'John Doe',
|
|
},
|
|
avatar_url: {
|
|
type: 'string',
|
|
nullable: true,
|
|
},
|
|
points: {
|
|
type: 'integer',
|
|
example: 150,
|
|
},
|
|
rank: {
|
|
type: 'integer',
|
|
example: 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
tags: [
|
|
{
|
|
name: 'Health',
|
|
description: 'Server health and readiness checks',
|
|
},
|
|
{
|
|
name: 'Auth',
|
|
description: 'Authentication and authorization',
|
|
},
|
|
{
|
|
name: 'Users',
|
|
description: 'User profile management',
|
|
},
|
|
{
|
|
name: 'Achievements',
|
|
description: 'Gamification and leaderboards',
|
|
},
|
|
{
|
|
name: 'Flyers',
|
|
description: 'Flyer uploads and retrieval',
|
|
},
|
|
{
|
|
name: 'Recipes',
|
|
description: 'Recipe management',
|
|
},
|
|
{
|
|
name: 'Budgets',
|
|
description: 'Budget tracking and analysis',
|
|
},
|
|
{
|
|
name: 'Admin',
|
|
description: 'Administrative operations (requires admin role)',
|
|
},
|
|
{
|
|
name: 'System',
|
|
description: 'System status and monitoring',
|
|
},
|
|
],
|
|
},
|
|
// Path to the API routes files with JSDoc annotations
|
|
apis: ['./src/routes/*.ts'],
|
|
};
|
|
|
|
export const swaggerSpec = swaggerJsdoc(options);
|