Strait Docs
Development

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:

    git clone https://github.com/leonardomso/strait.git
    cd strait
  2. Start infrastructure: Use Docker Compose to start the required services:

    docker compose -f apps/strait/docker-compose.yml up -d
  3. Install workspace dependencies:

    bun install
  4. Install pre-commit hooks:

    lefthook install
  5. Run the application:

    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
    go run ./apps/strait/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:

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:

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/: Entry point for the CLI and server. Contains command definitions.
  • 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.).
Was this page helpful?

On this page