{"id":24794293,"url":"https://github.com/eckertalex/improved-fiesta","last_synced_at":"2025-03-24T18:13:39.463Z","repository":{"id":260596698,"uuid":"881582030","full_name":"eckertalex/improved-fiesta","owner":"eckertalex","description":"A Go-based API service with SQLite storage and user authentication","archived":false,"fork":false,"pushed_at":"2025-02-23T20:50:06.000Z","size":56,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-23T21:28:42.224Z","etag":null,"topics":["api","authentication","authorization","go","sqlite3","user-management"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eckertalex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-31T21:22:20.000Z","updated_at":"2025-02-23T20:50:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"cfcce9a8-c184-4089-8e30-a14981652236","html_url":"https://github.com/eckertalex/improved-fiesta","commit_stats":null,"previous_names":["eckertalex/improved-fiesta"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eckertalex%2Fimproved-fiesta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eckertalex%2Fimproved-fiesta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eckertalex%2Fimproved-fiesta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eckertalex%2Fimproved-fiesta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eckertalex","download_url":"https://codeload.github.com/eckertalex/improved-fiesta/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245325223,"owners_count":20596818,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","authentication","authorization","go","sqlite3","user-management"],"created_at":"2025-01-29T22:36:04.864Z","updated_at":"2025-03-24T18:13:39.454Z","avatar_url":"https://github.com/eckertalex.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Improved Fiesta 🎉\n\nA Go-based API service with SQLite storage and user authentication.\n\n## Getting Started\n\n### Prerequisites\n\n- Go 1.23.2\n- SQLite3\n- Make\n\n### Quick Start\n\n1. Clone the repository\n2. Run `make tidy` to install dependencies\n3. Copy `.env.example` to `.env`:\n\n```sh\ncp .env.example .env\n```\n\n4. Run database migrations to set up the database schema:\n\n```sh\nmake db/migrations/up\n```\n\n5. Seed the database:\n\n```sh\nmake db/seed\n```\n\n6. Start the development server with hot reload:\n\n```sh\nmake watch/api\n```\n\nThe API will be available at the port specified in your `.env` file (default: 45067).\n\n### Available Make Commands\n\nRun `make help` to see all available commands. Here are the most commonly used ones:\n\n#### Development\n\n- `make run/api` - Build and run the API\n- `make watch/api` - Run the API with hot reload using Air\n- `make tidy` - Format code and tidy up Go modules\n\n#### Testing\n\n- `make test` - Run all tests\n- `make itest` - Run integration tests\n- `make audit` - Run quality control checks (tests, format verification, vulnerability scanning)\n\n#### Database Operations\n\n- `make db/migrations/new name=migration_name` - Create a new migration\n- `make db/migrations/up` - Apply all pending migrations\n- `make db/migrations/down` - Revert all migrations\n- `make db/seed` - Seed the database with initial data\n- `make db/connect` - Connect to the SQLite database\n\n## API Documentation\n\nThis document provides comprehensive documentation for all API endpoints, including required permissions, request/response formats, and examples.\n\n### Table of Contents\n\n| Method | Endpoint                                                  | Permission     | Description               |\n| ------ | --------------------------------------------------------- | -------------- | ------------------------- |\n| GET    | [/v1/healthcheck](#get-v1healthcheck)                     | Public         | Application health status |\n| GET    | [/v1/users](#get-v1users)                                 | Admin          | List users                |\n| POST   | [/v1/users](#post-v1users)                                | Public         | Create new user           |\n| GET    | [/v1/users/:id](#get-v1usersid)                           | Admin or Owner | Get user details          |\n| PATCH  | [/v1/users/:id](#patch-v1usersid)                         | Admin or Owner | Update user details       |\n| DELETE | [/v1/users/:id](#delete-v1usersid)                        | Admin or Owner | Delete user account       |\n| PATCH  | [/v1/users/:id/role](#patch-v1usersid-role)               | Admin          | Update user role          |\n| POST   | [/v1/users/activate](#post-v1usersactivate)               | Public         | Activate user account     |\n| POST   | [/v1/users/reset-password](#post-v1usersreset-password)   | Public         | Reset user password       |\n| POST   | [/v1/tokens/session](#post-v1tokenssession)               | Public         | Generate auth token       |\n| DELETE | [/v1/tokens/session](#delete-v1tokenssession)             | Public         | Delete auth token         |\n| POST   | [/v1/tokens/activation](#post-v1tokensactivation)         | Public         | Request activation token  |\n| POST   | [/v1/tokens/password-reset](#post-v1tokenspassword-reset) | Public         | Request password reset    |\n| GET    | [/debug/vars](#get-debugvars)                             | Admin          | Debug metrics             |\n\n### Authentication\n\nFor endpoints requiring authentication, include the authentication token in the Authorization header:\n\n```\nAuthorization: Bearer \u003ctoken\u003e\n```\n\nTokens can be obtained using the [/v1/auth/authentication](#post-v1tokensauthentication) endpoint.\n\n### Endpoint Details\n\n#### GET /v1/healthcheck\n\n**Permission:** Public  \n**Description:** Check application health status and version information\n\n**Example Request:**\n\n```bash\ncurl http://localhost:45067/v1/healthcheck\n```\n\n**Response Body:**\n\n- `status` (string): Current application status\n- `system_info` (object):\n  - `environment` (string): Current environment\n  - `version` (string): Application version\n\n**Example Response:**\n\n```json\n{\n  \"status\": \"available\",\n  \"system_info\": {\n    \"environment\": \"development\",\n    \"version\": \"2024-01-15T10:30:00Z-c3418de38b57f0a8bf49d9f7759469eac37cb410\"\n  }\n}\n```\n\n#### GET /v1/users\n\n**Permission:** Public  \n**Description:** List users\n\n**Query Parameters:**\n\n- `username` (string): Username\n- `email` (string): User's email address\n- `page` (number): Page\n- `page_size` (number): Page size\n- `sort` (number): Sort order (must be 'id', 'username', 'email', 'role', '-id', '-username', '-email', '-role')\n\n**Request Headers:**\n\n- `Authorization`: Bearer token\n\n**Example Request:**\n\n```bash\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     http://localhost:45067/v1/users?email=example\u0026page=2\u0026page_size=10\u0026sort=-username\n```\n\n**Response Body:**\n\n- `data` (array): User details\n- `metadata` (object): Metadata details\n\n**Example Response:**\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": 123,\n      \"created_at\": \"2024-01-15T10:30:00Z\",\n      \"updated_at\": \"2024-01-15T11:45:00Z\",\n      \"username\": \"alice\",\n      \"email\": \"alice.johnson@example.com\",\n      \"activated\": true,\n      \"role\": \"user\"\n    }\n    {\n      \"id\": 124,\n      \"created_at\": \"2024-01-15T14:00:00Z\",\n      \"updated_at\": \"2024-01-15T14:00:00Z\",\n      \"username\": \"bob\",\n      \"email\": \"bob.smith@example.com\",\n      \"activated\": false,\n      \"role\": \"user\"\n    },\n  ],\n  \"metadata\": {\n    \"current_page\": 1,\n    \"page_size\": 20,\n    \"first_page\": 1,\n    \"last_page\": 1,\n    \"total_records\": 2\n  }\n}\n```\n\n#### POST /v1/users\n\n**Permission:** Public  \n**Description:** Create a new user account\n\n**Request Body:**\n\n- `username` (string): Username\n- `email` (string): User's email address\n- `password` (string): User's password\n\n**Example Request:**\n\n```bash\ncurl -X POST \\\n     -d '{\"username\": \"bob\", \"email\": \"bob.smith@example.com\", \"password\": \"SecurePass123!\"}' \\\n     http://localhost:45067/v1/users\n```\n\n**Response Body:**\n\n- `data` (object): User details\n\n**Example Response:**\n\n```json\n{\n  \"data\": {\n    \"id\": 124,\n    \"created_at\": \"2024-01-15T14:00:00Z\",\n    \"updated_at\": \"2024-01-15T14:00:00Z\",\n    \"username\": \"bob\",\n    \"email\": \"bob.smith@example.com\",\n    \"activated\": false,\n    \"role\": \"user\"\n  }\n}\n```\n\n#### GET /v1/users/:id\n\n**Permission:** Admin or Owner  \n**Description:** Retrieve user details by ID\n\n**Path Parameters:**\n\n- `id` (number): User ID\n\n**Request Headers:**\n\n- `Authorization`: Bearer token\n\n**Example Request:**\n\n```bash\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     http://localhost:45067/v1/users/124\n```\n\n**Response Body:**\n\n- `data` (object): User details object\n\n**Example Response:**\n\n```json\n{\n  \"data\": {\n    \"id\": 124,\n    \"created_at\": \"2024-01-15T14:00:00Z\",\n    \"updated_at\": \"2024-01-15T14:00:00Z\",\n    \"username\": \"bob\",\n    \"email\": \"bob.smith@example.com\",\n    \"activated\": false,\n    \"role\": \"user\"\n  }\n}\n```\n\n#### PATCH /v1/users/:id\n\n**Permission:** Admin or Owner  \n**Description:** Update user details\n\n**Path Parameters:**\n\n- `id` (number): User ID\n\n**Request Headers:**\n\n- `Authorization`: Bearer token\n\n**Request Body:** (all fields optional)\n\n- `username` (string): New username\n- `email` (string): New email\n- `password` (string): New password\n\n**Example Request:**\n\n```bash\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     -X PATCH \\\n     -d '{\"username\": \"robert\"}' \\\n     http://localhost:45067/v1/users/124\n```\n\n**Response Body:**\n\n- `data` (object): Updated user details\n\n**Example Response:**\n\n```json\n{\n  \"data\": {\n    \"id\": 124,\n    \"created_at\": \"2024-01-15T14:00:00Z\",\n    \"updated_at\": \"2024-01-15T15:30:00Z\",\n    \"username\": \"robert\",\n    \"email\": \"bob.smith@example.com\",\n    \"activated\": false,\n    \"role\": \"user\"\n  }\n}\n```\n\n#### DELETE /v1/users/:id\n\n**Permission:** Admin or Owner  \n**Description:** Delete user account\n\n**Path Parameters:**\n\n- `id` (number): User ID\n\n**Request Headers:**\n\n- `Authorization`: Bearer token\n\n**Example Request:**\n\n```bash\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     -X DELETE \\\n     http://localhost:45067/v1/users/124\n```\n\n**Response:** 204 No Content\n\n#### PATCH /v1/users/:id/role\n\n**Permission:** Admin  \n**Description:** Update user's role\n\n**Path Parameters:**\n\n- `id` (number): User ID\n\n**Request Headers:**\n\n- `Authorization`: Bearer token\n\n**Request Body:**\n\n- `role` (string): New role (must be 'admin' or 'user')\n\n**Example Request:**\n\n```bash\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     -X PATCH \\\n     -d '{\"role\": \"admin\"}' \\\n     http://localhost:45067/v1/users/124/role\n```\n\n**Response Body:**\n\n- `data` (object): Updated user details\n\n**Example Response:**\n\n```json\n{\n  \"data\": {\n    \"id\": 124,\n    \"created_at\": \"2024-01-15T14:00:00Z\",\n    \"updated_at\": \"2024-01-15T16:00:00Z\",\n    \"username\": \"robert\",\n    \"email\": \"bob.smith@example.com\",\n    \"activated\": false,\n    \"role\": \"admin\"\n  }\n}\n```\n\n#### POST /v1/users/activate\n\n**Permission:** Public  \n**Description:** Activate user account\n\n**Request Body:**\n\n- `token` (string): Activation token\n\n**Example Request:**\n\n```bash\ncurl -X POST \\\n     -d '{\"token\": \"URQXUFRJDA4KCIZ3CLZTHS3K3U\"}' \\\n     http://localhost:45067/v1/users/activate\n```\n\n**Response Body:**\n\n- `data` (object): Updated user details\n\n**Example Response:**\n\n```json\n{\n  \"data\": {\n    \"id\": 123,\n    \"created_at\": \"2024-01-15T10:30:00Z\",\n    \"updated_at\": \"2024-01-15T10:30:00Z\",\n    \"username\": \"alice\",\n    \"email\": \"alice.johnson@example.com\",\n    \"activated\": true,\n    \"role\": \"user\"\n  }\n}\n```\n\n#### POST /v1/users/reset-password\n\n**Permission:** Public  \n**Description:** Reset user password\n\n**Request Body:**\n\n- `password` (string): New password\n- `token` (string): Password reset token\n\n**Example Request:**\n\n```bash\ncurl -X POST \\\n     -d '{\"password\": \"SecurePass123!\", \"token\": \"K5YB7CA3KTZL4B6YXO5JLNLWWU\"}' \\\n     http://localhost:45067/v1/users/reset-password\n```\n\n**Response Body:**\n\n- `data` (object): Updated user details\n\n**Example Response:**\n\n```json\n{\n  \"data\": {\n    \"id\": 123,\n    \"created_at\": \"2024-01-15T10:30:00Z\",\n    \"updated_at\": \"2024-01-15T11:45:00Z\",\n    \"username\": \"alice\",\n    \"email\": \"alice.johnson@example.com\",\n    \"activated\": true,\n    \"role\": \"user\"\n  }\n}\n```\n\n#### POST /v1/tokens/session\n\n**Permission:** Public  \n**Description:** Generate authentication token\n\n**Request Body:**\n\n- `email` (string): User's email\n- `password` (string): User's password\n\n**Example Request:**\n\n```bash\ncurl -X POST \\\n     -d '{\"email\": \"admin@example.com\", \"password\": \"AdminPass123!\"}' \\\n     http://localhost:45067/v1/tokens/session\n```\n\n**Response Body:**\n\n- `authentication_token` (object):\n  - `token` (string): Authentication token\n  - `expiry` (string): Token expiration timestamp\n\n**Example Response:**\n\n```json\n{\n  \"authentication_token\": {\n    \"token\": \"QNSMBHTILTB4RDRTMRYACTGCTE\",\n    \"expiry\": \"2024-01-15T13:30:00Z\"\n  }\n}\n```\n\n#### DELETE /v1/tokens/session\n\n**Permission:** Authenticated  \n**Description:** Delete auth token\n\n**Request Headers:**\n\n- `Authorization`: Bearer token\n\n**Example Request:**\n\n```bash\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     -X DELETE \\\n     http://localhost:45067/v1/tokens/session\n```\n\n**Response:** 204 No Content\n\n#### POST /v1/tokens/activation\n\n**Permission:** Public  \n**Description:** Request new activation token\n\n**Request Body:**\n\n- `email` (string): User's email\n\n**Example Request:**\n\n```bash\ncurl -X POST \\\n     -d '{\"email\": \"alice.johnson@example.com\"}' \\\n     http://localhost:45067/v1/tokens/activation\n```\n\n**Response Body:**\n\n- `message` (string): Confirmation message\n\n**Example Response:**\n\n```json\n{\n  \"message\": \"an email will be sent to you containing activation instructions\"\n}\n```\n\n#### POST /v1/tokens/password-reset\n\n**Permission:** Public  \n**Description:** Request password reset token\n\n**Request Body:**\n\n- `email` (string): User's email\n\n**Example Request:**\n\n```bash\ncurl -X POST \\\n     -d '{\"email\": \"alice.johnson@example.com\"}' \\\n     http://localhost:45067/v1/tokens/password-reset\n```\n\n**Response Body:**\n\n- `message` (string): Confirmation message\n\n**Example Response:**\n\n```json\n{\n  \"message\": \"an email will be sent to you containing password reset instructions\"\n}\n```\n\n#### GET /debug/vars\n\n**Permission:** Admin  \n**Description:** Displays application metrics for debugging purposes\n\n**Request Headers:**\n\n- `Authorization`: Bearer token\n\n**Example Request:**\n\n```bash\ncurl -H \"Authorization: Bearer $TOKEN\" \\\n     http://localhost:45067/debug/vars\n```\n\n**Response Body:**\n\n- Various debugging metrics and application variables\n\n## Database Schema\n\nThe application uses SQLite as its database engine with the following schema:\n\n### Users Table\n\nStores user account information and credentials.\n\n```sql\nCREATE TABLE IF NOT EXISTS users (\n    id INTEGER PRIMARY KEY AUTOINCREMENT,\n    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    username TEXT UNIQUE NOT NULL,\n    email TEXT UNIQUE NOT NULL,\n    password_hash BLOB NOT NULL,\n    activated BOOLEAN NOT NULL DEFAULT false,\n    role TEXT NOT NULL DEFAULT 'user' CHECK (role IN ('user', 'admin')),\n    version INTEGER NOT NULL DEFAULT 1\n);\n```\n\n**Columns:**\n\n- `id`: Unique identifier for each user\n- `created_at`: Timestamp of account creation\n- `updated_at`: Timestamp of last account update\n- `username`: Unique username\n- `email`: Unique email address\n- `password_hash`: Hashed user password (stored as BLOB)\n- `activated`: Account activation status\n- `role`: User role (either 'user' or 'admin')\n- `version`: Record version for optimistic locking\n\nAn `updated_at` trigger automatically updates the timestamp when the record changes:\n\n```sql\nCREATE TRIGGER set_updated_at\nAFTER UPDATE ON users\nFOR EACH ROW\nBEGIN\n    UPDATE users SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id;\nEND;\n```\n\n### Tokens Table\n\nStores authentication, activation, and password reset tokens.\n\n```sql\nCREATE TABLE IF NOT EXISTS tokens (\n    hash BLOB PRIMARY KEY,\n    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n    expiry DATETIME NOT NULL,\n    scope TEXT NOT NULL\n);\n```\n\n**Columns:**\n\n- `hash`: Hashed token value (primary key)\n- `user_id`: Associated user ID (foreign key to users table)\n- `expiry`: Token expiration timestamp\n- `scope`: Token purpose/scope (e.g., 'authentication', 'activation', 'password-reset')\n\n**Relationships:**\n\n- `user_id` references the `id` column in the `users` table\n- `ON DELETE CASCADE` ensures tokens are automatically deleted when the associated user is deleted\n\n## Todo\n\n- [ ] Write End-to-End tests\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feckertalex%2Fimproved-fiesta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feckertalex%2Fimproved-fiesta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feckertalex%2Fimproved-fiesta/lists"}