AGENTS.md
Rama master · réplica de lectura del repositorio original.
# Agent Instructions
CSA Admin is a multi-tenant Rails app for Community Supported Agriculture organizations. Each tenant is an isolated SQLite database, resolved from the request host, not an `org_id` column. Domain terms: `.agents/glossary.md`.
## Commands
- Iterate with filtered `bin/ci` (`-g style|security|tests`, `-s "Style: RuboCop"`, `-f`). Names match `config/ci.rb`.
- Full tests: `bin/rails test:all` (`acme` tenant). Minitest, Capybara, parallel, WebMock; stub HTTP, no process-global mutable state.
- Final: `bin/ci`. Single-tool wrappers: `bin/rubocop`, `bin/locales`, `bin/herb`, `bin/jactionlint`, `bin/shellcheck`, `bin/jobs check`.
- Setup: `mise bootstrap`. Upgrades: `bin/update` (review the diff).
- `bin/ci` `--group`/`--step` is `config/ci_filter.rb` until upstream Rails has both. Groups themselves are upstream.
## Tenant
`lib/tenant.rb`, `config/tenant.yml`.
- One tenant: `Tenant.switch(name) { ... }`. Cross-tenant: `Tenant.switch_each`. Current: `Tenant.current`, `Current.org`.
- Never query tenant models outside a switch, nest switches to another tenant, or carry Active Record objects across tenants.
- `TENANT` restricts `Tenant.all`, including db tasks in `lib/tasks/database.rake`.
- Tenant jobs inherit `ApplicationJob`; `perform_later` from inside a switch, never `perform_now`. Fan-out: `TenantSwitchEachJob.perform_later("MyJobClassName")`. Cross-tenant orchestrators inherit `ActiveJob::Base`.
- Gate features with `Current.org.feature?`. Fiscal years: `Current.fiscal_year` or `Current.org.fiscal_year_for`, not `Date.current.year`.
- Discardable: `.kept`, `can_destroy?`, `can_discard?`. Exports: `member&.display_id`, never `member.id` (`test/models/member/discardable_test.rb`).
Dev: `bin/dev` on `http://*.localhost:3000` (`DEV_ORIGIN=localhost`), or puma-dev on `https://*.test`. Hosts: `.agents/browser/README.md`. `acme` is test-only.
## Code
Vanilla Rails, rich models. No service, query, or form objects. Model concerns: `app/models/member/billing.rb`; shared: `app/models/concerns/`.
ActiveAdmin: `app/admin/`, DSL `lib/active_admin/`. Custom actions must authorize via `Ability`. UI: `DESIGN.md`.
Importmap, Turbo, Stimulus, Lucide, no-build CSS.
Copy: `TRANSLATIONS.md` and the `translations` skill. Never overwrite tenant-customized mail or newsletter content when changing source defaults.
## Hands off
Leave `db/schema.rb`, `db/queue_schema.rb`, applied migrations, tenant SQLite files, credentials, and `config/tenant.yml` hosts alone unless that is the task. Do not re-enable `db:prepare` in `bin/docker-entrypoint`.
Production deploys from `master` after CI via `.github/workflows/deploy.yml`. Tenant and queue migrations run in `.kamal/hooks/pre-deploy` on the new image.
## Banking
Credentials only on tenant-local `bank_connections`. Runtime: `Current.org.active_bank_connection` / `Current.org.bank_connection`. H005/BTF only; no org credential columns, no H003/H004. Setup: `docs/bank_connections.md`.