A Go-based API service with SQLite storage and user authentication.
- Go 1.23.2
- SQLite3
- Make
- Clone the repository
- Run
make tidyto install dependencies - Copy
.env.exampleto.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/apiThe 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/healthcheckResponse 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=-usernameResponse 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/usersResponse 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/124Response 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/124Response 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/124Response: 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/roleResponse 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/activateResponse 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-passwordResponse 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/sessionResponse 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/sessionResponse: 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/activationResponse 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-resetResponse 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/varsResponse 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_idreferences theidcolumn in theuserstableON DELETE CASCADEensures tokens are automatically deleted when the associated user is deleted
- Write End-to-End tests