A Go-based API service with SQLite storage and user authentication.
- Go 1.23.2
- SQLite3
- Make
- Clone the repository
- Run
make tidy
to install dependencies - Copy
.env.example
to.env
:
cp .env.example .env
- Run database migrations to set up the database schema:
make db/migrations/up
- Seed the database:
make db/seed
- Start the development server with hot reload:
make watch/api
The API will be available at the port specified in your .env
file (default: 45067).
Run make help
to see all available commands. Here are the most commonly used ones:
make run/api
- Build and run the APImake watch/api
- Run the API with hot reload using Airmake tidy
- Format code and tidy up Go modules
make test
- Run all testsmake itest
- Run integration testsmake audit
- Run quality control checks (tests, format verification, vulnerability scanning)
make db/migrations/new name=migration_name
- Create a new migrationmake db/migrations/up
- Apply all pending migrationsmake db/migrations/down
- Revert all migrationsmake db/seed
- Seed the database with initial datamake db/connect
- Connect to the SQLite database
This document provides comprehensive documentation for all API endpoints, including required permissions, request/response formats, and examples.
Method | Endpoint | Permission | Description |
---|---|---|---|
GET | /v1/healthcheck | Public | Application health status |
GET | /v1/users | Admin | List users |
POST | /v1/users | Public | Create new user |
GET | /v1/users/:id | Admin or Owner | Get user details |
PATCH | /v1/users/:id | Admin or Owner | Update user details |
DELETE | /v1/users/:id | Admin or Owner | Delete user account |
PATCH | /v1/users/:id/role | Admin | Update user role |
POST | /v1/users/activate | Public | Activate user account |
POST | /v1/users/reset-password | Public | Reset user password |
POST | /v1/tokens/session | Public | Generate auth token |
DELETE | /v1/tokens/session | Public | Delete auth token |
POST | /v1/tokens/activation | Public | Request activation token |
POST | /v1/tokens/password-reset | Public | Request password reset |
GET | /debug/vars | Admin | Debug metrics |
For endpoints requiring authentication, include the authentication token in the Authorization header:
Authorization: Bearer <token>
Tokens can be obtained using the /v1/auth/authentication endpoint.
Permission: Public
Description: Check application health status and version information
Example Request:
curl http://localhost:45067/v1/healthcheck
Response Body:
status
(string): Current application statussystem_info
(object):environment
(string): Current environmentversion
(string): Application version
Example Response:
{
"status": "available",
"system_info": {
"environment": "development",
"version": "2024-01-15T10:30:00Z-c3418de38b57f0a8bf49d9f7759469eac37cb410"
}
}
Permission: Public
Description: List users
Query Parameters:
username
(string): Usernameemail
(string): User's email addresspage
(number): Pagepage_size
(number): Page sizesort
(number): Sort order (must be 'id', 'username', 'email', 'role', '-id', '-username', '-email', '-role')
Request Headers:
Authorization
: Bearer token
Example Request:
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:45067/v1/users?email=example&page=2&page_size=10&sort=-username
Response Body:
data
(array): User detailsmetadata
(object): Metadata details
Example Response:
{
"data": [
{
"id": 123,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T11:45:00Z",
"username": "alice",
"email": "[email protected]",
"activated": true,
"role": "user"
}
{
"id": 124,
"created_at": "2024-01-15T14:00:00Z",
"updated_at": "2024-01-15T14:00:00Z",
"username": "bob",
"email": "[email protected]",
"activated": false,
"role": "user"
},
],
"metadata": {
"current_page": 1,
"page_size": 20,
"first_page": 1,
"last_page": 1,
"total_records": 2
}
}
Permission: Public
Description: Create a new user account
Request Body:
username
(string): Usernameemail
(string): User's email addresspassword
(string): User's password
Example Request:
curl -X POST \
-d '{"username": "bob", "email": "[email protected]", "password": "SecurePass123!"}' \
http://localhost:45067/v1/users
Response Body:
data
(object): User details
Example Response:
{
"data": {
"id": 124,
"created_at": "2024-01-15T14:00:00Z",
"updated_at": "2024-01-15T14:00:00Z",
"username": "bob",
"email": "[email protected]",
"activated": false,
"role": "user"
}
}
Permission: Admin or Owner
Description: Retrieve user details by ID
Path Parameters:
id
(number): User ID
Request Headers:
Authorization
: Bearer token
Example Request:
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:45067/v1/users/124
Response Body:
data
(object): User details object
Example Response:
{
"data": {
"id": 124,
"created_at": "2024-01-15T14:00:00Z",
"updated_at": "2024-01-15T14:00:00Z",
"username": "bob",
"email": "[email protected]",
"activated": false,
"role": "user"
}
}
Permission: Admin or Owner
Description: Update user details
Path Parameters:
id
(number): User ID
Request Headers:
Authorization
: Bearer token
Request Body: (all fields optional)
username
(string): New usernameemail
(string): New emailpassword
(string): New password
Example Request:
curl -H "Authorization: Bearer $TOKEN" \
-X PATCH \
-d '{"username": "robert"}' \
http://localhost:45067/v1/users/124
Response Body:
data
(object): Updated user details
Example Response:
{
"data": {
"id": 124,
"created_at": "2024-01-15T14:00:00Z",
"updated_at": "2024-01-15T15:30:00Z",
"username": "robert",
"email": "[email protected]",
"activated": false,
"role": "user"
}
}
Permission: Admin or Owner
Description: Delete user account
Path Parameters:
id
(number): User ID
Request Headers:
Authorization
: Bearer token
Example Request:
curl -H "Authorization: Bearer $TOKEN" \
-X DELETE \
http://localhost:45067/v1/users/124
Response: 204 No Content
Permission: Admin
Description: Update user's role
Path Parameters:
id
(number): User ID
Request Headers:
Authorization
: Bearer token
Request Body:
role
(string): New role (must be 'admin' or 'user')
Example Request:
curl -H "Authorization: Bearer $TOKEN" \
-X PATCH \
-d '{"role": "admin"}' \
http://localhost:45067/v1/users/124/role
Response Body:
data
(object): Updated user details
Example Response:
{
"data": {
"id": 124,
"created_at": "2024-01-15T14:00:00Z",
"updated_at": "2024-01-15T16:00:00Z",
"username": "robert",
"email": "[email protected]",
"activated": false,
"role": "admin"
}
}
Permission: Public
Description: Activate user account
Request Body:
token
(string): Activation token
Example Request:
curl -X POST \
-d '{"token": "URQXUFRJDA4KCIZ3CLZTHS3K3U"}' \
http://localhost:45067/v1/users/activate
Response Body:
data
(object): Updated user details
Example Response:
{
"data": {
"id": 123,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"username": "alice",
"email": "[email protected]",
"activated": true,
"role": "user"
}
}
Permission: Public
Description: Reset user password
Request Body:
password
(string): New passwordtoken
(string): Password reset token
Example Request:
curl -X POST \
-d '{"password": "SecurePass123!", "token": "K5YB7CA3KTZL4B6YXO5JLNLWWU"}' \
http://localhost:45067/v1/users/reset-password
Response Body:
data
(object): Updated user details
Example Response:
{
"data": {
"id": 123,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T11:45:00Z",
"username": "alice",
"email": "[email protected]",
"activated": true,
"role": "user"
}
}
Permission: Public
Description: Generate authentication token
Request Body:
email
(string): User's emailpassword
(string): User's password
Example Request:
curl -X POST \
-d '{"email": "[email protected]", "password": "AdminPass123!"}' \
http://localhost:45067/v1/tokens/session
Response Body:
authentication_token
(object):token
(string): Authentication tokenexpiry
(string): Token expiration timestamp
Example Response:
{
"authentication_token": {
"token": "QNSMBHTILTB4RDRTMRYACTGCTE",
"expiry": "2024-01-15T13:30:00Z"
}
}
Permission: Authenticated
Description: Delete auth token
Request Headers:
Authorization
: Bearer token
Example Request:
curl -H "Authorization: Bearer $TOKEN" \
-X DELETE \
http://localhost:45067/v1/tokens/session
Response: 204 No Content
Permission: Public
Description: Request new activation token
Request Body:
email
(string): User's email
Example Request:
curl -X POST \
-d '{"email": "[email protected]"}' \
http://localhost:45067/v1/tokens/activation
Response Body:
message
(string): Confirmation message
Example Response:
{
"message": "an email will be sent to you containing activation instructions"
}
Permission: Public
Description: Request password reset token
Request Body:
email
(string): User's email
Example Request:
curl -X POST \
-d '{"email": "[email protected]"}' \
http://localhost:45067/v1/tokens/password-reset
Response Body:
message
(string): Confirmation message
Example Response:
{
"message": "an email will be sent to you containing password reset instructions"
}
Permission: Admin
Description: Displays application metrics for debugging purposes
Request Headers:
Authorization
: Bearer token
Example Request:
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:45067/debug/vars
Response Body:
- Various debugging metrics and application variables
The application uses SQLite as its database engine with the following schema:
Stores user account information and credentials.
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password_hash BLOB NOT NULL,
activated BOOLEAN NOT NULL DEFAULT false,
role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('user', 'admin')),
version INTEGER NOT NULL DEFAULT 1
);
Columns:
id
: Unique identifier for each usercreated_at
: Timestamp of account creationupdated_at
: Timestamp of last account updateusername
: Unique usernameemail
: Unique email addresspassword_hash
: Hashed user password (stored as BLOB)activated
: Account activation statusrole
: User role (either 'user' or 'admin')version
: Record version for optimistic locking
An updated_at
trigger automatically updates the timestamp when the record changes:
CREATE TRIGGER set_updated_at
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
UPDATE users SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id;
END;
Stores authentication, activation, and password reset tokens.
CREATE TABLE IF NOT EXISTS tokens (
hash BLOB PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
expiry DATETIME NOT NULL,
scope TEXT NOT NULL
);
Columns:
hash
: Hashed token value (primary key)user_id
: Associated user ID (foreign key to users table)expiry
: Token expiration timestampscope
: Token purpose/scope (e.g., 'authentication', 'activation', 'password-reset')
Relationships:
user_id
references theid
column in theusers
tableON DELETE CASCADE
ensures tokens are automatically deleted when the associated user is deleted
- Write End-to-End tests