Categorygithub.com/bryanmorgan/time-tracking-api
modulepackage
0.0.0-20240102175237-66b7006646bb
Repository: https://github.com/bryanmorgan/time-tracking-api.git
Documentation: pkg.go.dev

# README

Time Tracking API

build Go Report Card

Go API for tracking time.

Manage time entries for tasks that are associated with projects. Built with Golang and PostgreSQL.

See the React Time Tracking App for a reference UI.

Setup

You can use Docker to get started quickly or run the Go server locally using a PostgreSQL instance.

Option #1: Docker

To run the Go server and PostgreSQL database in a container you can start both using Docker Compose:

docker-compose up

The API will be available at http://localhost:8000 and the PostgreSQL instance will be exposed on port 5432.

Option #2: Local

Database

Ensure you have PostgreSQL 12 or higher installed and running.

Create a timetracker database and role using the bootstrap SQL in:

./database/bootstrap.sql

Then create the schema in the timetracker database using:

./database/schema-1.sql

Run Server

To run the Go API server use the run Makefile target:

make run

which will start the server on the port configured in config/dev.yml. By default the API will be available at http://localhost:8000

Testing

Unit Tests

Unit tests can be run using:

make unit_test

Integration Tests

Integration tests are managed under the integration_test root folder and can be run using:

make int_test

Postman Tests

Additional functional tests are available using the Postman tool. These tests require the newman Postman command-line runner. Install using:

npm install -g newman

The test rely on the database/bootstrap.sql data to be present. To run the Postman tests locally, first start the web server:

make run

then run the Postman tests:

make postman

API

Authentication Token

Most of the REST endpoints require an authentication token which can be supplied as a custom header:

Authorization: Bearer {token}

Endpoints that do not require a token are noted below.

To validate the local or Docker instance is working you can hit the /_ping endpoint and you should get back an OK response:

curl http://localhost:8000/_ping

Authentication

MethodPathRequestResponseNotes
POST/api/auth/loginLoginRequestAuthResponseDoes not require an authentication token
POST/api/auth/tokenAuthResponse
POST/api/auth/logout{}
POST/api/auth/forgotEmailRequest{}Does not require an authentication token. Sends a forgot password validation email.

Profile

MethodPathRequestResponseNotes
GET/api/profile/ProfileResponse
PUT/api/profile/ProfileRequestProfileResponse
PUT/api/profile/passwordPasswordChangeRequest{}

Account

MethodPathRequestResponseNotes
POST/api/accountAccountRequestProfileResponseDoes not require an authentication token
PUT/api/accountAccountUpdateRequestProfileResponse
GET/api/accountAccountResponse
GET/api/account/users[]ProfileResponse
POST/api/account/userAddUserRequestProfileResponse

Client

MethodPathRequestResponseNotes
GET/api/client/{client_id}stringClientResponse
GET/api/client/all[]ClientResponse
GET/api/client/archived[]ClientResponse
POST/api/client/ClientRequestClientResponse
PUT/api/client/ClientRequest{}
DELETE/api/client/ClientRequest{}
PUT/api/client/archiveClientRequest{}
PUT/api/client/restoreClientRequest{}

Project

MethodPathRequestResponseNotes
GET/api/project/{project_id}stringProjectResponse
GET/api/project/all[]ProjectResponse
GET/api/project/archived[]ProjectResponse
POST/api/project/ProjectContainerRequestProjectResponse
PUT/api/project/ProjectContainerRequest{}
DELETE/api/project/ProjectIdRequest{}
PUT/api/project/archiveProjectIdRequest{}
PUT/api/project/restoreProjectIdRequest{}
POST/api/project/copy/last/weekStartAndEndDateRequest{} or TimeRangeResponseEmpty if no records the prior week

Time

MethodPathRequestResponseNotes
GET/api/time/weekTimeRangeResponse
GET/api/time/week/{startDate}stringTimeRangeResponseDate must be in the ISOShortDateFormat (e.g. "2006-01-02")
PUT/api/time/TimeEntryRangeRequest{}
POST/api/time/project/weekProjectWeekRequest{}
DELETE/api/time/project/weekProjectDeleteRequest{}

Task

MethodPathRequestResponseNotes
GET/api/task/{taskId}stringTaskResponse
GET/api/task/all[]TaskResponse
GET/api/task/archived[]TaskResponse
POST/api/task/TaskRequestTaskResponse
PUT/api/task/TaskRequest{}
PUT/api/task/archiveTaskRequest{}
PUT/api/task/restoreTaskRequest{}
DELETE/api/task/TaskRequest{}

Report

MethodPathRequestResponseNotes
GET/api/report/time/clientquery parameters: from, to, page[]ClientReportResponsefrom and to are date strings in the ISOShortDateFormat format
GET/api/report/time/projectquery parameters: from, to, page[]ProjectReportResponsefrom and to are date strings in the ISOShortDateFormat format
GET/api/report/time/taskquery parameters: from, to, page[]TaskReportResponsefrom and to are date strings in the ISOShortDateFormat format
GET/api/report/time/personquery parameters: from, to, page[]PersonReportResponsefrom and to are date strings in the ISOShortDateFormat format
GET/api/report/time/export/clientquery parameters: from, toCSV file with content type text/csvfrom and to are date strings in the ISOShortDateFormat format
GET/api/report/time/export/projectquery parameters: from, toCSV file with content type text/csvfrom and to are date strings in the ISOShortDateFormat format
GET/api/report/time/export/taskquery parameters: from, toCSV file with content type text/csvfrom and to are date strings in the ISOShortDateFormat format
GET/api/report/time/export/personquery parameters: from, toCSV file with content type text/csvfrom and to are date strings in the ISOShortDateFormat format

Ping

MethodPathRequestResponseNotes
GET/_pingText ok with content type text/plain

Errors

If an API fails, the HTTP status code will reflect the type of error response. Common error status codes are:

Status CodeError
400http.StatusBadRequest
401http.StatusUnauthorized
404http.StatusNotFound
405http.StatusMethodNotAllowed
500http.StatusInternalServerError

Errors will produce a JSON response that contains a status field set to error. Error details will be included as part of the serialized Error struct.

For example the error response below shows the JSON response for a 400 error when an email value is invalid:

{
  "status": "error",
  "error": "invalid input",
  "message": "Invalid email",
  "code": "InvalidEmail",
  "detail": {"field": "email" }
}

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author