Skip to content

BryanMorgan/time-tracking-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

Method Path Request Response Notes
POST /api/auth/login LoginRequest AuthResponse Does not require an authentication token
POST /api/auth/token AuthResponse
POST /api/auth/logout {}
POST /api/auth/forgot EmailRequest {} Does not require an authentication token. Sends a forgot password validation email.

Profile

Method Path Request Response Notes
GET /api/profile/ ProfileResponse
PUT /api/profile/ ProfileRequest ProfileResponse
PUT /api/profile/password PasswordChangeRequest {}

Account

Method Path Request Response Notes
POST /api/account AccountRequest ProfileResponse Does not require an authentication token
PUT /api/account AccountUpdateRequest ProfileResponse
GET /api/account AccountResponse
GET /api/account/users []ProfileResponse
POST /api/account/user AddUserRequest ProfileResponse

Client

Method Path Request Response Notes
GET /api/client/{client_id} string ClientResponse
GET /api/client/all []ClientResponse
GET /api/client/archived []ClientResponse
POST /api/client/ ClientRequest ClientResponse
PUT /api/client/ ClientRequest {}
DELETE /api/client/ ClientRequest {}
PUT /api/client/archive ClientRequest {}
PUT /api/client/restore ClientRequest {}

Project

Method Path Request Response Notes
GET /api/project/{project_id} string ProjectResponse
GET /api/project/all []ProjectResponse
GET /api/project/archived []ProjectResponse
POST /api/project/ ProjectContainerRequest ProjectResponse
PUT /api/project/ ProjectContainerRequest {}
DELETE /api/project/ ProjectIdRequest {}
PUT /api/project/archive ProjectIdRequest {}
PUT /api/project/restore ProjectIdRequest {}
POST /api/project/copy/last/week StartAndEndDateRequest {} or TimeRangeResponse Empty if no records the prior week

Time

Method Path Request Response Notes
GET /api/time/week TimeRangeResponse
GET /api/time/week/{startDate} string TimeRangeResponse Date must be in the ISOShortDateFormat (e.g. "2006-01-02")
PUT /api/time/ TimeEntryRangeRequest {}
POST /api/time/project/week ProjectWeekRequest {}
DELETE /api/time/project/week ProjectDeleteRequest {}

Task

Method Path Request Response Notes
GET /api/task/{taskId} string TaskResponse
GET /api/task/all []TaskResponse
GET /api/task/archived []TaskResponse
POST /api/task/ TaskRequest TaskResponse
PUT /api/task/ TaskRequest {}
PUT /api/task/archive TaskRequest {}
PUT /api/task/restore TaskRequest {}
DELETE /api/task/ TaskRequest {}

Report

Method Path Request Response Notes
GET /api/report/time/client query parameters: from, to, page []ClientReportResponse from and to are date strings in the ISOShortDateFormat format
GET /api/report/time/project query parameters: from, to, page []ProjectReportResponse from and to are date strings in the ISOShortDateFormat format
GET /api/report/time/task query parameters: from, to, page []TaskReportResponse from and to are date strings in the ISOShortDateFormat format
GET /api/report/time/person query parameters: from, to, page []PersonReportResponse from and to are date strings in the ISOShortDateFormat format
GET /api/report/time/export/client query parameters: from, to CSV file with content type text/csv from and to are date strings in the ISOShortDateFormat format
GET /api/report/time/export/project query parameters: from, to CSV file with content type text/csv from and to are date strings in the ISOShortDateFormat format
GET /api/report/time/export/task query parameters: from, to CSV file with content type text/csv from and to are date strings in the ISOShortDateFormat format
GET /api/report/time/export/person query parameters: from, to CSV file with content type text/csv from and to are date strings in the ISOShortDateFormat format

Ping

Method Path Request Response Notes
GET /_ping Text 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 Code Error
400 http.StatusBadRequest
401 http.StatusUnauthorized
404 http.StatusNotFound
405 http.StatusMethodNotAllowed
500 http.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" }
}