Compare commits
10 Commits
9094d12c3a
...
4cdfe753c8
Author | SHA1 | Date | |
---|---|---|---|
|
4cdfe753c8 | ||
|
332871d403 | ||
|
c00cbf35f1 | ||
|
1d753783ce | ||
|
a6abdf504d | ||
|
426471d3b1 | ||
|
8edea3f0b8 | ||
|
d7b007b851 | ||
|
8f9e552696 | ||
|
28bc869c64 |
2
Makefile
2
Makefile
@ -42,7 +42,7 @@ format: # format code.
|
|||||||
|
|
||||||
.PHONY: add-copyright
|
.PHONY: add-copyright
|
||||||
add-copyright: # add license to file headers.
|
add-copyright: # add license to file headers.
|
||||||
@addlicense -v -f $(ROOT_DIR)/LICENSE $(ROOT_DIR) --skip-files=database.yml --skip-dirs=$(OUTPUT_DIR),deployment,migrations,configs
|
@addlicense -v -f $(ROOT_DIR)/LICENSE $(ROOT_DIR) --skip-files=database.yml --skip-dirs=$(OUTPUT_DIR),deployment,migrations,configs,sqlc
|
||||||
|
|
||||||
.PHONY: swagger
|
.PHONY: swagger
|
||||||
swagger: # Run swagger.
|
swagger: # Run swagger.
|
||||||
|
@ -197,3 +197,10 @@ type User struct {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Use Buffalo pop `Soda CLI` to create database migrations.
|
Use Buffalo pop `Soda CLI` to create database migrations.
|
||||||
|
|
||||||
|
### 2024/10/07
|
||||||
|
|
||||||
|
Implement the architecture design for User entity.
|
||||||
|
|
||||||
|
Checked out OpenAPI, and found that it was not that simple at all. It needs
|
||||||
|
a whole package of knowledge about the web development!
|
||||||
|
828
api/openapi/openapi-example.yaml
Normal file
828
api/openapi/openapi-example.yaml
Normal file
@ -0,0 +1,828 @@
|
|||||||
|
# MIT License
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
swagger: "2.0"
|
||||||
|
openapi: 3.1.0
|
||||||
|
info:
|
||||||
|
title: Swagger Petstore - OpenAPI 3.1
|
||||||
|
description: |-
|
||||||
|
This is a sample Pet Store Server based on the OpenAPI 3.1 specification. You can find out more about
|
||||||
|
Swagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!
|
||||||
|
You can now help us improve the API whether it's by making changes to the definition itself or to the code.
|
||||||
|
That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
|
||||||
|
|
||||||
|
Some useful links:
|
||||||
|
- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
|
||||||
|
- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
|
||||||
|
|
||||||
|
termsOfService: http://swagger.io/terms/
|
||||||
|
contact:
|
||||||
|
email: apiteam@swagger.io
|
||||||
|
license:
|
||||||
|
name: Apache 2.0
|
||||||
|
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
version: 1.0.11
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about Swagger
|
||||||
|
url: http://swagger.io
|
||||||
|
servers:
|
||||||
|
- url: https://petstore3.swagger.io/api/v3
|
||||||
|
tags:
|
||||||
|
- name: pet
|
||||||
|
description: Everything about your Pets
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more
|
||||||
|
url: http://swagger.io
|
||||||
|
- name: store
|
||||||
|
description: Access to Petstore orders
|
||||||
|
externalDocs:
|
||||||
|
description: Find out more about our store
|
||||||
|
url: http://swagger.io
|
||||||
|
- name: user
|
||||||
|
description: Operations about user
|
||||||
|
paths:
|
||||||
|
/pet:
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Update an existing pet
|
||||||
|
description: Update an existing pet by Id
|
||||||
|
operationId: updatePet
|
||||||
|
requestBody:
|
||||||
|
description: Update an existent pet in the store
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Add a new pet to the store
|
||||||
|
description: Add a new pet to the store
|
||||||
|
operationId: addPet
|
||||||
|
requestBody:
|
||||||
|
description: Create a new pet in the store
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/findByStatus:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Finds Pets by status
|
||||||
|
description: Multiple status values can be provided with comma separated strings
|
||||||
|
operationId: findPetsByStatus
|
||||||
|
parameters:
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
description: Status values that need to be considered for filter
|
||||||
|
required: false
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
default: available
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid status value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/findByTags:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Finds Pets by tags
|
||||||
|
description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
|
||||||
|
operationId: findPetsByTags
|
||||||
|
parameters:
|
||||||
|
- name: tags
|
||||||
|
in: query
|
||||||
|
description: Tags to filter by
|
||||||
|
required: false
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid tag value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/{petId}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Find pet by ID
|
||||||
|
description: Returns a single pet
|
||||||
|
operationId: getPetById
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to return
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Pet not found
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Updates a pet in the store with form data
|
||||||
|
description: ''
|
||||||
|
operationId: updatePetWithForm
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet that needs to be updated
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: name
|
||||||
|
in: query
|
||||||
|
description: Name of pet that needs to be updated
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
description: Status of pet that needs to be updated
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: Deletes a pet
|
||||||
|
description: delete a pet
|
||||||
|
operationId: deletePet
|
||||||
|
parameters:
|
||||||
|
- name: api_key
|
||||||
|
in: header
|
||||||
|
description: ''
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: Pet id to delete
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid pet value
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/pet/{petId}/uploadImage:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- pet
|
||||||
|
summary: uploads an image
|
||||||
|
description: ''
|
||||||
|
operationId: uploadFile
|
||||||
|
parameters:
|
||||||
|
- name: petId
|
||||||
|
in: path
|
||||||
|
description: ID of pet to update
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
- name: additionalMetadata
|
||||||
|
in: query
|
||||||
|
description: Additional Metadata
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/octet-stream:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
security:
|
||||||
|
- petstore_auth:
|
||||||
|
- write:pets
|
||||||
|
- read:pets
|
||||||
|
/store/inventory:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Returns pet inventories by status
|
||||||
|
description: Returns a map of status codes to quantities
|
||||||
|
operationId: getInventory
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
security:
|
||||||
|
- api_key: []
|
||||||
|
/store/order:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Place an order for a pet
|
||||||
|
description: Place a new order in the store
|
||||||
|
operationId: placeOrder
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'422':
|
||||||
|
description: Validation exception
|
||||||
|
/store/order/{orderId}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Find purchase order by ID
|
||||||
|
description: For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.
|
||||||
|
operationId: getOrderById
|
||||||
|
parameters:
|
||||||
|
- name: orderId
|
||||||
|
in: path
|
||||||
|
description: ID of order that needs to be fetched
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Order'
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Order not found
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- store
|
||||||
|
summary: Delete purchase order by ID
|
||||||
|
description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
|
||||||
|
operationId: deleteOrder
|
||||||
|
parameters:
|
||||||
|
- name: orderId
|
||||||
|
in: path
|
||||||
|
description: ID of the order that needs to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid ID supplied
|
||||||
|
'404':
|
||||||
|
description: Order not found
|
||||||
|
/user:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Create user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: createUser
|
||||||
|
requestBody:
|
||||||
|
description: Created user object
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
/user/createWithList:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Creates list of users with given input array
|
||||||
|
description: Creates list of users with given input array
|
||||||
|
operationId: createUsersWithListInput
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
/user/login:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs user into the system
|
||||||
|
description: ''
|
||||||
|
operationId: loginUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: query
|
||||||
|
description: The user name for login
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: password
|
||||||
|
in: query
|
||||||
|
description: The password for login in clear text
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
headers:
|
||||||
|
X-Rate-Limit:
|
||||||
|
description: calls per hour allowed by the user
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
X-Expires-After:
|
||||||
|
description: date in UTC when token expires
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
'400':
|
||||||
|
description: Invalid username/password supplied
|
||||||
|
/user/logout:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Logs out current logged in user session
|
||||||
|
description: ''
|
||||||
|
operationId: logoutUser
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
/user/{username}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Get user by user name
|
||||||
|
description: ''
|
||||||
|
operationId: getUserByName
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: 'The name that needs to be fetched. Use user1 for testing. '
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Update user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: updateUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: name that need to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: Update an existent user in the store
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
application/x-www-form-urlencoded:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
responses:
|
||||||
|
default:
|
||||||
|
description: successful operation
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- user
|
||||||
|
summary: Delete user
|
||||||
|
description: This can only be done by the logged in user.
|
||||||
|
operationId: deleteUser
|
||||||
|
parameters:
|
||||||
|
- name: username
|
||||||
|
in: path
|
||||||
|
description: The name that needs to be deleted
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'400':
|
||||||
|
description: Invalid username supplied
|
||||||
|
'404':
|
||||||
|
description: User not found
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Order:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
examples: [10]
|
||||||
|
petId:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
examples: [198772]
|
||||||
|
quantity:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
examples: [7]
|
||||||
|
shipDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Order Status
|
||||||
|
examples: [approved]
|
||||||
|
enum:
|
||||||
|
- placed
|
||||||
|
- approved
|
||||||
|
- delivered
|
||||||
|
complete:
|
||||||
|
type: boolean
|
||||||
|
xml:
|
||||||
|
name: order
|
||||||
|
Customer:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
examples: [100000]
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
examples: [fehguy]
|
||||||
|
address:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
name: addresses
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Address'
|
||||||
|
xml:
|
||||||
|
name: customer
|
||||||
|
Address:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
street:
|
||||||
|
type: string
|
||||||
|
examples: [437 Lytton]
|
||||||
|
city:
|
||||||
|
type: string
|
||||||
|
examples: [Palo Alto]
|
||||||
|
state:
|
||||||
|
type: string
|
||||||
|
examples: [CA]
|
||||||
|
zip:
|
||||||
|
type: string
|
||||||
|
examples: ['94301']
|
||||||
|
xml:
|
||||||
|
name: address
|
||||||
|
Category:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
examples: [1]
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
examples: [Dogs]
|
||||||
|
xml:
|
||||||
|
name: category
|
||||||
|
User:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
examples: [10]
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
examples: [theUser]
|
||||||
|
firstName:
|
||||||
|
type: string
|
||||||
|
examples: [John]
|
||||||
|
lastName:
|
||||||
|
type: string
|
||||||
|
examples: [James]
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
examples: [john@email.com]
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
examples: ['12345']
|
||||||
|
phone:
|
||||||
|
type: string
|
||||||
|
examples: ['12345']
|
||||||
|
userStatus:
|
||||||
|
type: integer
|
||||||
|
description: User Status
|
||||||
|
format: int32
|
||||||
|
examples: [1]
|
||||||
|
xml:
|
||||||
|
name: user
|
||||||
|
Tag:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: tag
|
||||||
|
Pet:
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- photoUrls
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
examples: [10]
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
examples: [doggie]
|
||||||
|
category:
|
||||||
|
$ref: '#/components/schemas/Category'
|
||||||
|
photoUrls:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: photoUrl
|
||||||
|
tags:
|
||||||
|
type: array
|
||||||
|
xml:
|
||||||
|
wrapped: true
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Tag'
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: pet status in the store
|
||||||
|
enum:
|
||||||
|
- available
|
||||||
|
- pending
|
||||||
|
- sold
|
||||||
|
xml:
|
||||||
|
name: pet
|
||||||
|
ApiResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: '##default'
|
||||||
|
requestBodies:
|
||||||
|
Pet:
|
||||||
|
description: Pet object that needs to be added to the store
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
UserArray:
|
||||||
|
description: List of user object
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/User'
|
||||||
|
securitySchemes:
|
||||||
|
petstore_auth:
|
||||||
|
type: oauth2
|
||||||
|
flows:
|
||||||
|
implicit:
|
||||||
|
authorizationUrl: https://petstore3.swagger.io/oauth/authorize
|
||||||
|
scopes:
|
||||||
|
write:pets: modify pets in your account
|
||||||
|
read:pets: read your pets
|
||||||
|
api_key:
|
||||||
|
type: apiKey
|
||||||
|
name: api_key
|
||||||
|
in: header
|
@ -21,795 +21,79 @@
|
|||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
|
||||||
swagger: "2.0"
|
swagger: "2.0"
|
||||||
openapi: "3.1.0"
|
openapi: 3.1.0
|
||||||
info:
|
info:
|
||||||
title: Howmuch expense-sharing
|
title: Howmuch Expense-sharing app
|
||||||
description: |-
|
description: |-
|
||||||
A simple web application that can help you share your expense with your
|
A simple web application that can help you share your expense with your
|
||||||
friends.
|
friends.
|
||||||
|
|
||||||
contact:
|
contact:
|
||||||
email: vinchent@vinchent.vinchent
|
email: vinchent@vinchent.xyz
|
||||||
license:
|
license:
|
||||||
name: MIT
|
name: MIT
|
||||||
url: https://opensource.org/license/MIT
|
url: https://opensource.org/license/MIT
|
||||||
version: 0.0.1
|
version: '0.0.1'
|
||||||
# externalDocs:
|
|
||||||
# description: Find out more about Swagger
|
|
||||||
# url: http://swagger.io
|
|
||||||
servers:
|
servers:
|
||||||
- url: http://localhost:8080/v1
|
- url: https:/localhost:8000/v1
|
||||||
tags:
|
tags:
|
||||||
- name: event
|
|
||||||
description: Event with your friends
|
|
||||||
- name: expense
|
|
||||||
description: Who paid how much for whom else
|
|
||||||
- name: user
|
- name: user
|
||||||
description: Operations about user
|
|
||||||
paths:
|
paths:
|
||||||
/event:
|
/signup:
|
||||||
put:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- event
|
- user
|
||||||
summary: Update an existing pet
|
description: Sign up as a new user
|
||||||
description: Update an existing pet by Id
|
|
||||||
operationId: updatePet
|
|
||||||
requestBody:
|
requestBody:
|
||||||
description: Update an existent pet in the store
|
description: Sign up
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Pet'
|
$ref: '#/components/schemas/UserSignUpRequest'
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
application/x-www-form-urlencoded:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
required: true
|
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Successful operation
|
description: Successful operation
|
||||||
|
'400':
|
||||||
|
description: Client side error
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Pet'
|
$ref: '#/components/schemas/ErrResponse'
|
||||||
application/xml:
|
'500':
|
||||||
schema:
|
description: Server side error
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
'400':
|
|
||||||
description: Invalid ID supplied
|
|
||||||
'404':
|
|
||||||
description: Pet not found
|
|
||||||
'422':
|
|
||||||
description: Validation exception
|
|
||||||
security:
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- event
|
|
||||||
summary: Add a new pet to the store
|
|
||||||
description: Add a new pet to the store
|
|
||||||
operationId: addPet
|
|
||||||
requestBody:
|
|
||||||
description: Create a new pet in the store
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
application/x-www-form-urlencoded:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Pet'
|
$ref: '#/components/schemas/ErrResponse'
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
'400':
|
|
||||||
description: Invalid input
|
|
||||||
'422':
|
|
||||||
description: Validation exception
|
|
||||||
security:
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
/event/findByStatus:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- event
|
|
||||||
summary: Finds Pets by status
|
|
||||||
description: Multiple status values can be provided with comma separated strings
|
|
||||||
operationId: findPetsByStatus
|
|
||||||
parameters:
|
|
||||||
- name: status
|
|
||||||
in: query
|
|
||||||
description: Status values that need to be considered for filter
|
|
||||||
required: false
|
|
||||||
explode: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
default: available
|
|
||||||
enum:
|
|
||||||
- available
|
|
||||||
- pending
|
|
||||||
- sold
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
'400':
|
|
||||||
description: Invalid status value
|
|
||||||
security:
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
/event/findByTags:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- event
|
|
||||||
summary: Finds Pets by tags
|
|
||||||
description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
|
|
||||||
operationId: findPetsByTags
|
|
||||||
parameters:
|
|
||||||
- name: tags
|
|
||||||
in: query
|
|
||||||
description: Tags to filter by
|
|
||||||
required: false
|
|
||||||
explode: true
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
'400':
|
|
||||||
description: Invalid tag value
|
|
||||||
security:
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
/event/{eventId}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- event
|
|
||||||
summary: Find pet by ID
|
|
||||||
description: Returns a single pet
|
|
||||||
operationId: getPetById
|
|
||||||
parameters:
|
|
||||||
- name: petId
|
|
||||||
in: path
|
|
||||||
description: ID of pet to return
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
'400':
|
|
||||||
description: Invalid ID supplied
|
|
||||||
'404':
|
|
||||||
description: Pet not found
|
|
||||||
security:
|
|
||||||
- api_key: []
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- event
|
|
||||||
summary: Updates a pet in the store with form data
|
|
||||||
description: ''
|
|
||||||
operationId: updatePetWithForm
|
|
||||||
parameters:
|
|
||||||
- name: petId
|
|
||||||
in: path
|
|
||||||
description: ID of pet that needs to be updated
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
- name: name
|
|
||||||
in: query
|
|
||||||
description: Name of pet that needs to be updated
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: status
|
|
||||||
in: query
|
|
||||||
description: Status of pet that needs to be updated
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'400':
|
|
||||||
description: Invalid input
|
|
||||||
security:
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- event
|
|
||||||
summary: Deletes a pet
|
|
||||||
description: delete a pet
|
|
||||||
operationId: deletePet
|
|
||||||
parameters:
|
|
||||||
- name: api_key
|
|
||||||
in: header
|
|
||||||
description: ''
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: petId
|
|
||||||
in: path
|
|
||||||
description: Pet id to delete
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
responses:
|
|
||||||
'400':
|
|
||||||
description: Invalid pet value
|
|
||||||
security:
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
/event/{eventId}/uploadImage:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- event
|
|
||||||
summary: uploads an image
|
|
||||||
description: ''
|
|
||||||
operationId: uploadFile
|
|
||||||
parameters:
|
|
||||||
- name: petId
|
|
||||||
in: path
|
|
||||||
description: ID of pet to update
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
- name: additionalMetadata
|
|
||||||
in: query
|
|
||||||
description: Additional Metadata
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
application/octet-stream:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: binary
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
|
||||||
security:
|
|
||||||
- petstore_auth:
|
|
||||||
- write:pets
|
|
||||||
- read:pets
|
|
||||||
/expense/inventory:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- expense
|
|
||||||
summary: Returns pet inventories by status
|
|
||||||
description: Returns a map of status codes to quantities
|
|
||||||
operationId: getInventory
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
security:
|
|
||||||
- api_key: []
|
|
||||||
/expense/order:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- expense
|
|
||||||
summary: Place an order for a pet
|
|
||||||
description: Place a new order in the store
|
|
||||||
operationId: placeOrder
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Order'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Order'
|
|
||||||
application/x-www-form-urlencoded:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Order'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Order'
|
|
||||||
'400':
|
|
||||||
description: Invalid input
|
|
||||||
'422':
|
|
||||||
description: Validation exception
|
|
||||||
/expense/order/{orderId}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- expense
|
|
||||||
summary: Find purchase order by ID
|
|
||||||
description: For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.
|
|
||||||
operationId: getOrderById
|
|
||||||
parameters:
|
|
||||||
- name: orderId
|
|
||||||
in: path
|
|
||||||
description: ID of order that needs to be fetched
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Order'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Order'
|
|
||||||
'400':
|
|
||||||
description: Invalid ID supplied
|
|
||||||
'404':
|
|
||||||
description: Order not found
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- expense
|
|
||||||
summary: Delete purchase order by ID
|
|
||||||
description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
|
|
||||||
operationId: deleteOrder
|
|
||||||
parameters:
|
|
||||||
- name: orderId
|
|
||||||
in: path
|
|
||||||
description: ID of the order that needs to be deleted
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
responses:
|
|
||||||
'400':
|
|
||||||
description: Invalid ID supplied
|
|
||||||
'404':
|
|
||||||
description: Order not found
|
|
||||||
/user:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Create user
|
|
||||||
description: This can only be done by the logged in user.
|
|
||||||
operationId: createUser
|
|
||||||
requestBody:
|
|
||||||
description: Created user object
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/x-www-form-urlencoded:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
/user/createWithList:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Creates list of users with given input array
|
|
||||||
description: Creates list of users with given input array
|
|
||||||
operationId: createUsersWithListInput
|
|
||||||
requestBody:
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
default:
|
|
||||||
description: successful operation
|
|
||||||
/user/login:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Logs user into the system
|
|
||||||
description: ''
|
|
||||||
operationId: loginUser
|
|
||||||
parameters:
|
|
||||||
- name: username
|
|
||||||
in: query
|
|
||||||
description: The user name for login
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
- name: password
|
|
||||||
in: query
|
|
||||||
description: The password for login in clear text
|
|
||||||
required: false
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
headers:
|
|
||||||
X-Rate-Limit:
|
|
||||||
description: calls per hour allowed by the user
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
X-Expires-After:
|
|
||||||
description: date in UTC when token expires
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
content:
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
'400':
|
|
||||||
description: Invalid username/password supplied
|
|
||||||
/user/logout:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Logs out current logged in user session
|
|
||||||
description: ''
|
|
||||||
operationId: logoutUser
|
|
||||||
parameters: []
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: successful operation
|
|
||||||
/user/{username}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Get user by user name
|
|
||||||
description: ''
|
|
||||||
operationId: getUserByName
|
|
||||||
parameters:
|
|
||||||
- name: username
|
|
||||||
in: path
|
|
||||||
description: 'The name that needs to be fetched. Use user1 for testing. '
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
'400':
|
|
||||||
description: Invalid username supplied
|
|
||||||
'404':
|
|
||||||
description: User not found
|
|
||||||
put:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Update user
|
|
||||||
description: This can only be done by the logged in user.
|
|
||||||
operationId: updateUser
|
|
||||||
parameters:
|
|
||||||
- name: username
|
|
||||||
in: path
|
|
||||||
description: name that need to be deleted
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
requestBody:
|
|
||||||
description: Update an existent user in the store
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
application/x-www-form-urlencoded:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
responses:
|
|
||||||
default:
|
|
||||||
description: successful operation
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- user
|
|
||||||
summary: Delete user
|
|
||||||
description: This can only be done by the logged in user.
|
|
||||||
operationId: deleteUser
|
|
||||||
parameters:
|
|
||||||
- name: username
|
|
||||||
in: path
|
|
||||||
description: The name that needs to be deleted
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'400':
|
|
||||||
description: Invalid username supplied
|
|
||||||
'404':
|
|
||||||
description: User not found
|
|
||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
Order:
|
UserSignUpRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
examples: [10]
|
|
||||||
petId:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
examples: [198772]
|
|
||||||
quantity:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
examples: [7]
|
|
||||||
shipDate:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
description: Order Status
|
|
||||||
examples: [approved]
|
|
||||||
enum:
|
|
||||||
- placed
|
|
||||||
- approved
|
|
||||||
- delivered
|
|
||||||
complete:
|
|
||||||
type: boolean
|
|
||||||
xml:
|
|
||||||
name: order
|
|
||||||
Customer:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
examples: [100000]
|
|
||||||
username:
|
|
||||||
type: string
|
|
||||||
examples: [fehguy]
|
|
||||||
address:
|
|
||||||
type: array
|
|
||||||
xml:
|
|
||||||
name: addresses
|
|
||||||
wrapped: true
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Address'
|
|
||||||
xml:
|
|
||||||
name: customer
|
|
||||||
Address:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
street:
|
|
||||||
type: string
|
|
||||||
examples: [437 Lytton]
|
|
||||||
city:
|
|
||||||
type: string
|
|
||||||
examples: [Palo Alto]
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
examples: [CA]
|
|
||||||
zip:
|
|
||||||
type: string
|
|
||||||
examples: ['94301']
|
|
||||||
xml:
|
|
||||||
name: address
|
|
||||||
Category:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
examples: [1]
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
examples: [Dogs]
|
|
||||||
xml:
|
|
||||||
name: category
|
|
||||||
User:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
examples: [10]
|
|
||||||
username:
|
|
||||||
type: string
|
|
||||||
examples: [theUser]
|
|
||||||
firstName:
|
|
||||||
type: string
|
|
||||||
examples: [John]
|
|
||||||
lastName:
|
|
||||||
type: string
|
|
||||||
examples: [James]
|
|
||||||
email:
|
email:
|
||||||
type: string
|
type: string
|
||||||
examples: [john@email.com]
|
example: bruce@wayne.com
|
||||||
|
first_name:
|
||||||
|
type: string
|
||||||
|
example: Bruce
|
||||||
|
last_name:
|
||||||
|
type: string
|
||||||
|
example: Wayne
|
||||||
password:
|
password:
|
||||||
type: string
|
type: string
|
||||||
examples: ['12345']
|
example: verystrongpassword
|
||||||
phone:
|
|
||||||
type: string
|
|
||||||
examples: ['12345']
|
|
||||||
userStatus:
|
|
||||||
type: integer
|
|
||||||
description: User Status
|
|
||||||
format: int32
|
|
||||||
examples: [1]
|
|
||||||
xml:
|
|
||||||
name: user
|
|
||||||
Tag:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
xml:
|
|
||||||
name: tag
|
|
||||||
Pet:
|
|
||||||
required:
|
required:
|
||||||
- name
|
- email
|
||||||
- photoUrls
|
- fist_name
|
||||||
type: object
|
- last_name
|
||||||
properties:
|
- password
|
||||||
id:
|
ErrResponse:
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
examples: [10]
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
examples: [doggie]
|
|
||||||
category:
|
|
||||||
$ref: '#/components/schemas/Category'
|
|
||||||
photoUrls:
|
|
||||||
type: array
|
|
||||||
xml:
|
|
||||||
wrapped: true
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
xml:
|
|
||||||
name: photoUrl
|
|
||||||
tags:
|
|
||||||
type: array
|
|
||||||
xml:
|
|
||||||
wrapped: true
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Tag'
|
|
||||||
status:
|
|
||||||
type: string
|
|
||||||
description: pet status in the store
|
|
||||||
enum:
|
|
||||||
- available
|
|
||||||
- pending
|
|
||||||
- sold
|
|
||||||
xml:
|
|
||||||
name: pet
|
|
||||||
ApiResponse:
|
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
code:
|
code:
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
type:
|
|
||||||
type: string
|
type: string
|
||||||
|
example: FailedOperation.UserAlreadyExists
|
||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
xml:
|
example: "User already exists."
|
||||||
name: '##default'
|
|
||||||
requestBodies:
|
|
||||||
Pet:
|
|
||||||
description: Pet object that needs to be added to the store
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
application/xml:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/Pet'
|
|
||||||
UserArray:
|
|
||||||
description: List of user object
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/User'
|
|
||||||
securitySchemes:
|
|
||||||
petstore_auth:
|
|
||||||
type: oauth2
|
|
||||||
flows:
|
|
||||||
implicit:
|
|
||||||
authorizationUrl: https://petstore3.swagger.io/oauth/authorize
|
|
||||||
scopes:
|
|
||||||
write:pets: modify pets in your account
|
|
||||||
read:pets: read your pets
|
|
||||||
api_key:
|
|
||||||
type: apiKey
|
|
||||||
name: api_key
|
|
||||||
in: header
|
|
||||||
|
@ -1,24 +1,18 @@
|
|||||||
dev-mode: true
|
dev-mode: true
|
||||||
|
|
||||||
web:
|
web:
|
||||||
addr: :8080
|
addr: :8000
|
||||||
shutdown-timeout: 10
|
shutdown-timeout: 10
|
||||||
|
|
||||||
db:
|
db:
|
||||||
# DB host
|
# DB host
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
# DB username
|
# DB username
|
||||||
username: howmuch
|
username: postgres
|
||||||
# DB password
|
# DB password
|
||||||
password: howmuch
|
password: example
|
||||||
# DB name
|
# DB name
|
||||||
database: howmuch
|
database: howmuch
|
||||||
# max idle connections
|
|
||||||
max-idle-connections: 100
|
|
||||||
# max open connections
|
|
||||||
max-open-connections: 100
|
|
||||||
# max connection life time
|
|
||||||
max-connection-life-time: 10s
|
|
||||||
|
|
||||||
log:
|
log:
|
||||||
level: debug
|
level: debug
|
||||||
|
12
go.mod
12
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gosuri/uitable v0.0.4
|
github.com/gosuri/uitable v0.0.4
|
||||||
|
github.com/jackc/pgx/v5 v5.7.1
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.19.0
|
github.com/spf13/viper v1.19.0
|
||||||
@ -29,8 +30,12 @@ require (
|
|||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
@ -54,10 +59,11 @@ require (
|
|||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/arch v0.8.0 // indirect
|
golang.org/x/arch v0.8.0 // indirect
|
||||||
golang.org/x/crypto v0.23.0 // indirect
|
golang.org/x/crypto v0.27.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||||
golang.org/x/sys v0.20.0 // indirect
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/text v0.15.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
|
golang.org/x/text v0.18.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.1 // indirect
|
google.golang.org/protobuf v1.34.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
26
go.sum
26
go.sum
@ -35,8 +35,8 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx
|
|||||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@ -46,6 +46,14 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
|||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||||
|
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
@ -127,19 +135,21 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
|||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
52
internal/howmuch/adapter/controller/admin.go
Normal file
52
internal/howmuch/adapter/controller/admin.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Admin interface {
|
||||||
|
CreateUser(core.Context)
|
||||||
|
GetUserById(core.Context)
|
||||||
|
UpdateUser(core.Context)
|
||||||
|
DeleteUser(core.Context)
|
||||||
|
ListUsers(core.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdminController struct{}
|
||||||
|
|
||||||
|
func (ac *AdminController) CreateUser(core.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AdminController) GetUserById(core.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AdminController) UpdateUser(core.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AdminController) DeleteUser(core.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AdminController) ListUsers(core.Context) {
|
||||||
|
}
|
31
internal/howmuch/adapter/controller/app.go
Normal file
31
internal/howmuch/adapter/controller/app.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package controller
|
||||||
|
|
||||||
|
// AppController is the controller structure that holds service controllers.
|
||||||
|
type AppController struct {
|
||||||
|
// User must implement User interface
|
||||||
|
User interface{ User }
|
||||||
|
|
||||||
|
Admin interface{ Admin }
|
||||||
|
}
|
57
internal/howmuch/adapter/controller/user.go
Normal file
57
internal/howmuch/adapter/controller/user.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// User is the user controller interface, it describes all the handlers
|
||||||
|
// that need to be implemented for the /user endpoint
|
||||||
|
type User interface {
|
||||||
|
Signup(core.Context)
|
||||||
|
UpdateInfo(core.Context)
|
||||||
|
Login(core.Context)
|
||||||
|
Logout(core.Context)
|
||||||
|
ChangePassword(core.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserController struct{}
|
||||||
|
|
||||||
|
func (uc *UserController) Signup(ctx core.Context) {
|
||||||
|
ctx.JSON(http.StatusOK, "hello")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uc *UserController) UpdateInfo(ctx core.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uc *UserController) Login(ctx core.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uc *UserController) Logout(ctx core.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (uc *UserController) ChangePassword(ctx core.Context) {
|
||||||
|
}
|
27
internal/howmuch/adapter/repo/sqlc/user.sql
Normal file
27
internal/howmuch/adapter/repo/sqlc/user.sql
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
-- MIT License
|
||||||
|
--
|
||||||
|
-- Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
--
|
||||||
|
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
-- of this software and associated documentation files (the "Software"), to deal
|
||||||
|
-- in the Software without restriction, including without limitation the rights
|
||||||
|
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
-- copies of the Software, and to permit persons to whom the Software is
|
||||||
|
-- furnished to do so, subject to the following conditions:
|
||||||
|
--
|
||||||
|
-- The above copyright notice and this permission notice shall be included in all
|
||||||
|
-- copies or substantial portions of the Software.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
-- SOFTWARE.
|
||||||
|
|
||||||
|
-- name: InsertUser :one
|
||||||
|
INSERT INTO "user" (
|
||||||
|
email, first_name, last_name, password, created_at, updated_at
|
||||||
|
) VALUES ( $1, $2, $3, $4, $5, $6 )
|
||||||
|
RETURNING *;
|
@ -40,8 +40,25 @@ const (
|
|||||||
configType = "yaml"
|
configType = "yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func defaultConfig() {
|
||||||
|
viper.SetDefault("dev-mode", true)
|
||||||
|
|
||||||
|
// web
|
||||||
|
viper.SetDefault("web.addr", ":8000")
|
||||||
|
viper.SetDefault("web.shutdown-timeout", "10")
|
||||||
|
|
||||||
|
// db
|
||||||
|
viper.SetDefault("db.host", "localhost")
|
||||||
|
viper.SetDefault("db.port", 5432)
|
||||||
|
viper.SetDefault("db.username", "postgres")
|
||||||
|
viper.SetDefault("db.password", "example")
|
||||||
|
viper.SetDefault("db.database", "howmuch")
|
||||||
|
viper.SetDefault("db.sslmode", "disable")
|
||||||
|
}
|
||||||
|
|
||||||
// initConfig reads in config file and ENV variables if set.
|
// initConfig reads in config file and ENV variables if set.
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
|
defaultConfig()
|
||||||
if cfgFile != "" {
|
if cfgFile != "" {
|
||||||
// Use config file from the flag.
|
// Use config file from the flag.
|
||||||
viper.SetConfigFile(cfgFile)
|
viper.SetConfigFile(cfgFile)
|
||||||
@ -65,7 +82,7 @@ func initConfig() {
|
|||||||
viper.SetEnvKeyReplacer(replacer)
|
viper.SetEnvKeyReplacer(replacer)
|
||||||
|
|
||||||
if err := viper.ReadInConfig(); err != nil {
|
if err := viper.ReadInConfig(); err != nil {
|
||||||
log.ErrorLog("Failed to read viper configuration file", "err", err)
|
log.ErrorLog("Failed to read viper configuration file, use default config", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
32
internal/howmuch/controller/repo/sqlc/db.go
Normal file
32
internal/howmuch/controller/repo/sqlc/db.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DBTX interface {
|
||||||
|
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||||
|
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||||
|
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db DBTX) *Queries {
|
||||||
|
return &Queries{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Queries struct {
|
||||||
|
db DBTX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||||
|
return &Queries{
|
||||||
|
db: tx,
|
||||||
|
}
|
||||||
|
}
|
26
internal/howmuch/controller/repo/sqlc/models.go
Normal file
26
internal/howmuch/controller/repo/sqlc/models.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Admin struct {
|
||||||
|
ID int32
|
||||||
|
Email string
|
||||||
|
Password string
|
||||||
|
AccessLevel int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID int32
|
||||||
|
Email string
|
||||||
|
FirstName string
|
||||||
|
LastName string
|
||||||
|
Password string
|
||||||
|
CreatedAt pgtype.Timestamp
|
||||||
|
UpdatedAt pgtype.Timestamp
|
||||||
|
}
|
72
internal/howmuch/controller/repo/sqlc/user.sql.go
Normal file
72
internal/howmuch/controller/repo/sqlc/user.sql.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.27.0
|
||||||
|
// source: user.sql
|
||||||
|
|
||||||
|
package sqlc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
)
|
||||||
|
|
||||||
|
const insertUser = `-- name: InsertUser :one
|
||||||
|
|
||||||
|
INSERT INTO "user" (
|
||||||
|
email, first_name, last_name, password, created_at, updated_at
|
||||||
|
) VALUES ( $1, $2, $3, $4, $5, $6 )
|
||||||
|
RETURNING id, email, first_name, last_name, password, created_at, updated_at
|
||||||
|
`
|
||||||
|
|
||||||
|
type InsertUserParams struct {
|
||||||
|
Email string
|
||||||
|
FirstName string
|
||||||
|
LastName string
|
||||||
|
Password string
|
||||||
|
CreatedAt pgtype.Timestamp
|
||||||
|
UpdatedAt pgtype.Timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
func (q *Queries) InsertUser(ctx context.Context, arg InsertUserParams) (User, error) {
|
||||||
|
row := q.db.QueryRow(ctx, insertUser,
|
||||||
|
arg.Email,
|
||||||
|
arg.FirstName,
|
||||||
|
arg.LastName,
|
||||||
|
arg.Password,
|
||||||
|
arg.CreatedAt,
|
||||||
|
arg.UpdatedAt,
|
||||||
|
)
|
||||||
|
var i User
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.Email,
|
||||||
|
&i.FirstName,
|
||||||
|
&i.LastName,
|
||||||
|
&i.Password,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
@ -31,12 +31,11 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/core"
|
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/infra/datastore"
|
||||||
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno"
|
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/infra/router"
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/registry"
|
||||||
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/log"
|
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/log"
|
||||||
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/middleware"
|
|
||||||
"git.vinchent.xyz/vinchent/howmuch/pkg/version/verflag"
|
"git.vinchent.xyz/vinchent/howmuch/pkg/version/verflag"
|
||||||
"github.com/gin-contrib/cors"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@ -97,6 +96,7 @@ to share their expense of an event or a trip`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
func run() error {
|
||||||
|
// Set Gin running mode
|
||||||
isDev := viper.GetBool("dev-mode")
|
isDev := viper.GetBool("dev-mode")
|
||||||
if isDev {
|
if isDev {
|
||||||
gin.SetMode(gin.DebugMode)
|
gin.SetMode(gin.DebugMode)
|
||||||
@ -104,32 +104,37 @@ func run() error {
|
|||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
r := gin.Default()
|
// Init DB
|
||||||
|
dbPool, err := datastore.NewDB(
|
||||||
|
fmt.Sprintf(
|
||||||
|
"host=%s port=%d dbname=%s user=%s password=%s sslmode=%s",
|
||||||
|
viper.GetString("db.host"),
|
||||||
|
viper.GetInt("db.port"),
|
||||||
|
viper.GetString("db.database"),
|
||||||
|
viper.GetString("db.username"),
|
||||||
|
viper.GetString("db.password"),
|
||||||
|
viper.GetString("db.sslmode"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.FatalLog("DB connection failure", "err", err)
|
||||||
|
}
|
||||||
|
defer dbPool.Close()
|
||||||
|
|
||||||
// Middlewares
|
// Register the core service
|
||||||
corsCfg := cors.DefaultConfig()
|
r := registry.NewRegistry(dbPool)
|
||||||
corsCfg.AllowAllOrigins = true
|
|
||||||
corsCfg.AllowHeaders = append(corsCfg.AllowHeaders, "Authorization", "Accept", "X-CSRF-Token")
|
|
||||||
r.Use(cors.New(corsCfg))
|
|
||||||
|
|
||||||
r.Use(middleware.RequestID())
|
engine := gin.Default()
|
||||||
|
|
||||||
r.NoRoute(func(ctx *gin.Context) {
|
engine = router.Routes(engine, r.NewAppController())
|
||||||
core.WriteResponse(ctx, errno.PageNotFoundErr, nil)
|
|
||||||
})
|
|
||||||
|
|
||||||
r.GET("/", func(ctx *gin.Context) {
|
|
||||||
// time.Sleep(10 * time.Second) // Test shutdown
|
|
||||||
core.WriteResponse(ctx, nil, gin.H{
|
|
||||||
"message": "how much?",
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
server := http.Server{
|
server := http.Server{
|
||||||
Addr: viper.GetString("web.addr"),
|
Addr: viper.GetString("web.addr"),
|
||||||
Handler: r,
|
Handler: engine,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.InfoLog("Server running", "port", viper.GetString("web.addr"))
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
||||||
log.FatalLog(err.Error())
|
log.FatalLog(err.Error())
|
||||||
|
44
internal/howmuch/infra/datastore/db.go
Normal file
44
internal/howmuch/infra/datastore/db.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package datastore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewDB creates a new database for the application
|
||||||
|
func NewDB(dsn string) (*pgxpool.Pool, error) {
|
||||||
|
conn, err := pgxpool.New(context.Background(), dsn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ping test the conn
|
||||||
|
if err = conn.Ping(context.Background()); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn, err
|
||||||
|
}
|
54
internal/howmuch/infra/router/router.go
Normal file
54
internal/howmuch/infra/router/router.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/controller"
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/core"
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno"
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/middleware"
|
||||||
|
"github.com/gin-contrib/cors"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Routes(engine *gin.Engine, c controller.AppController) *gin.Engine {
|
||||||
|
// Middlewares
|
||||||
|
// Cors
|
||||||
|
corsCfg := cors.DefaultConfig()
|
||||||
|
corsCfg.AllowAllOrigins = true
|
||||||
|
corsCfg.AllowHeaders = append(corsCfg.AllowHeaders, "Authorization", "Accept", "X-CSRF-Token")
|
||||||
|
engine.Use(cors.New(corsCfg))
|
||||||
|
|
||||||
|
// Use my request id middleware
|
||||||
|
// TODO: I might use the community version later
|
||||||
|
engine.Use(middleware.RequestID())
|
||||||
|
|
||||||
|
// Route for the 404 error
|
||||||
|
engine.NoRoute(func(ctx *gin.Context) {
|
||||||
|
core.WriteResponse(ctx, errno.PageNotFoundErr, nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
engine.POST("/signup", func(ctx *gin.Context) { c.User.Signup(ctx) })
|
||||||
|
|
||||||
|
return engine
|
||||||
|
}
|
30
internal/howmuch/registry/admin.go
Normal file
30
internal/howmuch/registry/admin.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/controller"
|
||||||
|
|
||||||
|
// NewUserController returns an admin controller's implementation
|
||||||
|
func (r *registry) NewAdminController() controller.Admin {
|
||||||
|
return &controller.AdminController{}
|
||||||
|
}
|
57
internal/howmuch/registry/registry.go
Normal file
57
internal/howmuch/registry/registry.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/controller"
|
||||||
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
)
|
||||||
|
|
||||||
|
// registry is an implementation of Registry interface.
|
||||||
|
// It needs a db connection to provide the necessary support.
|
||||||
|
// It might holds other drivers when the projects grows. For example
|
||||||
|
// the object needed to connect to Redis or Kafka.
|
||||||
|
type registry struct {
|
||||||
|
db *pgxpool.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registry returns a new app controller that will be used by main()/run()
|
||||||
|
// AppController is essentially the struct that holds all the controllers,
|
||||||
|
// classed by their domains.
|
||||||
|
type Registry interface {
|
||||||
|
NewAppController() controller.AppController
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRegistry returns a new Registry's implementation.
|
||||||
|
func NewRegistry(db *pgxpool.Pool) Registry {
|
||||||
|
return ®istry{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAppController creates a new AppController with controller struct for
|
||||||
|
// each domain.
|
||||||
|
func (r *registry) NewAppController() controller.AppController {
|
||||||
|
return controller.AppController{
|
||||||
|
User: r.NewUserController(),
|
||||||
|
Admin: r.NewAdminController(),
|
||||||
|
}
|
||||||
|
}
|
30
internal/howmuch/registry/user.go
Normal file
30
internal/howmuch/registry/user.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/adapter/controller"
|
||||||
|
|
||||||
|
// NewUserController returns a user controller's implementation
|
||||||
|
func (r *registry) NewUserController() controller.User {
|
||||||
|
return &controller.UserController{}
|
||||||
|
}
|
@ -1,3 +1,25 @@
|
|||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
type Context interface {
|
type Context interface {
|
||||||
|
31
sqlc.yml
Normal file
31
sqlc.yml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# MIT License
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 vinchent <vinchent@vinchent.xyz>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
|
||||||
|
version: "2"
|
||||||
|
sql:
|
||||||
|
- engine: "postgresql"
|
||||||
|
queries: "internal/app/adapter/repo/sqlc"
|
||||||
|
schema: "migrations"
|
||||||
|
gen:
|
||||||
|
go:
|
||||||
|
out: "internal/app/controller/repo/sqlc"
|
||||||
|
sql_package: "pgx/v5"
|
Loading…
x
Reference in New Issue
Block a user