このコミットが含まれているのは:
+186
@@ -67,6 +67,192 @@ pass or the remaining failure is clearly blocked.
|
||||
Before changing behavior, inspect the matching route, controller, model,
|
||||
service, representation, and spec.
|
||||
|
||||
## Shared backend systems
|
||||
|
||||
Before adding backend behaviour, search the existing backend first. At minimum,
|
||||
check these locations:
|
||||
|
||||
- `app/controllers`
|
||||
- `app/controllers/concerns`
|
||||
- `app/models`
|
||||
- `app/models/concerns`
|
||||
- `app/representations`
|
||||
- `app/services`
|
||||
- `app/services/*`
|
||||
- `app/jobs`
|
||||
- `lib`
|
||||
- `lib/tasks`
|
||||
- `config/initializers`
|
||||
|
||||
Do not infer commonality from directory names alone. Read the actual
|
||||
responsibility and representative usage sites.
|
||||
|
||||
### Controller reuse
|
||||
|
||||
Before adding logic to a controller, inspect:
|
||||
|
||||
- `ApplicationController` authentication, authorization, BAN, and IP BAN
|
||||
- existing render and validation-error helpers
|
||||
- existing param parsing
|
||||
- controller concerns
|
||||
- the controller for the same resource
|
||||
- existing services
|
||||
- existing representations
|
||||
|
||||
Keep controllers focused on:
|
||||
|
||||
- authentication and authorization
|
||||
- parameter intake
|
||||
- service and model invocation
|
||||
- HTTP status selection
|
||||
- representation selection
|
||||
|
||||
Do not reimplement these per controller when an existing path already owns
|
||||
them:
|
||||
|
||||
- authentication and role checks
|
||||
- validation error JSON
|
||||
- URL normalisation
|
||||
- tag normalisation
|
||||
- thumbnail handling
|
||||
- version recording
|
||||
- complex transactions
|
||||
- external HTTP fetching
|
||||
- response representation assembly
|
||||
|
||||
### Authentication, authorization, and BAN
|
||||
|
||||
Treat these as the canonical backend entrypoints:
|
||||
|
||||
- `ApplicationController#authenticate_user`
|
||||
- `current_user`
|
||||
- `X-Transfer-Code`
|
||||
- `reject_banned_ip_address!`
|
||||
- `reject_banned_user!`
|
||||
- `gte_member?`
|
||||
- `admin?`
|
||||
|
||||
Do not create feature-local permission services, role comparisons, or header
|
||||
parsing when the existing authentication boundary already owns the behaviour.
|
||||
If the current boundary is insufficient, extend it minimally instead of adding
|
||||
another permission path.
|
||||
|
||||
### Representations
|
||||
|
||||
If an endpoint for the same resource already uses `app/representations`, do not
|
||||
assemble a separate JSON shape directly inside the controller without first
|
||||
checking the existing representation contract.
|
||||
|
||||
Inspect at least:
|
||||
|
||||
- `PostRepr`
|
||||
- `TagRepr`
|
||||
- `MaterialRepr`
|
||||
- `TheatreRepr`
|
||||
- `UserRepr`
|
||||
- `WikiPageRepr`
|
||||
- `DeerjikistRepr`
|
||||
|
||||
When a lightweight response is genuinely different in purpose, keep it
|
||||
deliberate and compatible with the surrounding contracts. Do not force every
|
||||
identifier list into a large representation, but do not fork the same resource
|
||||
shape casually either.
|
||||
|
||||
### Domain services
|
||||
|
||||
When work touches multiple models, transactions, external APIs, file handling,
|
||||
history creation, or multi-step workflow, search `app/services` first.
|
||||
|
||||
At minimum, search for existing services in these responsibility areas:
|
||||
|
||||
- version recorder and versioning
|
||||
- wiki commit
|
||||
- YouTube or Google Drive API client
|
||||
- material sync or ZIP export
|
||||
- similarity calculation
|
||||
- theatre selection or skip finalisation
|
||||
- metadata, thumbnail, or file processing
|
||||
- URL normaliser or sanitisation
|
||||
- import or export
|
||||
- preview safety or HTTP fetch
|
||||
|
||||
Do not create a same-responsibility service under another namespace or another
|
||||
name. If an existing service is close, extend that API minimally instead of
|
||||
wrapping it in a feature-local service.
|
||||
|
||||
### Versioning
|
||||
|
||||
When a feature writes history, snapshots, or restore roots, search the existing
|
||||
versioning path first. At minimum, inspect:
|
||||
|
||||
- `VersionRecorder`
|
||||
- `PostVersionRecorder`
|
||||
- `TagVersionRecorder`
|
||||
- `TagVersioning`
|
||||
- `MaterialVersionRecorder`
|
||||
- `NicoTagVersionRecorder`
|
||||
- `WikiVersionRecorder`
|
||||
|
||||
Do not implement history writes in controllers, callbacks, or ad hoc feature
|
||||
services when the recorder layer already owns the transaction boundary and
|
||||
meaning.
|
||||
|
||||
### Normalisation, sanitisation, and parsing
|
||||
|
||||
For URLs, tag names, times, video durations, identifiers, and paths, search the
|
||||
existing normaliser, sanitisation rule, parser, and model-callback path first.
|
||||
|
||||
Do not let frontend, controller, service, and model each invent different rules
|
||||
for the same value. Use one canonical normalisation path and keep input
|
||||
validation distinct from pre-persistence normalisation.
|
||||
|
||||
### External HTTP and URL safety
|
||||
|
||||
When fetching external URLs, reuse the existing preview-safety stack. Search at
|
||||
least for:
|
||||
|
||||
- URL safety
|
||||
- redirect validation
|
||||
- response size limits
|
||||
- timeouts
|
||||
- network failure mapping
|
||||
- HTML metadata extraction
|
||||
- known-site extraction
|
||||
- thumbnail fetching
|
||||
|
||||
Do not add direct `Net::HTTP`, `Faraday`, or equivalent feature-local HTTP code
|
||||
that reimplements SSRF checks, redirect restrictions, size limits, or timeouts.
|
||||
If the current fetcher is insufficient, extend its existing safety contract.
|
||||
|
||||
### Storage, files, and Active Storage
|
||||
|
||||
When handling files, thumbnails, ZIP output, object storage, or Active Storage
|
||||
blobs, inspect existing storage helpers, exporters, thumbnail generators, and
|
||||
checksum helpers first. Do not reimplement the same attach, export path,
|
||||
download, resize, or checksum flow in a controller or one-off service.
|
||||
|
||||
### Concerns
|
||||
|
||||
Do not create controller or model concerns merely because some code is shared.
|
||||
Use a concern only when multiple classes share the same lifecycle, macro,
|
||||
callback, or tightly cohesive behaviour. Utility collections belong in explicit
|
||||
objects or services, not in `CommonConcern`, `SharedMethods`, or `Utils`.
|
||||
|
||||
### Model boundaries
|
||||
|
||||
Model-specific invariants, associations, validations, and normalisation may
|
||||
live in the model. Multi-model workflow, external access, complex transaction
|
||||
flow, and feature orchestration belong in services. Do not hide feature
|
||||
workflow in model callbacks.
|
||||
|
||||
### Transactions, locking, and race handling
|
||||
|
||||
If transactions, locking, idempotency, or race recovery already exist in a
|
||||
service or model method, do not add a second implementation in a controller or
|
||||
new service. Inspect the existing transaction boundary first, avoid wrapping
|
||||
the same operation in needless nested transactions, and handle unique-constraint
|
||||
races according to the target constraint's business meaning.
|
||||
|
||||
## Ruby style
|
||||
|
||||
- Prefer precise, minimal changes.
|
||||
|
||||
新しい課題から参照
ユーザをブロックする