Reviewed-on: #413 Co-authored-by: miteruzo <miteruzo@naver.com> Co-committed-by: miteruzo <miteruzo@naver.com>
このコミットはPull リクエスト #413 でマージされました.
このコミットが含まれているのは:
@@ -114,28 +114,242 @@ npm run preview
|
||||
- Ruby: `render` 系メソッド呼び出しでは、keyword 引数付きでも括弧を書かない。
|
||||
- Ruby: never put a line break immediately before `)`.
|
||||
- Ruby: do not use `%w` or `%i`.
|
||||
- Ruby: TypeScript / TSX の associative syntax に近い感覚で読むこと。
|
||||
Hash の `}` は block の `}` ではない。call の `)` も function 定義の
|
||||
parameter-list `)` ではない。delimiter の役割を見誤らないこと。
|
||||
- In Ruby, when an `if` condition is split across multiple lines and combines
|
||||
clauses with `&&` or `||`, wrap the whole condition in parentheses.
|
||||
- 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.
|
||||
- Short Ruby hashes may stay visually compact across two lines with the first
|
||||
pair kept on the opening line and aligned continuation pairs below it.
|
||||
- Ruby blocks use separate `{ ... }` rules from hashes, with 2-space body
|
||||
indentation.
|
||||
- Ruby hash / block / call delimiter の詳細は、下の
|
||||
`Ruby delimiter and wrapping rules` を正本として扱ふこと。
|
||||
- For arrays, never put whitespace or a line break immediately before `]`.
|
||||
- Keep the first element on the same line as `[` by default.
|
||||
- If an array would exceed the line limit, break after `[` and indent
|
||||
elements by 4 spaces.
|
||||
elements 4 spaces deeper than the statement's base indentation.
|
||||
|
||||
### Ruby delimiter and wrapping rules
|
||||
|
||||
- Ruby でも、closing delimiter は glyph ではなく syntax role で判定する。
|
||||
`}` が block close なのか hash close なのか、`)` が method call なのか
|
||||
grouping なのかを区別してから配置すること。
|
||||
- Ruby の multi-line method call では、receiver / method と opening `(` を
|
||||
同じ行に保ち、closing `)` を単独行へ落とさない。
|
||||
- Ruby の multi-line hash literal / keyword-like argument hash では、opening
|
||||
`{` を最初の pair と同じ行に置き、closing `}` を最後の pair と同じ行に
|
||||
置く。Prettier 的な縦開き・縦閉じをしない。
|
||||
- Ruby の guard 条件は、1 行で収まるなら modifier 形式を優先する。
|
||||
99 文字を超えるなら block 形式へ切り替へるか、message 定数化などで縮める。
|
||||
- Ruby の method chain や call argument を折り返す際、call-site の `)` を
|
||||
block close のやうに独立させない。
|
||||
- Ruby では、行末の `\` を用途を問はず一切使用しない。
|
||||
- Ruby では、文字列連結、logger message、method call、条件式、SQL 断片、
|
||||
正規表現その他すべての式で、行末バックスラッシュによる継続を禁止する。
|
||||
- Ruby の block body は、その基準位置から 2 空白深くする。
|
||||
- Ruby の wrapped expression、method argument、array element、hash pair などの
|
||||
continuation indentation は、その statement の基準位置から 4 空白深くする。
|
||||
- Ruby の continuation indentation を、行頭からの絶対空白数として扱はない。
|
||||
- Ruby では、暗黙的に継続可能な構文を優先し、method call、array、Hash 及び
|
||||
括弧内ではバックスラッシュなしで改行する。
|
||||
- Ruby では、行長制限を守るために行末バックスラッシュを導入してはならない。
|
||||
- Ruby で行末バックスラッシュが必要に見える場合は、括弧内で自然に改行する、
|
||||
一つの文字列補間へまとめる、中間変数へ分ける、`format` を使ふ、heredoc を
|
||||
使ふ、array 又は Hash を組み立ててから処理する、条件式全体を括弧で囲む、
|
||||
method へ抽出する、のいづれかへ書き換へる。
|
||||
- Ruby では、一つの文字列を、改行をまたいだ隣接文字列 literal として記述しない。
|
||||
- Ruby では、method argument 内でも、複数の文字列 literal を区切りなしで縦に
|
||||
並べない。
|
||||
- RSpec の `describe`、`context`、`it` 等の description が長い場合は、意味を
|
||||
保ったまま一行へ収まる文言へ短縮する。
|
||||
- 文字列を短縮できない場合は、用途に応じて `format`、heredoc 又は中間変数を
|
||||
検討する。
|
||||
- ただし RSpec description では、原則として簡潔な一行の文字列を使ふ。
|
||||
- formatter 又は自動修正にも、Ruby の行末バックスラッシュを生成させない。
|
||||
- 新規 code だけでなく、今回触れる Ruby code にも行末バックスラッシュを残さない。
|
||||
- 例へば class body 内の array は、class body の 2 空白を基準に、更に 4 空白
|
||||
深くするため、結果として行頭から 6 空白になる。
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
response = Example.fetch(
|
||||
value,
|
||||
option: option,
|
||||
)
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```rb
|
||||
response = Example.fetch(
|
||||
value,
|
||||
option: option)
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
payload = {
|
||||
title: title,
|
||||
url: url,
|
||||
}
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```rb
|
||||
payload = {
|
||||
title: title,
|
||||
url: url }
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
raise ArgumentError, 'URL が長すぎます.' if url.bytesize > MAX_URL_BYTES && flag.present?
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```rb
|
||||
if url.bytesize > MAX_URL_BYTES && flag.present?
|
||||
raise ArgumentError, 'URL が長すぎます.'
|
||||
end
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
Rails.logger.info(
|
||||
"post_import_metadata_fetch_failure "\
|
||||
"#{ payload.to_json }")
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```rb
|
||||
payload = {
|
||||
error: e.class.name,
|
||||
message: e.message }
|
||||
|
||||
Rails.logger.info(
|
||||
"post_import_metadata_fetch_failure #{ payload.to_json }")
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
message = "first "\
|
||||
"second"
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```rb
|
||||
message = format(
|
||||
'%<first>s %<second>s',
|
||||
first: 'first',
|
||||
second: 'second')
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
result = first_value + \
|
||||
second_value
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
it(
|
||||
'returns 409 when stale changes '
|
||||
'do not conflict'
|
||||
) do
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```rb
|
||||
it 'returns mergeable 409 for stale non-conflicting changes' do
|
||||
```
|
||||
|
||||
Bad:
|
||||
|
||||
```rb
|
||||
records.each {
|
||||
do_work(_1) }
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```rb
|
||||
records.each {
|
||||
do_work(_1)
|
||||
}
|
||||
```
|
||||
- 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.
|
||||
- In TypeScript and TSX, use 2-space block indentation.
|
||||
- In TypeScript and TSX, block bodies for components, functions, callbacks,
|
||||
`if`, `try`, `catch`, `finally`, loops, and JSX nesting use 2 spaces per
|
||||
level.
|
||||
- In TypeScript and TSX, put the opening brace of `try`, `catch`, and
|
||||
`finally` blocks on the next line at the same indentation as the keyword.
|
||||
- Do not indent the opening `{` one level deeper than `try`, `catch`, or
|
||||
`finally`.
|
||||
- Indent the block body 2 spaces deeper than the keyword and opening brace.
|
||||
- Put the closing `}` on its own line at the same indentation as the keyword.
|
||||
- Do not write `try {`, `catch {`, or `finally {`.
|
||||
- In TypeScript and TSX, use 4-space continuation indentation for wrapped
|
||||
expressions, arguments, conditions, arrays, object literals, JSX
|
||||
attributes, and similar continuations.
|
||||
- Treat the user's `PostImportSourcePage.tsx` and `PostImportReviewPage.tsx`
|
||||
formatting as the local reference shape: component and callback bodies use
|
||||
2-space block indentation, single-line bodies do not gain unnecessary
|
||||
braces, wrapped expressions use 4-space continuation indentation, multi-
|
||||
stage ternaries use explicit parentheses, and TypeScript / TSX indentation
|
||||
and alignment whitespace compress every complete run of 8 spaces to tabs.
|
||||
- A tab does not represent one indentation level.
|
||||
- In TypeScript and TSX, first determine visible indentation using 2-space
|
||||
block indentation and 4-space continuation indentation, then compress every
|
||||
complete run of 8 spaces used for indentation or column alignment to tabs.
|
||||
- In TypeScript and TSX, 8-space compression is mandatory, not optional.
|
||||
- In TypeScript and TSX, this applies both to leading indentation and to
|
||||
alignment whitespace after non-space text, such as aligned inline type
|
||||
columns.
|
||||
- In TypeScript and TSX, keep residual 2, 4, or 6 spaces after each tab
|
||||
compression.
|
||||
- In TypeScript and TSX, do not treat a tab as one logical indentation level.
|
||||
- In TypeScript and TSX, do not alter string literals, template-literal
|
||||
contents, regular expressions, or user-facing text merely to apply tab
|
||||
compression.
|
||||
- Examples: 2 columns = 2 spaces, 4 columns = 4 spaces, 6 columns = 6
|
||||
spaces, 8 columns = 1 tab, 10 columns = 1 tab + 2 spaces, 12 columns = 1
|
||||
tab + 4 spaces, 14 columns = 1 tab + 6 spaces, 16 columns = 2 tabs.
|
||||
- When TypeScript or TSX code already uses column alignment, apply the same
|
||||
8-space compression rule to that alignment whitespace.
|
||||
- Example:
|
||||
|
||||
```ts
|
||||
type Props = {
|
||||
row: PostImportRow
|
||||
displayNumber?: number
|
||||
onEdit?: () => void
|
||||
onRetry?: () => void
|
||||
onToggleSkip?: (checked: boolean) => void }
|
||||
```
|
||||
- TypeScript and TSX imports may stay on one line if they remain within the
|
||||
line limit; do not expand short type-only imports mechanically.
|
||||
- Keep runtime value imports and type imports in separate declarations.
|
||||
- Do not write `import { value, type TypeName } from ...`.
|
||||
- Type-only declarations must use `import type`.
|
||||
- Do not merge type imports into value imports merely to save lines.
|
||||
- In TypeScript and TSX, order imports as four groups with a blank line
|
||||
between groups: external value imports, `@/...` value imports, external
|
||||
type imports, `@/...` type imports.
|
||||
- Do not mechanically split a short value import from one module across
|
||||
multiple lines when it still fits within 99 characters.
|
||||
- In TypeScript and TSX, when breaking a line at an operator, break before the
|
||||
operator and put the operator at the beginning of the next line. A trailing
|
||||
operator at end of line is unacceptable. This rule does not apply to Ruby,
|
||||
@@ -167,6 +381,17 @@ case 'no':
|
||||
- In TypeScript and TSX, use `value == null` and `value != null` as the
|
||||
default nullish checks. Do not use `=== null`, `=== undefined`,
|
||||
`!== null`, or `!== undefined`.
|
||||
- In JavaScript, JSX, TypeScript, and TSX, never use `_1`, `_2`, or similar
|
||||
Ruby-style numbered parameter names. Reserve numbered parameters for Ruby.
|
||||
Use a meaningful callback parameter name such as `row`, `item`, `value`,
|
||||
`entry`, or `result`.
|
||||
- In JavaScript, JSX, TypeScript, and TSX, use `cn` from `@/lib/utils`
|
||||
whenever `className` combines multiple values, conditional classes, or a
|
||||
caller-provided `className` prop.
|
||||
- Do not construct `className` with template literals, `${ ... }`, string
|
||||
concatenation, arrays joined with spaces, or feature-local class-merging
|
||||
helpers.
|
||||
- A static `className="..."` containing only fixed classes does not need `cn`.
|
||||
- If code appears to need a distinction between `null` and `undefined`, treat
|
||||
that as a design smell and revise the logic to avoid the distinction.
|
||||
External library APIs that explicitly require distinguishing the two are the
|
||||
@@ -190,6 +415,151 @@ const value =
|
||||
value selection. Do not replace a clear ternary with `if` statements, and do
|
||||
not introduce immediately invoked functions just to avoid or reformat a
|
||||
ternary expression.
|
||||
- In TypeScript and TSX, multi-stage ternary expressions must make branch
|
||||
boundaries explicit. Wrap each condition group in parentheses instead of
|
||||
relying on indentation alone to show which `?` matches which `:`.
|
||||
- In TypeScript and TSX, wrap nested ternary expressions in parentheses. Do
|
||||
not write flat vertical chains of `?` and `:` without explicit grouping.
|
||||
- In TypeScript and TSX, when a ternary condition contains `&&` or `||`, wrap
|
||||
the whole condition in parentheses before `?`.
|
||||
- In TypeScript and TSX, if a ternary reaches three or more stages and still
|
||||
reads poorly after explicit grouping, extract a helper function or use `if`
|
||||
statements instead of keeping a flat multi-stage ternary.
|
||||
|
||||
Bad:
|
||||
|
||||
```ts
|
||||
row.skipReason === 'existing' || row.importStatus === 'skipped'
|
||||
? 'skipped'
|
||||
: Object.keys (row.validationErrors ?? { }).length > 0
|
||||
|| row.importStatus === 'failed'
|
||||
|| row.importStatus === 'created'
|
||||
? null
|
||||
: hasWarnings (row) || row.status === 'warning'
|
||||
? 'warning'
|
||||
: 'ready'
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```ts
|
||||
(row.skipReason === 'existing' || row.importStatus === 'skipped')
|
||||
? 'skipped'
|
||||
: ((Object.keys (row.validationErrors ?? { }).length > 0
|
||||
|| row.importStatus === 'failed'
|
||||
|| row.importStatus === 'created')
|
||||
? null
|
||||
: ((hasWarnings (row) || row.status === 'warning')
|
||||
? 'warning'
|
||||
: 'ready'))
|
||||
```
|
||||
|
||||
## Shared-system discovery and reuse
|
||||
|
||||
Before creating a new component, hook, service, helper, utility, concern,
|
||||
representation, normaliser, validator, parser, fetcher, store, context, event
|
||||
bus, API client, query key, permission helper, dialogue, toast, form field, or
|
||||
version recorder, search the existing repository first.
|
||||
|
||||
Do not search by name alone. Search by responsibility, behaviour, and usage
|
||||
intent as well. Typical search themes include:
|
||||
|
||||
- dialogue, modal, confirm, alert, choice
|
||||
- validation error, field error, unprocessable entity
|
||||
- permission, role, member, admin, editable
|
||||
- URL normalise, sanitise, canonicalise
|
||||
- API call, query key, prefetch, cache invalidation
|
||||
- version, snapshot, history, restore
|
||||
- thumbnail, metadata, HTTP fetch, URL safety
|
||||
- form, field, input, textarea, warning, status badge
|
||||
- file storage, Active Storage, ZIP, export
|
||||
- transaction, locking, race, idempotency
|
||||
|
||||
Before deciding that something new is needed, confirm at least:
|
||||
|
||||
1. the existing definition
|
||||
2. its public API
|
||||
3. representative call sites
|
||||
4. other implementations with similar responsibility
|
||||
5. the nearest directory-level `AGENTS.md`
|
||||
|
||||
Do not reject an existing implementation by name alone. Read the code and its
|
||||
usage first.
|
||||
|
||||
When new behaviour is needed, make the decision in this order:
|
||||
|
||||
1. use the existing common API as-is
|
||||
2. use the existing extension points of that API
|
||||
3. extend the existing common API minimally
|
||||
4. keep the implementation local when the meaning is feature-specific
|
||||
5. add a new common system only when multiple real users and a stable contract
|
||||
are already clear
|
||||
|
||||
Do not create a parallel foundation merely because the existing one feels
|
||||
slightly awkward, because a new one seems faster, or because the current task
|
||||
looks special.
|
||||
|
||||
Do not create a second common platform with names such as `CommonFoo`,
|
||||
`SharedFoo`, `BaseFoo`, `FooManager`, `FooService`, `FooProvider`,
|
||||
`FooWrapper`, `FooUtils`, or `useFoo` when an existing system already owns the
|
||||
same responsibility. Judge by responsibility, not by spelling.
|
||||
|
||||
Wrapper aliases, barrel exports, and re-export shims do not count as reuse.
|
||||
Using a different import path that merely forwards to the existing system does
|
||||
not satisfy a reuse requirement.
|
||||
|
||||
Keep this boundary explicit:
|
||||
|
||||
- business meaning stays in feature code
|
||||
- visual and mechanical shell stays in common code
|
||||
|
||||
Common code may hold generic primitives, interaction shells, API transport,
|
||||
auth and permission helpers, query-key and prefetch conventions, validation
|
||||
error conversion, shared normalisation, version-recording mechanisms, storage
|
||||
helpers, HTTP safety, and other contracts that carry the same meaning across
|
||||
multiple features.
|
||||
|
||||
Feature code should keep feature-specific states, labels, input fields,
|
||||
workflow steps, payload shapes, validation rules, and business decisions.
|
||||
|
||||
Do not commonise business logic merely because the visuals look similar or two
|
||||
code fragments resemble each other.
|
||||
|
||||
Create a new common system only when all of the following are true:
|
||||
|
||||
- no existing implementation already owns the responsibility
|
||||
- there are multiple real consumers, or a clearly defined platform contract
|
||||
- the differences between consumers do not require option bloat
|
||||
- feature-specific vocabulary does not leak into common types, props, tones, or
|
||||
state names
|
||||
- the location matches the existing directory structure
|
||||
- the new abstraction does not compete with an existing common system
|
||||
- it is not just a one-off wrapper for a single task
|
||||
|
||||
Do not add unused tones, variants, options, callbacks, states, or abstractions
|
||||
for speculative future use.
|
||||
|
||||
Before finishing work that touches shared systems, verify:
|
||||
|
||||
- you searched for an existing implementation with the same responsibility
|
||||
- you are using the canonical import path or entrypoint
|
||||
- feature code is not reaching directly for a low-level primitive that already
|
||||
has a higher-level common API
|
||||
- you did not bypass an existing common API
|
||||
- any new wrapper or shim is genuinely necessary
|
||||
- feature-specific vocabulary did not leak into common code
|
||||
- the feature did not reimplement a common shell
|
||||
- existing unrelated consumers were not changed without need
|
||||
- one task did not trigger a needless redesign of the whole foundation
|
||||
- any newly introduced common system really has multiple consumers
|
||||
|
||||
For backend-specific discovery, Rails structure, services, representation
|
||||
selection, versioning, normalisation, and HTTP safety, follow
|
||||
`backend/AGENTS.md`.
|
||||
|
||||
For frontend-specific component hierarchy, low-level primitive reuse, dialogue
|
||||
entrypoints, API/query helpers, validation/form infrastructure, state/storage,
|
||||
and layout reuse, follow `frontend/AGENTS.md`.
|
||||
- In TypeScript and TSX, do not write `let` followed by later `if` assignments
|
||||
when the value can be expressed as a single `const` initializer. Prefer
|
||||
`const` because it prevents accidental later reassignment.
|
||||
@@ -197,9 +567,39 @@ const value =
|
||||
structure, control flow, or variable mutability unless the requested style
|
||||
explicitly requires it.
|
||||
- Do not add production dependencies without explicit approval.
|
||||
- Do not add user-facing copy, helper text, descriptions, notes, tooltips,
|
||||
placeholders, empty-state messages, loading messages, or explanatory text
|
||||
unless the user explicitly specified the wording.
|
||||
- When new user-facing wording appears necessary, ask the user for the exact
|
||||
wording and placement before implementing it.
|
||||
- Do not invent replacement copy when removing unrequested wording.
|
||||
- Do not create, modify, or run tests unless the user explicitly asks for
|
||||
test work. When the user asks for tests, keep working and rerun them until
|
||||
they pass or the remaining failure is clearly blocked.
|
||||
test work. When the user asks for tests, keep working within the permitted
|
||||
test-file scope and rerun them until they pass or the remaining failure is
|
||||
clearly blocked.
|
||||
- Test-only work includes adding, updating, deleting, reorganising, or fixing
|
||||
SyntaxError in tests. During test-only work, do not modify production code.
|
||||
- During test-only work, do not change production constants, behaviour, API
|
||||
contracts, validation, routes, authentication, permissions, UI, copy,
|
||||
dependencies, limits, thresholds, defaults, migrations, schema, or
|
||||
environment settings to satisfy tests.
|
||||
- Do not make production code match failing tests, mock assumptions, fixtures,
|
||||
snapshots, old expectations, or stale setup. This includes changing
|
||||
production constants merely because a test expects a different value.
|
||||
- If test work reveals a production bug, spec mismatch, or missing behaviour,
|
||||
stop without modifying production code and report: the failing test or
|
||||
discovered issue, the related production file, the actual behaviour, the
|
||||
expected behaviour, and why a production change appears necessary.
|
||||
- Modify production code for test failures only when the user explicitly asks
|
||||
for that production change. Do not expand a test task into a production task
|
||||
on your own authority.
|
||||
- If the user explicitly asks for both production implementation and test
|
||||
updates, implement production code to the confirmed specification first,
|
||||
then add or update tests to verify that specification. Never roll production
|
||||
behaviour back to satisfy old tests.
|
||||
- If it is unclear whether the test or the production implementation is stale,
|
||||
or a test cannot be corrected without changing production code, ask the user
|
||||
instead of guessing.
|
||||
|
||||
## Backend rules
|
||||
|
||||
@@ -253,6 +653,11 @@ const value =
|
||||
- Mobile UI must be checked as a first-class layout. Avoid wide fixed content,
|
||||
make dense controls wrap or scroll intentionally, and keep tag/filter
|
||||
controls usable without horizontal page overflow.
|
||||
- Frontend のスマホ/PC表示境界は原則 `md` とする。
|
||||
- button stack、footer action、dialogue action は `md` 未満で縦並び、
|
||||
`md` 以上で横並びとする。
|
||||
- 同じ画面内で `sm` と `md` を混在させて中間 layout を作らない。
|
||||
- 明確に別の responsive 要件がある component だけを例外とする。
|
||||
- For mobile horizontal scrollers, make the scroll direction and item sizing
|
||||
explicit, and ensure chip text remains readable in both light and dark modes.
|
||||
- In TypeScript and TSX, prefer direct comparison operators such as `===` and
|
||||
@@ -265,6 +670,20 @@ const value =
|
||||
- For user-facing Japanese kanji spelling, do not normalize to
|
||||
《当用漢字による書きかえ》; prefer original forms such as `編輯`.
|
||||
- For user-facing Japanese ellipses, prefer `……` over ASCII `...`.
|
||||
- Frontend dialogue work must use `@/lib/dialogues/useDialogue` as the
|
||||
feature-facing entrypoint.
|
||||
- Reuse the existing common dialogue API and common dialogue component
|
||||
instead of building feature-local overlay, close button, header, footer,
|
||||
focus handling, outside click handling, Escape handling, or confirmation
|
||||
flows.
|
||||
- Do not import `@/components/ui/dialog` directly in feature code to build a
|
||||
one-off dialogue, and do not evade this rule with aliases such as
|
||||
`Dialog as Dialogue`.
|
||||
- Keep business-specific form content in feature code, and keep the visual
|
||||
and behavioural dialogue shell in common code.
|
||||
- Use British spelling `Dialogue` for project-defined dialogue identifiers.
|
||||
Keep an exact third-party API spelling only at the external boundary where
|
||||
compatibility requires it.
|
||||
|
||||
### Frontend TypeScript and TSX style
|
||||
|
||||
@@ -303,15 +722,34 @@ const value =
|
||||
beginning of a line.
|
||||
- The TSX-specific self-review must confirm JSX closing markers and closing
|
||||
parentheses keep the surrounding compact style.
|
||||
- The TypeScript/TSX self-review must confirm leading indentation follows
|
||||
4-space logical indentation with tabs only as leading 8-space compression.
|
||||
- The TypeScript/TSX self-review must confirm block indentation uses 2 spaces
|
||||
per level, wrapped continuations use the repository's 4-space continuation
|
||||
alignment, and every complete run of 8 spaces used for indentation or
|
||||
alignment has been compressed to tabs.
|
||||
- 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.
|
||||
- In TypeScript and TSX, convert every leading run of 8 spaces to a tab
|
||||
character.
|
||||
- A leading tab is exactly equivalent to 8 leading spaces.
|
||||
- In TSX, use 2-space block indentation and 4-space continuation
|
||||
indentation.
|
||||
- In TypeScript and TSX, put the opening brace of `try`, `catch`, and
|
||||
`finally` blocks on the next line at the same indentation as the keyword.
|
||||
- Do not indent the opening `{` one level deeper than `try`, `catch`, or
|
||||
`finally`.
|
||||
- Indent the block body 2 spaces deeper than the keyword and opening brace.
|
||||
- Put the closing `}` on its own line at the same indentation as the keyword.
|
||||
- Do not write `try {`, `catch {`, or `finally {`.
|
||||
- In TypeScript and TSX, convert every complete run of 8 spaces used for
|
||||
indentation or alignment to a tab character.
|
||||
- In TypeScript and TSX, a tab is exactly equivalent to 8 columns, whether it
|
||||
appears at the beginning of a line or in alignment whitespace after
|
||||
non-space text.
|
||||
- In TSX, JSX nesting uses 2-space block indentation and wrapped JSX
|
||||
attributes use 4-space continuation indentation; after visible columns are
|
||||
determined, compress every complete run of 8 spaces in the resulting
|
||||
indentation or alignment to tabs.
|
||||
- In TSX, do not leave JSX subtree indentation at 8, 10, 12, 14, or 16
|
||||
columns as spaces alone; convert each complete run of 8 spaces to tabs and
|
||||
keep only the residual 2, 4, or 6 spaces.
|
||||
- In TypeScript and TSX function declarations, including `const` arrow
|
||||
function declarations, classify the parameter list before placing the closing
|
||||
`)`.
|
||||
@@ -359,6 +797,22 @@ const value =
|
||||
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.
|
||||
- `try` / `catch` / `finally` brace placement example:
|
||||
|
||||
```ts
|
||||
try
|
||||
{
|
||||
doWork ()
|
||||
}
|
||||
catch
|
||||
{
|
||||
recover ()
|
||||
}
|
||||
finally
|
||||
{
|
||||
cleanUp ()
|
||||
}
|
||||
```
|
||||
- Do not use a leading semicolon for expression statements such as
|
||||
`;([...]).forEach(...)`; rewrite the expression to avoid ASI hazards
|
||||
explicitly, for example with `void`.
|
||||
@@ -938,8 +1392,9 @@ to `.ts` and `.tsx`:
|
||||
7. JSX `>` and `/>` stay with the final prop unless nearby code proves
|
||||
otherwise.
|
||||
8. JSX closing parentheses keep the compact local style.
|
||||
9. Leading indentation is 4-space logical indentation with tabs used only as
|
||||
leading 8-space compression.
|
||||
9. Block indentation uses 2 spaces per level, wrapped continuations use the
|
||||
repository's 4-space continuation alignment, and every complete run of 8
|
||||
spaces used for indentation or alignment has been compressed to tabs.
|
||||
10. No line has trailing whitespace.
|
||||
|
||||
Preferred:
|
||||
|
||||
新しい課題から参照
ユーザをブロックする