mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-04-29 21:49:16 +08:00
When a `PUT`, `POST`, or `DELETE` operation doesn't need to return any
data, we've historically either returned nothing, or `{ success: "OK"
}`.
A more consistent way to return the same data would be with a 204 status
response. This gives the same information as the `{ success: "OK" }`
body (ie, that the operation successfully completed), without needing to
read or parse the response body.
This change adds a 204 response for `Admin::SiteSettingsController`.
Additional controllers could be migrated in follow-up PRs, or on an
ad-hoc basis.
5 KiB
5 KiB
AI Coding Agent Guide
Project-specific instructions for AI agents. MUST be loaded at conversation start.
Default Mode
- Architect mode enabled by default: detailed analysis, patterns, trade-offs, architectural guidance
- Stop and ask for context if unable to write code meeting guidelines
Development Rules
Discourse is large with long history. Understand context before changes.
All Files
- Always lint changed files
- Make display strings translatable (use placeholders, not split strings)
- Create subagent to review changes against this file after completing tasks
Toolset
- Use
pnpmfor JavaScript,bundlefor Ruby - Use helpers in bin over bundle exec (bin/rspec, bin/rake)
JavaScript
- No empty backing classes for template-only components unless requested
- Use FormKit for forms: https://meta.discourse.org/t/discourse-toolkit-to-render-forms/326439 (
app/assets/javascripts/discourse/app/form-kit)
JSDoc
- Required for classes, methods, members (except
@servicemembers, constructors) - Multiline format only
- Components:
@componentname, list params (this.argsor@paramname) - Methods: no
@returnsfor@action, use@returnsfor getters (not@type) - Members: specify
@type
Testing
- Do not write unnecessary comments in tests, every single assertion doesn't need a comment
- Don't test functionality handled by other classes/components
- Don't write obvious tests
- Ruby: use
fab!()overlet(), system tests for UI (spec/system), use page objects for system spec finders (spec/system/page_objects)
Page Objects (System Specs)
- Located in
spec/system/page_objects/pages/, inherit fromPageObjects::Pages::Base - NEVER store
find()results - causes stale element references after re-renders - Use
has_x?/has_no_x?patterns for state checks (finds fresh each time) - Action methods find+interact atomically, return
selffor chaining - Don't assert immediate UI feedback after clicks (tests browser, not app logic)
Commands
# Ruby tests
bin/rspec [spec/path/file_spec.rb[:123]]
LOAD_PLUGINS=1 bin/rspec # Plugin tests
# JavaScript tests
bin/rake qunit:test # RUN all non plugin tests
LOAD_PLUGINS=1 TARGET=all FILTER='fill filter here' bin/rake qunit:test # RUN specific tests based on filter
Exmaple filters JavaScript tests:
emoji-test.js
...
acceptance("Emoji" ..
test("cooked correctly")
...
Filter string is: "Acceptance: Emoji: cooked correctly"
user-test.js
...
module("Unit | Model | user" ..
test("staff")
...
Filter string is: "Unit | Model | user: staff"
# Linting
bin/lint path/to/file path/to/another/file
bin/lint --fix path/to/file path/to/another/file
bin/lint --fix --recent # Lint all recently changed files
ALWAYS lint any changes you make
Site Settings
- Configured in
config/site_settings.ymlorconfig/settings.ymlfor plugins - Functionality in
lib/site_setting_extension.rb - Access:
SiteSetting.setting_name(Ruby),siteSettings.setting_name(JS with@service siteSettings)
Services
- Extract business logic (validation, models, permissions) from controllers
- https://meta.discourse.org/t/using-service-objects-in-discourse/333641
- Examples:
app/services(only classes withService::Base)
Database & Performance
- ActiveRecord: use
includes()/preload()(N+1),find_each()/in_batches()(large sets),update_all/delete_all(bulk),exists?overpresent? - Migrations: rollback logic,
algorithm: :concurrentlyfor large tables, deprecate before removing columns - Queries: use
explain, specify columns, strategic indexing,counter_cachefor counts
HTTP Response Codes
- 204 No Content: Use
head :no_contentfor successful operations that don't return data- DELETE operations that successfully remove a resource
- UPDATE/PUT operations that succeed but don't need to return modified data
- POST operations that perform an action without creating/returning resources (mark as read, clear notifications)
- 200 OK: Use
render json: success_jsonwhen returning confirmation data or when clients expect a response body - 201 Created: Use when creating resources, include location header or resource data
- Do NOT use 204 when:
- Creating resources (use 201 with data)
- Returning modified/useful data to the client
- Clients expect confirmation data beyond success/failure
Security
- XSS: use
{{}}(escaped) not{{{ }}}, sanitize withsanitize/cook, noinnerHTML, careful with@html - Auth: Guardian classes (
lib/guardian.rb), POST/PUT/DELETE for state changes, CSRF tokens,protect_from_forgery - Input: validate client+server, strong parameters, length limits, don't trust client-only validation
- Authorization: Guardian classes, route+action permissions, scope limiting,
can_see?/can_edit?patterns
Knowledge Sharing
- ALWAYS persist information for ALL developers (no conversational-only memory)
- Follow project conventions, prevent knowledge silos
- Recommend storage locations by info type
- Inform when this file changes and reloads