An open API service indexing awesome lists of open source software.

https://github.com/boutaj/raqym

Arabic-first productivity backend built with Go, PostgreSQL, JWT auth, and role-based access control
https://github.com/boutaj/raqym

chi docker go jwt postgresql

Last synced: about 1 month ago
JSON representation

Arabic-first productivity backend built with Go, PostgreSQL, JWT auth, and role-based access control

Awesome Lists containing this project

README

          

# Raqym

Raqym is a Go-based task management API built for Arabic-first productivity workflows. It focuses on the backend foundations of a real product: authentication, account activation, role-aware access control, task and list management, pagination, filtering, and API documentation.
It includes layered architecture, transactional user onboarding, JWT-based authentication, SMTP-backed email flows, SQL migrations, and a documented HTTP API.

## Core Features

- User registration with password hashing
- Email-based account activation flow
- JWT authentication for protected endpoints
- Basic auth protection for internal tooling endpoints
- Fixed-window rate limiting for API traffic
- Optional Redis-backed user caching
- List creation and management
- Task creation, retrieval, update, delete, search, and pagination
- Role-aware access checks
- Graceful shutdown on interrupt/termination signals
- Swagger/OpenAPI documentation

## Tech Stack

- Language: Go
- Router: `chi`
- Database: PostgreSQL
- Migrations: `golang-migrate`
- Auth: JWT
- Password hashing: Argon2id
- Mail: SMTP
- Cache / in-memory store: Redis
- Rate limiting: custom fixed-window limiter
- Logging: `zap`
- API docs: `swaggo`
- Local services: Docker Compose, PostgreSQL, Redis

## Architecture

The codebase follows a pragmatic layered structure:

- `cmd/api`
HTTP entrypoint, route registration, middleware, handlers, and response helpers.
- `internal/repository`
Data access layer for users, roles, tasks, lists, and pagination queries.
- `internal/repository/cache`
Redis-backed cache storage for frequently accessed user records.
- `internal/auth`
JWT generation and validation.
- `internal/mailer`
SMTP client and email templates for invitation and activation flows.
- `internal/ratelimiter`
Fixed-window rate limiter used by API middleware.
- `internal/db`
Database connection setup and seed support.
- `internal/env`
Environment variable loading helpers.
- `cmd/migrate`
SQL migrations and seed entrypoints.
- `scripts`
First-time database initialization SQL.
- `docs`
Generated Swagger artifacts.

## API Highlights

The API is versioned under `/v1` and includes routes for:

- `GET /healthz`
Basic-auth protected health check.
- `GET /docs/*`
Basic-auth protected Swagger UI and OpenAPI documentation.
- `POST /authentication/user`
Register a user and trigger the activation flow.
- `PUT /users/activate/{token}`
Activate an invited user account.
- `POST /authentication/token`
Exchange credentials for a JWT.
- `GET /users/me`
Retrieve the authenticated user profile.
- `GET /tasks`
List tasks with pagination, priority filtering, search, and sorting.
- `POST /tasks`
Create a task.
- `GET /tasks/{taskID}`
Fetch a single task.
- `PATCH /tasks/{taskID}`
Update a task.
- `DELETE /tasks/{taskID}`
Delete a task.
- `POST /lists`
Create a list.
- `GET /lists/{listID}`
Fetch a single list.
- `PATCH /lists/{listID}`
Update a list.
- `DELETE /lists/{listID}`
Delete a list.

Swagger UI is exposed through the docs route when the API is running. Use the configured Basic Auth credentials to access `/v1/healthz` and `/v1/docs/*`.

## Local Setup

### Prerequisites

- Go installed locally
- Docker and Docker Compose
- PostgreSQL migration CLI if you want to run migrations manually via `make`
- Air if you want live reload while developing

### 1. Start Local Services

```bash
docker compose up -d
```

This starts the local PostgreSQL and Redis containers used for development.

### 2. Configure Environment Variables

Create an `.env` file in the project root with values for the server, database, auth, and SMTP settings used by the app.

Typical variables used by this project include:

```env
SERVER_ADDR=localhost:8080
FRONTEND_URL=http://localhost:4000
ENV=development

DATABASE_ADDR=postgres://user:password@localhost:5432/taskmanager?sslmode=disable
DATABASE_MAX_OPEN_CONS=30
DATABASE_MAX_IDLE_CONS=30
DATABASE_MAX_IDLE_TIME=15m

REDIS_ADDR=0.0.0.0:6379
REDIS_PW=
REDIS_DB=0
REDIS_ENABLED=true

AUTH_BASIC_USER=admin
AUTH_BASIC_PASS=admin
JWT_AUTH_SECRET=change-me
APP_NAME=taskmanager

SMTP_FROMEMAIL=admin@raqym.com
SMTP_HOST=localhost
SMTP_PORT=25
SMTP_USERNAME=
SMTP_PASSWORD=

POSTGRES_DB=taskmanager
POSTGRES_USER=user
POSTGRES_PASSWORD=password

RATELIMITER_REQ_COUNT=20
RATELIMITER_EN=true
```

### 3. Initialize the Database

If the `taskmanager` database does not already exist, run the first-time setup SQL before migrations:

```bash
docker compose exec -T db psql -U user -d postgres < scripts/db_init.sql
```

If you are using the included Docker Compose setup from a fresh volume, PostgreSQL may already create the database from `POSTGRES_DB=taskmanager`, so you can skip this step when the database already exists.

### 4. Run Migrations

```bash
make migrate-up
```

### 5. Seed Data

```bash
make seed
```

### 6. Run the API

For development with live reload, install Air if you do not already have it:

```bash
go install github.com/air-verse/air@latest
```

Then run the API with:

```bash
air
```

If you do not want to install Air, you can run the API directly with Go:

```bash
go run ./cmd/api
```

## Useful Commands

```bash
make db-connect # Connect to the PostgreSQL CLI
make redis-connect # Connect to the Redis CLI
docker compose exec -T db psql -U user -d postgres < scripts/db_init.sql
# Run the db_init.sql file in the PostgreSQL CLI
make migrate-up # Run migrations
make migrate-down # Roll back migrations
make seed # Seed the database with data
make test # Test the endpoints
air # Run the Go live-reloading tool
```

## Engineering Notes

Some decisions in this codebase were made to reflect backend engineering concerns beyond basic endpoint wiring:

- Middleware-driven auth to keep handlers focused on business logic
- Repository layer to isolate SQL from transport concerns
- Transactional user creation plus invitation persistence
- SAGA-style compensation flow when user creation succeeds but email delivery fails
- Validation at the request boundary
- Structured logging for operational visibility
- Redis-backed caching for authenticated user lookup when Redis is enabled
- Fixed-window rate limiting with `Retry-After` responses
- Graceful shutdown on `SIGINT` and `SIGTERM`
- Swagger annotations to keep the API explorable for reviewers and collaborators

## What I’d Build Next

- [ ] Refresh tokens and token revocation
- [ ] Better authorization policies for shared or admin-managed resources
- [ ] Broader test coverage for handlers and repository logic
- [ ] Background job processing for email delivery
- [x] Add API user authentication and activation handler tests
- [x] Implement graceful shutdown for the HTTP server and background resources
- [x] Add Redis caching for authenticated user lookup
- [x] Add rate limiting to protect authentication and public-facing endpoints
- [ ] Expose server metrics for monitoring and observability
- [ ] Set up CI/CD pipelines for linting, testing, and deployment
- [ ] Deploy the application on AWS
- [ ] Frontend client for the Arabic-first product experience