Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add API docs using swagger(#68) #69

Merged
merged 1 commit into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 69 additions & 2 deletions api/employer.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,19 @@ func newEmployerResponse(employer db.Employer, company db.Company) employerRespo
}
}

// createEmployer handles creation of an employer
// @Schemes
// @Summary Create employer
// @Description Create a new employer
// @Tags employers
// @Accept json
// @Produce json
// @param CreateEmployerRequest body createEmployerRequest true "Employer and company details"
// @Success 201 {object} employerResponse
// @Failure 400 {object} ErrorResponse "Invalid request body"
// @Failure 403 {object} ErrorResponse "Company with given name or employer with given email already exists"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /employers [post]
// createEmployer handles creating a new employer
func (server *Server) createEmployer(ctx *gin.Context) {
var request createEmployerRequest
if err := ctx.ShouldBindJSON(&request); err != nil {
Expand Down Expand Up @@ -119,6 +131,19 @@ type loginEmployerResponse struct {
Employer employerResponse `json:"employer"`
}

// @Schemes
// @Summary Login employer
// @Description Login an employer
// @Tags employers
// @Accept json
// @Produce json
// @param LoginEmployerRequest body loginEmployerRequest true "Employer credentials"
// @Success 200 {object} loginEmployerResponse
// @Failure 400 {object} ErrorResponse "Invalid request body"
// @Failure 404 {object} ErrorResponse "Employer with given email or company with given id does not exist"
// @Failure 401 {object} ErrorResponse "Incorrect password"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /employers/login [post]
// loginEmployer handles login of an employer
func (server *Server) loginEmployer(ctx *gin.Context) {
var request loginEmployerRequest
Expand Down Expand Up @@ -175,6 +200,14 @@ func (server *Server) loginEmployer(ctx *gin.Context) {
ctx.JSON(http.StatusOK, res)
}

// @Schemes
// @Summary Get employer
// @Description Get the details of the authenticated employer
// @Tags employers
// @Produce json
// @Success 200 {object} employerResponse
// @Failure 500 {object} ErrorResponse "Internal error"
// @Router /employers [get]
// getEmployer get details of the authenticated employer
func (server *Server) getEmployer(ctx *gin.Context) {
authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload)
Expand All @@ -201,6 +234,17 @@ type updateEmployerRequest struct {
CompanyLocation string `json:"company_location"`
}

// @Schemes
// @Summary Update employer
// @Description Update the details of the authenticated employer
// @Tags employers
// @Accept json
// @Produce json
// @param UpdateEmployerRequest body updateEmployerRequest true "Employer details to update"
// @Success 200 {object} employerResponse
// @Failure 400 {object} ErrorResponse "Invalid request body"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /employers [patch]
// updateEmployer handles update of an employer details
func (server *Server) updateEmployer(ctx *gin.Context) {
var request updateEmployerRequest
Expand Down Expand Up @@ -295,6 +339,22 @@ type updateEmployerPasswordRequest struct {
NewPassword string `json:"new_password" binding:"required,min=6"`
}

type updateEmployerPasswordResponse struct {
Message string `json:"message"`
}

// @Schemes
// @Summary Update employer password
// @Description Update/change logged-in employer password
// @Tags employers
// @Accept json
// @Produce json
// @param UpdateEmployerPasswordRequest body updateEmployerPasswordRequest true "Employer old and new password"
// @Success 200 {object} updateEmployerPasswordResponse
// @Failure 400 {object} ErrorResponse "Invalid request body"
// @Failure 401 {object} ErrorResponse "Incorrect password"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /employers/password [patch]
// updateEmployerPassword handles user password update
func (server *Server) updateEmployerPassword(ctx *gin.Context) {
var request updateEmployerPasswordRequest
Expand Down Expand Up @@ -334,9 +394,16 @@ func (server *Server) updateEmployerPassword(ctx *gin.Context) {
return
}

ctx.JSON(http.StatusOK, gin.H{"message": "password updated successfully"})
ctx.JSON(http.StatusOK, updateEmployerPasswordResponse{"password updated successfully"})
}

// @Schemes
// @Summary Delete employer
// @Description Delete the logged-in employer
// @Tags employers
// @Success 204 {null} null
// @Failure 500 {object} ErrorResponse "Any error"
// @Router /employers [delete]
// deleteEmployer handles deleting employer
func (server *Server) deleteEmployer(ctx *gin.Context) {
authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload)
Expand Down
12 changes: 6 additions & 6 deletions api/employer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func TestCreateEmployerAPI(t *testing.T) {
data, err := json.Marshal(tc.body)
require.NoError(t, err)

url := "/employers"
url := "/api/v1/employers"
req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data))
require.NoError(t, err)

Expand Down Expand Up @@ -405,7 +405,7 @@ func TestLoginEmployerAPI(t *testing.T) {
data, err := json.Marshal(tc.body)
require.NoError(t, err)

url := "/employers/login"
url := "/api/v1/employers/login"
req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data))
require.NoError(t, err)

Expand Down Expand Up @@ -496,7 +496,7 @@ func TestGetEmployerAPI(t *testing.T) {
server := newTestServer(t, store)
recorder := httptest.NewRecorder()

url := "/employers"
url := "/api/v1/employers"
req, err := http.NewRequest(http.MethodGet, url, nil)
require.NoError(t, err)

Expand Down Expand Up @@ -755,7 +755,7 @@ func TestUpdateEmployerAPI(t *testing.T) {
data, err := json.Marshal(tc.body)
require.NoError(t, err)

url := "/employers"
url := "/api/v1/employers"
req, err := http.NewRequest(http.MethodPatch, url, bytes.NewReader(data))
require.NoError(t, err)

Expand Down Expand Up @@ -928,7 +928,7 @@ func TestUpdateEmployerPasswordAPI(t *testing.T) {
data, err := json.Marshal(tc.body)
require.NoError(t, err)

url := "/employers/password"
url := "/api/v1/employers/password"
req, err := http.NewRequest(http.MethodPatch, url, bytes.NewReader(data))
require.NoError(t, err)

Expand Down Expand Up @@ -1053,7 +1053,7 @@ func TestDeleteEmployerAPI(t *testing.T) {
server := newTestServer(t, store)
recorder := httptest.NewRecorder()

url := "/employers"
url := "/api/v1/employers"
req, err := http.NewRequest(http.MethodDelete, url, nil)
require.NoError(t, err)

Expand Down
87 changes: 87 additions & 0 deletions api/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ type createJobRequest struct {
RequiredSkills []string `json:"required_skills" binding:"required"`
}

// @Schemes
// @Summary Create job
// @Description Create a new job
// @Tags jobs
// @Accept json
// @Produce json
// @param CreateJobRequest body createJobRequest true "Job details"
// @Success 201 {object} jobResponse
// @Failure 400 {object} ErrorResponse "Invalid request body"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /jobs [post]
// createJob handles creating a job posting - job with job skills
func (server *Server) createJob(ctx *gin.Context) {
var request createJobRequest
Expand Down Expand Up @@ -118,6 +129,14 @@ type deleteJobRequest struct {
ID int32 `uri:"id" binding:"required,min=1"`
}

// @Schemes
// @Summary Delete job
// @Description Delete the job with the given id
// @Tags jobs
// @param id path integer true "Job ID"
// @Success 204 {null} null
// @Failure 500 {object} ErrorResponse "Any error"
// @Router /jobs/{id} [delete]
// deleteJob handles deleting a job posting
func (server *Server) deleteJob(ctx *gin.Context) {
var request deleteJobRequest
Expand Down Expand Up @@ -172,6 +191,20 @@ type updateJobRequest struct {
RequiredSkillIDsToRemove []int32 `json:"required_skill_ids_to_remove"`
}

// @Schemes
// @Summary Update job
// @Description update the job with the given id
// @Tags jobs
// @Param id path integer true "Job ID"
// @Param UpdateJobRequest body updateJobRequest true "Job details to update"
// @Accept json
// @Produce json
// @Success 200 {object} jobResponse
// @Failure 400 {object} ErrorResponse "Invalid request query or body"
// @Failure 401 {object} ErrorResponse "User making the request not an employer or employer not the owner of the job"
// @Failure 404 {object} ErrorResponse "Job not found"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /jobs/{id} [patch]
// updateJob handles updating a job posting - job and job skills
func (server *Server) updateJob(ctx *gin.Context) {
// job ID
Expand Down Expand Up @@ -305,6 +338,17 @@ type getJobRequest struct {
ID int32 `uri:"id" binding:"required,min=1"`
}

// @Schemes
// @Summary Get job
// @Description Get details of the job with the given id
// @Tags jobs
// @Param id path integer true "Job ID"
// @Produce json
// @Success 200 {object} jobResponse
// @Failure 400 {object} ErrorResponse "Invalid request query"
// @Failure 404 {object} ErrorResponse "Job not found"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /jobs/{id} [get]
// getJob handles getting a job posting with all details
// without job skills - these are fetched separately
// to allow for the client to get paginated job skills.
Expand Down Expand Up @@ -338,6 +382,23 @@ type filterAndListJobs struct {
PageSize int32 `form:"page_size" binding:"required,min=5,max=15"`
}

// @Schemes
// @Summary Filter and list jobs
// @Description Filter and list jobs
// @Tags jobs
// @Param page query integer true "Page number"
// @Param page_size query integer true "Page size"
// @Param title query string false "Job title - matches partially (ILIKE)"
// @Param industry query string false "Job industry - exact name"
// @Param job_location query string false "Job location - exact name"
// @Param salary_min query integer false "Salary min - must be smaller or equal salary_max"
// @Param salary_max query integer false "Salary max - must be greater or equal salary_min"
// @Produce json
// @Success 200 {array} []db.ListJobsByFiltersRow
// @Failure 400 {object} ErrorResponse "Invalid query"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /jobs [get]
// filterAndListJobs handles filtering and listing jobs
func (server *Server) filterAndListJobs(ctx *gin.Context) {
var request filterAndListJobs
if err := ctx.ShouldBindQuery(&request); err != nil {
Expand Down Expand Up @@ -384,6 +445,18 @@ type listJobsByMatchingSkillsRequest struct {
PageSize int32 `form:"page_size" binding:"required,min=5,max=15"`
}

// @Schemes
// @Summary List jobs by matching skills
// @Description List jobs that match the authenticated users skills
// @Tags jobs
// @Param page query integer true "Page number"
// @Param page_size query integer true "Page size"
// @Produce json
// @Success 200 {array} []db.ListJobsMatchingUserSkillsRow
// @Failure 400 {object} ErrorResponse "Invalid query"
// @Failure 401 {object} ErrorResponse "Employer making the request - only users can access"
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /jobs/match-skills [get]
// listJobsByMatchingSkills handles listing all jobs
// that skills match the users skills.
func (server *Server) listJobsByMatchingSkills(ctx *gin.Context) {
Expand Down Expand Up @@ -429,6 +502,20 @@ type listJobsByCompanyRequest struct {
PageSize int32 `form:"page_size" binding:"required,min=5,max=15"`
}

// @Schemes
// @Summary List jobs by company
// @Description List jobs by company name, id or part of the name.
// @Tags jobs
// @Param page query integer true "Page number"
// @Param page_size query integer true "Page size"
// @Param id query integer false "Company ID"
// @Param name query string false "Company name"
// @Param name_contains query string false "Part of the company name"
// @Produce json
// @Success 200 {array} []db.ListJobsByCompanyNameRow
// @Failure 400 {object} ErrorResponse "Invalid query. Only one of the three parameters is allowed."
// @Failure 500 {object} ErrorResponse "Any other error"
// @Router /jobs/company [get]
// listJobsByCompany handles listing jobs by company.
// Required parameters:
// - page (page number)
Expand Down
14 changes: 7 additions & 7 deletions api/job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ func TestCreateJobAPI(t *testing.T) {
data, err := json.Marshal(tc.body)
require.NoError(t, err)

url := "/jobs"
url := "/api/v1/jobs"
req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(data))
require.NoError(t, err)

Expand Down Expand Up @@ -482,7 +482,7 @@ func TestDeleteJobAPI(t *testing.T) {
server := newTestServer(t, store)
recorder := httptest.NewRecorder()

url := fmt.Sprintf("/jobs/%d", tc.jobID)
url := fmt.Sprintf("/api/v1/jobs/%d", tc.jobID)
req, err := http.NewRequest(http.MethodDelete, url, nil)
require.NoError(t, err)

Expand Down Expand Up @@ -594,7 +594,7 @@ func TestGetJobAPI(t *testing.T) {
server := newTestServer(t, store)
recorder := httptest.NewRecorder()

url := fmt.Sprintf("/jobs/%d", tc.jobID)
url := fmt.Sprintf("/api/v1/jobs/%d", tc.jobID)
req, err := http.NewRequest(http.MethodGet, url, nil)
require.NoError(t, err)

Expand Down Expand Up @@ -811,7 +811,7 @@ func TestFilterAndListJobsAPI(t *testing.T) {
server := newTestServer(t, store)
recorder := httptest.NewRecorder()

url := "/jobs"
url := "/api/v1/jobs"
req, err := http.NewRequest(http.MethodGet, url, nil)
require.NoError(t, err)

Expand Down Expand Up @@ -1074,7 +1074,7 @@ func TestListJobsByMatchingSkillsAPI(t *testing.T) {
server := newTestServer(t, store)
recorder := httptest.NewRecorder()

url := "/jobs/match-skills"
url := "/api/v1/jobs/match-skills"
req, err := http.NewRequest(http.MethodGet, url, nil)
require.NoError(t, err)

Expand Down Expand Up @@ -1603,7 +1603,7 @@ func TestUpdateJobAPI(t *testing.T) {
data, err := json.Marshal(tc.body)
require.NoError(t, err)

url := fmt.Sprintf("/jobs/%d", tc.jobID)
url := fmt.Sprintf("/api/v1/jobs/%d", tc.jobID)
req, err := http.NewRequest(http.MethodPatch, url, bytes.NewReader(data))
require.NoError(t, err)

Expand Down Expand Up @@ -1954,7 +1954,7 @@ func TestListJobsByCompanyAPI(t *testing.T) {
server := newTestServer(t, store)
recorder := httptest.NewRecorder()

url := "/jobs/company"
url := "/api/v1/jobs/company"
req, err := http.NewRequest(http.MethodGet, url, nil)
require.NoError(t, err)

Expand Down
Loading