# AGENTS.md ## Project overview BTRC Hub / タグ広場 is a split Rails API and React frontend repository. - Backend: Rails API under `backend/`. - Frontend: React + TypeScript + Vite under `frontend/`. - Docs: lightweight command notes under `docs/`. - There is no README or Makefile at the repository root as of this inspection. ## Stack - Backend: Ruby `3.2.2` from `backend/.ruby-version`, Rails `~> 8.0.2`. - Backend dependencies include `mysql2`, `sqlite3`, `rspec-rails`, `factory_bot_rails`, `rack-cors`, `jwt`, `discard`, `gollum`, `whenever`, `aws-sdk-s3`, `brakeman`, and `rubocop-rails-omakase`. - Frontend: React `^19.1.0`, TypeScript `~5.8.3`, Vite `^6.3.5`. - Frontend data/UI dependencies include Axios, TanStack Query, Tailwind CSS, Framer Motion, Radix UI components, lucide-react, MDX/Markdown tooling, and Zustand. ## Main directories - `backend/app/controllers`: Rails API controllers. - `backend/app/models`: Active Record models. - `backend/app/representations`: API response representation classes. - `backend/app/services`: domain services such as version recording, wiki commit, YouTube sync, and similarity calculation. - `backend/config/routes.rb`: API routes. - `backend/db/migrate`: migrations. - `backend/db/schema.rb`: current schema snapshot. - `backend/lib/tasks`: custom Rake tasks. - `backend/spec`: RSpec tests. - `backend/test`: Rails minitest files that still exist in the tree. - `frontend/src/App.tsx`: frontend route definitions and initial user setup. - `frontend/src/pages`: page-level React components. - `frontend/src/components`: shared and feature components. - `frontend/src/lib`: API client helpers, query keys, prefetchers, and domain helpers. - `frontend/src/stores`: Zustand stores. - `docs/commands.md`: command notes. ## Commands Only list commands that are backed by files inspected in this repository. ### Backend The following binstubs exist under `backend/bin`: ```sh cd backend bin/setup bin/dev bin/rails bin/rake bin/rubocop bin/brakeman bin/kamal bin/thrust ``` Common Rails/Rake usage through existing binstubs: ```sh cd backend bin/rails db:prepare bin/rails db:migrate bin/rails routes bin/rails server bin/rake bin/rubocop bin/brakeman ``` RSpec is present in `Gemfile` and `.rspec` exists: ```sh cd backend bundle exec rspec ``` ### Frontend The following npm scripts exist in `frontend/package.json`: ```sh cd frontend npm run dev npm run build npm run lint npm run test npm run test:run npm run preview ``` `npm run build` runs `tsc -b && vite build`, then `postbuild` runs `node scripts/generate-sitemap.js`. `npm run test` runs Vitest in watch mode. Use `npm run test:run` for a non-watch frontend test run. ## Coding style - Prefer precise, minimal changes. - Do not flatter or over-explain. - Explain risks directly. - Prefer single quotes for strings unless interpolation or escaping makes double quotes better. - Ruby: never put a space before method-call parentheses. - Ruby: never put a line break immediately before `)`. - Ruby: do not use `%w` or `%i`. - Ruby hashes are not blocks; keep `}` on the same line as the final pair. - Ruby hashes keep the first pair on the same line as `{` unless line length requires a break. - Ruby blocks use separate `{ ... }` rules from hashes, with 2-space body indentation. - TypeScript and Python: use GNU-style spacing before parentheses where syntactically valid. - Never write Ruby, TypeScript, or TSX lines longer than 99 characters. - Aim to keep Ruby, TypeScript, and TSX lines within 79 characters where practical. - TypeScript and TSX use 4-space logical indentation. - In TypeScript and TSX only, replace every leading run of 8 spaces with a tab. - Tabs are only for leading indentation, never for spaces after non-space text. - Do not add production dependencies without explicit approval. ## Backend rules - Inspect existing routes, controllers, models, services, and specs before editing backend behavior. - For API behavior changes, add or update request specs under `backend/spec/requests`. - Prefer RSpec for new backend tests; existing minitest files under `backend/test` do not make minitest the default for new coverage. - Do not weaken authentication, BAN user checks, or IP BAN checks. - Preserve the `X-Transfer-Code` user identification flow unless the task explicitly changes authentication. - Be careful with version tables, `version_no`, optimistic concurrency, wiki revisions, and restore/diff behavior. - Be careful with tag names, tag normalization, implications, similarities, and discard behavior. - Be sensitive to N+1 queries; avoid introducing them and proactively fix existing N+1 issues in the code path being edited. - Keep migration files and `backend/db/schema.rb` consistent when changing schema. ## Frontend rules - Use `frontend/src/lib/api.ts` for API calls so headers and camelCase conversion stay consistent. - Add or reuse TanStack Query keys through `frontend/src/lib/queryKeys.ts`; avoid ad hoc query key arrays. - Encode URL path-segment values with `encodeURIComponent`. - React hooks must be called unconditionally. - Keep page-level code under `frontend/src/pages` and shared UI/feature code under `frontend/src/components` unless existing patterns point elsewhere. - Match existing Tailwind, component, and import alias conventions. ### Frontend TSX style - Preserve the local TSX formatting style. - Do not normalize TSX to common Prettier-style React formatting unless explicitly asked. - Prefer `const` arrow functions for TypeScript/TSX component and helper declarations. - Put two blank lines before and after top-level `const` function declarations, unless imports, exports, or file boundaries make that awkward. - In TSX, indent with 4-space logical indentation. - A leading tab is exactly equivalent to 8 leading spaces. - Keep a tag's closing marker on the same line as the final prop when the tag spans multiple lines. - Do not put `/>` or `>` on its own line unless the existing surrounding code does so. - Keep JSX closing parentheses in the existing compact style, for example `)` rather than moving `)` onto a separate line. - Do not add braces around `if`, `else`, or `for` bodies when the body is a single physical line. - Always add braces around `if`, `else`, or `for` bodies when the body spans two or more physical lines, even if it is one statement. Preferred: ```tsx const PostFormTagsArea: FC = ({ tags, setTags, errors, ...rest }) => { return (