turniere-backend/AGENTS.md

5.7 KiB

turniere-backend Agent Notes

This repository should be operated through invoke tasks by default.

For routine development, verification, Docker, and E2E work, agents should use inv ... rather than ad-hoc shell commands unless there is a strong reason not to.

Default Workflow

Use tasks.py and run commands through inv ... instead of ad-hoc shell commands for routine work.

Local Setup

Assume Ruby is already installed at the version from .ruby-version.

For local development, the preferred path is:

  • inv setup
  • inv start-local

inv setup installs the Bundler version pinned in Gemfile.lock, configures Bundler for local development (development test, without production), and runs bundle install.

inv start-local runs the normal local bootstrap flow:

  • inv setup
  • inv db-migrate
  • optional local user bootstrap via --bootstrap-user
  • Rails server start on 0.0.0.0:3000

Useful local commands:

  • inv setup
  • inv db-reset --env=test
  • inv db-migrate
  • inv server
  • inv start-local
  • inv start-local --bootstrap-user
  • inv start-test-local
  • inv bootstrap-dev-user
  • inv bootstrap-e2e-user

Examples:

  • inv db-migrate
  • inv test
  • inv test-shard --node-index=1 --node-total=8
  • inv lint
  • inv verify-http
  • inv blackbox-production
  • inv scenario-main-usecase
  • inv docker-build-all
  • inv docker-test-shard --node-index=3 --node-total=8
  • inv docker-test-http-e2e

Concurrent Local Testing

If other agents or local runs may already be using shared test resources, do not reuse db/test.sqlite3 or fixed ports for ad-hoc verification.

Prefer isolated per-run resources instead:

  • use a unique temporary sqlite database via DATABASE_URL=sqlite3:/tmp/...
  • choose open ports automatically or derive unique ports per run
  • keep normal repo tasks as default, but use isolated overrides when avoiding collisions is important

Practical expectation:

  • for targeted/spec-specific verification where inv does not provide isolation knobs, it is acceptable to run the underlying command with isolated env vars
  • if isolated local verification becomes recurring, add or extend an inv task for it

For local E2E-style startup with a usable login, prefer:

  • inv start-local --bootstrap-user
  • inv start-test-local

inv start-test-local is preferred for cross-repo or Playwright-style local E2E runs. It recreates db/test.sqlite3 on every run, re-migrates, bootstraps the default E2E users, and starts Rails in test mode on 0.0.0.0:3000.

Default local bootstrap credentials:

  • email: e2e@example.com
  • password: password123
  • username: e2e-user

The GitLab CI pipeline is expected to use these tasks as well. In CI, blackbox E2E should prefer the documented GitLab service-to-service model with FF_NETWORK_PER_BUILD: "true" when the production image needs to talk to a Postgres sidecar. The normal Rails spec suite is sharded through inv test-shard ... and should stay aligned with the CI matrix configuration.

Useful GitLab push-option variables for saving CI minutes on public repos:

  • skip all spec jobs: git push -o ci.variable="SKIP_ALL_SPECS=1"
  • skip only normal Rails specs: git push -o ci.variable="SKIP_RAILS_SPEC=1"
  • skip only blackbox E2E: git push -o ci.variable="SKIP_E2E_SPEC=1"

Do not use these by default. Only use them when the change truly does not affect the skipped area.

This is not just a convenience preference. The task layer is the operational contract for this repo and should stay aligned across local use, CI, and cross-repo consumers.

Why

The point of the task layer is:

  • one stable entrypoint for local development
  • one stable entrypoint for CI
  • one stable entrypoint for frontend and cross-repo test setup
  • fewer undocumented command variants

If a workflow matters often enough that a human or CI needs to remember it, it should usually become an invoke task.

Maintenance Rule

When new functionality or recurring maintenance work is added, extend tasks.py so the new workflow stays easy to discover and easy to run.

Do not leave important multi-step flows only in:

  • CI YAML
  • MR descriptions
  • shell history
  • team memory

Instead, add or update an inv task and then have CI or docs call that task.

If a new backend capability introduces a meaningful setup, verification, fixture, or scenario workflow, add or extend a task for it as part of the same change.

Local-Only Helper Code

If helper code exists only for local development, local profiling, or test/E2E support, prefer placing it in a path that the production Docker image does not copy.

Current production image copies:

  • app
  • bin
  • config
  • db
  • public
  • script
  • config.ru
  • Rakefile

It does not copy lib, spec, e2e, or tasks.py.

Practical rule:

  • production runtime code belongs in copied paths such as app/
  • local-only helpers should prefer lib/, spec/, e2e/, or task-layer code when feasible
  • if production must ignore a local-only feature, cover that with blackbox E2E against the production image

HTTP E2E

The backend HTTP E2E flow is intended to be reusable outside this repo, especially by frontend tests that need realistic backend state.

That means:

  • scenario creation should stay HTTP-driven
  • reusable scenario setup should be exposed through inv tasks and script/e2e_scenarios.rb
  • new commonly needed backend states should be added to the scenario/task layer, not recreated ad hoc in each consuming test suite
  • the released production image should be exercised through the blackbox task layer, not only Rails-internal test entrypoints

Practical Expectation

If you touch test, verification, boot, Docker, or scenario setup workflows, check whether tasks.py also needs to change.