diff --git a/docs/design/README.md b/docs/design/README.md new file mode 100644 index 0000000..60901e1 --- /dev/null +++ b/docs/design/README.md @@ -0,0 +1,9 @@ + +## How to convert swagger.yaml to a html file + + +``` +cd docs/design +npm install -g redoc-cli +redoc-cli bundle swagger.yaml +``` \ No newline at end of file diff --git a/docs/design/api/redoc-static.html b/docs/design/api/redoc-static.html new file mode 100644 index 0000000..6fb3e96 --- /dev/null +++ b/docs/design/api/redoc-static.html @@ -0,0 +1,2192 @@ + + + + + + Crowd-Sourced Racing Events + + + + + + + + + +

Crowd-Sourced Racing Events (0.1.9)

Download OpenAPI specification:Download

This is the blueprint for the API used in this service.

+

Create a user profile.

Create a user profile.

+
Request Body schema: application/json
username
required
string
email
required
string <email>
full_name
required
string

Responses

Request samples

Content type
application/json
{
  • "username": "alexrunner",
  • "email": "alex@example.com",
  • "full_name": "Alex Runner"
}

Response samples

Content type
application/json
{
  • "user_id": "firebase-uid-123",
  • "username": "alexrunner",
  • "email": "alex@example.com",
  • "full_name": "Alex Runner",
  • "created_at": "2025-10-21T04:20:00Z",
  • "updated_at": "2025-10-22T04:20:00Z"
}

Retrieve a user profile

Retrieve a user profile

+
path Parameters
user_id
required
string

Responses

Response samples

Content type
application/json
{
  • "user_id": "firebase-uid-123",
  • "username": "alexrunner",
  • "email": "alex@example.com",
  • "full_name": "Alex Runner",
  • "created_at": "2025-10-21T04:20:00Z",
  • "updated_at": "2025-10-22T04:20:00Z"
}

Update a user profile.

Update a user profile.

+
path Parameters
user_id
required
string
Request Body schema: application/json
username
string
email
string <email>
full_name
string

Responses

Request samples

Content type
application/json
{
  • "username": "alexrunner",
  • "email": "alex@example.com",
  • "full_name": "Alex Runner"
}

Response samples

Content type
application/json
{
  • "user_id": "firebase-uid-123",
  • "username": "alexrunner",
  • "email": "alex@example.com",
  • "full_name": "Alex Runner",
  • "created_at": "2025-10-21T04:20:00Z",
  • "updated_at": "2025-10-22T04:20:00Z"
}
+ + + + \ No newline at end of file diff --git a/docs/design/api/swagger.yaml b/docs/design/api/swagger.yaml new file mode 100644 index 0000000..dfe229e --- /dev/null +++ b/docs/design/api/swagger.yaml @@ -0,0 +1,347 @@ +openapi: 3.0.0 +info: + title: Crowd-Sourced Racing Events + description: This is the blueprint for the API used in this service. + version: 0.1.9 +servers: + - url: http://api.example.com/v1 + description: TBD +paths: + # Craete a user profile [#US5] + /users: + post: + description: Create a user profile. + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UsersCreateRequest' + examples: + UsersCreateExample: + $ref: '#/components/examples/UsersCreateExample' + responses: + '201': + description: User profile created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/UsersResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/UsersResponseExample' + '400': + description: Invalid request data + content: + application/json: + schema: + $ref: '#/components/schemas/BadRequestResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/BadRequestExample' + '401': + description: Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/UnauthorizedExample' + '409': + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/ConflictResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/ConflictExample' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/InternalServiceErrorResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/InternalServerErrorExample' + # Get a user profile [#US6] + /users/{user_id}: + get: + description: Retrieve a user profile + parameters: + - name: user_id + in: path + required: true + schema: + type: string + responses: + '200': + description: User successfully retrived + content: + application/json: + schema: + $ref: '#/components/schemas/UsersResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/UsersResponseExample' + '400': + description: Invalid request data + content: + application/json: + schema: + $ref: '#/components/schemas/BadRequestResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/BadRequestExample' + '401': + description: Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/UnauthorizedExample' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/NotFoundResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/NotFoundExample' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/InternalServiceErrorResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/InternalServerErrorExample' + # Update a user profile [#US6] + put: + description: Update a user profile. + parameters: + - name: user_id + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UsersUpdateRequest' + examples: + UsersUpdateExample: + $ref: '#/components/examples/UsersUpdateExample' + responses: + '200': + description: User successfully updated + content: + application/json: + schema: + $ref: '#/components/schemas/UsersResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/UsersResponseExample' + '400': + description: Invalid request data + content: + application/json: + schema: + $ref: '#/components/schemas/BadRequestResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/BadRequestExample' + '401': + description: Authentication required + content: + application/json: + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/UnauthorizedExample' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/NotFoundResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/NotFoundExample' + '409': + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/ConflictResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/ConflictExample' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/InternalServiceErrorResponse' + examples: + UsersResponseExample: + $ref: '#/components/examples/InternalServerErrorExample' + # delete a user profile [TBD] + delete: + description: (TBD) Delete a user profile. + parameters: + - name: user_id + in: path + required: true + schema: + type: string + responses: + '204': + description: User successfully deleted + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + description: | + Use the ID token issued by Firebase Authentication. + Please include it in the Authorization header in the following format: + `Authorization: Bearer ` + schemas: + UsersCreateRequest: + type: object + properties: + username: + type: string + email: + type: string + format: email + full_name: + type: string + required: + - username + - email + UsersUpdateRequest: + type: object + properties: + username: + type: string + email: + type: string + format: email + full_name: + type: string + UsersResponse: + type: object + properties: + user_id: + type: string + username: + type: string + email: + type: string + format: email + full_name: + type: string + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + BadRequestResponse: + type: object + properties: + error: + type: string + message: + type: string + UnauthorizedResponse: + type: object + properties: + error: + type: string + message: + type: string + NotFoundResponse: + type: object + properties: + error: + type: string + message: + type: string + ConflictResponse: + type: object + properties: + error: + type: string + message: + type: string + InternalServiceErrorResponse: + type: object + properties: + error: + type: string + message: + type: string + + examples: + UsersCreateExample: + summary: Example of creating a new user + value: + username: "alexrunner" + email: "alex@example.com" + full_name: "Alex Runner" + UsersUpdateExample: + summary: Example of updating a user profile + value: + username: "alexrunner" + email: "alex@example.com" + full_name: "Alex Runner" + UsersResponseExample: + summary: Example of user creation request + value: + user_id: "firebase-uid-123" + username: "alexrunner" + email: "alex@example.com" + full_name: "Alex Runner" + created_at: "2025-10-21T04:20:00Z" + updated_at: "2025-10-22T04:20:00Z" + avatar_url: "https://..." + BadRequestExample: + summary: 400 Bad Request + value: + error: "BadRequest" + message: "Missing required field 'xxxxxx'." + UnauthorizedExample: + summary: 401 Unauthorized + value: + error: "Unauthorized" + message: "Authentication token is missing or invalid." + NotFoundExample: + summary: 404 Not Found + value: + error: "NotFound" + message: "The specified resource does not exist." + ConflictExample: + summary: 409 Conflict error + value: + error: "Conflict" + message: "The same resource already exists." + InternalServerErrorExample: + summary: Internal Server Error + value: + error: "Internal Server Error" + message: "An unexpected error occurred while processing the request." + +security: + - bearerAuth: [] \ No newline at end of file