2de7e13a8a
#346 Co-authored-by: miteruzo <miteruzo@naver.com> Reviewed-on: #347
6.3 KiB
6.3 KiB
backend/AGENTS.md
Scope
These rules apply to work under backend/.
This is a Rails API app using Active Record, RSpec, request specs, service objects, representation classes, and version tables for post/tag/wiki history.
Commands
Use commands backed by files and dependencies in this directory:
bin/setup
bin/dev
bin/rails
bin/rake
bin/rubocop
bin/brakeman
bundle exec rspec
Common checks:
bundle exec rspec
bin/rubocop
bin/brakeman
Common Rails commands:
bin/rails db:prepare
bin/rails db:migrate
bin/rails routes
bin/rails server
After backend behavior changes, run the relevant RSpec files. For broad backend changes, run:
bundle exec rspec
If a command cannot be run or fails, report the exact command and failure.
Rails structure
app/controllers: API controllers.app/models: Active Record models and concerns.app/representations: JSON response shaping.app/services: domain services such as version recorders, wiki commit, YouTube sync, and similarity calculation.config/routes.rb: public API routes.db/migrate: migrations.db/schema.rb: schema snapshot.lib/tasks: custom Rake tasks.spec: RSpec tests.
Before changing behavior, inspect the matching route, controller, model, service, representation, and spec.
Ruby style
- Prefer precise, minimal changes.
- Use single quotes unless interpolation or escaping makes double quotes better.
- Do not put a space before Ruby method-call parentheses.
- Do not use
%wor%iin new Ruby code. - Keep comments short and useful; avoid narrating obvious code.
- Do not add production dependencies without approval.
Authentication and authorization
- Authentication is handled through the
X-Transfer-Codeheader inApplicationController#authenticate_user. current_useris set by looking upUser.inheritance_code.- Do not bypass or weaken the
X-Transfer-Codeflow unless the task explicitly changes authentication. - Unauthenticated write actions should return
:unauthorizedconsistently with existing controllers. - Role checks use
Userenum roles:guest,member, andadmin. - Use
current_user.gte_member?for member-or-admin write permissions where existing controllers do so. - Use
current_user.admin?only for admin-only paths, such as tag child relationship changes. - Do not replace role checks with looser presence checks.
BAN and IP BAN
ApplicationControllerruns these before actions in order:reject_banned_ip_address!authenticate_userreject_banned_user!
- User and IP bans use
banned_at, not a booleanbannedcolumn. User#banned?andIpAddress#banned?checkbanned_at.present?.- Do not weaken BAN or IP BAN behavior.
- If changing request authentication or controller before actions, add or update request specs covering banned users and banned IP addresses.
RSpec
- Prefer RSpec for new backend tests.
- Put API behavior coverage under
spec/requests. - Put model behavior under
spec/models. - Put service behavior under
spec/services. - Put Rake task coverage under
spec/tasks. spec/rails_helper.rbloadsspec/support/**/*.rb.- Request specs include
AuthHelperandJsonHelper. AuthHelper#sign_in_as(user)stubsApplicationController#current_user; use it when matching existing request spec style.- Add or update request specs for API behavior changes, especially status codes, permissions, response shape, and version conflict behavior.
Migrations
- Keep migrations and
db/schema.rbconsistent. - Use reversible migrations where practical; otherwise define explicit
upanddown. - For data backfills inside migrations, follow the existing pattern of defining migration-local
ActiveRecord::Baseclasses withself.table_name. - Preserve existing indexes, foreign keys, check constraints, and null constraints.
- Be careful with MySQL-specific options already present in migrations, such as
after:. - Do not edit old migrations just to change current behavior unless explicitly requested; add a new migration.
Version tables
- Versioned records include posts, tags, nico tags, and wiki pages.
- Current records have
version_no; version tables have positiveversion_nowith unique indexes scoped to the parent record. - Version event types are
create,update,discard, andrestore. - Version rows are readonly through the
VersionRecordconcern. - Use the existing recorder services instead of manually inserting version rows in application code:
PostVersionRecorderTagVersionRecorderNicoTagVersionRecorderWikiVersionRecorderTagVersioning
VersionRecorderlocks the current record, validates sequence consistency, skips unchanged update snapshots, creates the next version row, and updates the recordversion_no.- Do not update versioned records without considering whether a version snapshot must be created.
- For optimistic concurrency paths, preserve
base_version_no,force, andmergesemantics and cover conflicts in request specs.
Domain cautions
- Posts have tag snapshots, parent post implications, original-created ranges, viewed state, and version conflict behavior.
- Tags have canonical names, aliases through
TagName, categories, parent implications, discard behavior, and version snapshots. - Nico tags have separate relation/version behavior; do not treat them like normal editable tags without checking existing code.
- Wiki pages involve page content, revisions/history, version rows, title/tag-name behavior, and diff/restore paths.
- Materials, theatres, and comments have user and permission checks; inspect the controller before changing them.
API responses
- Use representation classes under
app/representationswhen existing endpoints do. - Keep response keys consistent with existing JSON contracts; frontend code expects camelCase conversion client-side, while Rails params and JSON keys are generally snake_case.
- Preserve existing HTTP status conventions:
:unauthorizedfor no user,:forbiddenfor insufficient role or banned user,:not_foundfor missing records, and:unprocessable_entityfor validation failures.
Files to avoid in routine work
- Do not inspect or edit
tmp/,log/,storage/,vendor/, or dependency directories unless explicitly needed. - Do not modify generated schema or migration output without the corresponding migration when schema changes are made.