> ## Documentation Index
> Fetch the complete documentation index at: https://docs.strait.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Contributing

> Guidelines for contributing to Strait project.

We welcome contributions to Strait! This document provides instructions on how to set up your development environment and the standards we follow.

## Getting Started

### Prerequisites

To build and run Strait locally, you need:

* **Go 1.26+**
* **Docker** (for running PostgreSQL, Redis, and Sequin)
* **Bun** (workspace package manager)
* **golangci-lint** (for linting)
* **lefthook** (for pre-commit hooks)

### Setup Instructions

1. **Clone the repository**:
   ```bash theme={null}
   git clone https://github.com/leonardomso/strait.git
   cd strait
   ```

2. **Start infrastructure**:
   Use Docker Compose to start the required services:
   ```bash theme={null}
   docker compose -f apps/strait/docker-compose.yml up -d
   ```

3. **Install workspace dependencies**:
   ```bash theme={null}
   bun install
   ```

4. **Install pre-commit hooks**:
   ```bash theme={null}
   lefthook install
   ```

5. **Run the application**:
   ```bash theme={null}
   export DATABASE_URL=postgres://strait:strait@localhost:5432/strait?sslmode=disable
   export REDIS_URL=redis://localhost:6379
   export INTERNAL_SECRET=your-secret
   export JWT_SIGNING_KEY=your-jwt-key-at-least-32-chars-long
   cd apps/strait && go run ./cmd/strait --mode all
   ```

## Code Style

We follow idiomatic Go patterns and specific project conventions:

* **Raw SQL**: We use `pgx/v5` and raw SQL for all database operations. Do not use an ORM.
* **Interface Segregation**: Define small, focused interfaces at the consumer side.
* **Error Handling**: Wrap errors using `%w` to provide context while preserving the original error type.
* **Collections**: Use `samber/lo` for collection operations (Map, Filter, KeyBy, Keys) instead of hand-written loops.
* **Concurrency**: Use `sourcegraph/conc` for goroutines (WaitGroup, pool). Never use bare `go` statements or `sync.WaitGroup` directly.
* **Worker Pool**: Use the `apps/strait/internal/worker` pond/v2 pool. Do not create custom goroutine pools.
* **Test Assertions**: Use `testutil.AssertEqual` (powered by `google/go-cmp`) for structural comparisons with rich diffs. Avoid manual field-by-field assertions.
* **No Emojis**: Avoid using emojis in code, comments, or documentation.

## Linting

We use `golangci-lint` with a strict set of 18+ linters configured in `apps/strait/.golangci.yml`.

To run the linter manually:

```bash theme={null}
cd apps/strait && golangci-lint run ./...
```

The linter checks for code duplication, unhandled errors, security vulnerabilities, and style consistency.

## Pre-commit Hooks

We use `lefthook` to run checks automatically before every commit. This ensures that all code entering the repository meets our quality standards.

Current pre-commit checks include:

* `golangci-lint`
* OpenAPI parity check (`apps/strait/scripts/check-openapi-parity/main.go`) to ensure `apps/strait/internal/api/routes.go`, `apps/strait/internal/api/openapi.yaml`, and `docs/openapi.yaml` stay in sync.

Manual parity check command:

```bash theme={null}
cd apps/strait && go run ./scripts/check-openapi-parity
```

If `lefthook` fails, you must fix the issues before you can commit your changes.

## Pull Request Guidelines

* **One Logical Change**: Each PR should focus on a single feature, bug fix, or refactoring.
* **Tests Required**: All new features and bug fixes must include corresponding tests (unit, integration, or E2E).
* **Documentation**: Update relevant documentation if your changes affect the public API or configuration.
* **Clean History**: Ensure your commit history is clean and messages are descriptive.

## Project Structure

* `apps/strait/cmd/strait/`: Server entrypoint and migration commands. CLI has moved to [strait-dev/cli](https://github.com/strait-dev/cli).
* `apps/strait/internal/`: Private application code.
  * `api/`: HTTP handlers and routing.
  * `domain/`: Core business logic and FSM definitions.
  * `store/`: Database access layer (raw SQL).
  * `worker/`: Job execution and pond/v2 worker pool with backpressure and OTel metrics.
  * `scheduler/`: Background tasks and polling (uses conc for structured concurrency).
  * `testutil/`: Shared testing helpers, go-cmp assertion utilities, and data factories.
* `apps/strait/migrations/`: SQL migration files embedded into the binary.
* `packages/`: Shared workspace packages (UI, SDKs, utilities, etc.).
