このコミットが含まれているのは:
2026-07-15 22:26:58 +09:00
コミット 07ce19e32d
8個のファイルの変更784行の追加264行の削除
+232 -13
ファイルの表示
@@ -110,19 +110,7 @@ pass or the remaining failure is clearly blocked.
## Dialogues
- Feature code must use `@/lib/dialogues/useDialogue` as the entrypoint for
dialogue work.
- Reuse the existing common dialogue API and common dialogue component.
- Do not import `@/components/ui/dialog` directly in feature code to build a
bespoke 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.
- Reuse the common confirmation flow from `useDialogue` instead of building a
feature-local confirmation dialogue.
- 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.
- Dialogue work follows the shared-frontend reuse rules below.
## Imports and aliases
@@ -339,6 +327,237 @@ const rows =
`BehaviorSettingsSection.tsx`.
- Avoid reformatting unrelated JSX.
## Shared frontend systems
Before creating a new component, hook, helper, store, context, or other
frontend abstraction, search at least:
- `src/components/common`
- `src/components/layout`
- `src/components/ui`
- `src/components/dialogues`
- `src/lib`
- `src/lib/dialogues`
- `src/stores`
- `src/types.ts`
Also inspect the existing pages and components in the same feature.
Search by responsibility, not by filename alone. Check display, interaction,
state, communication, validation, and permission behaviour before deciding that
an existing implementation is unsuitable.
### Component placement and reuse order
When adding UI, use this order:
1. reuse an existing feature component
2. reuse an existing component from `components/common`
3. reuse an existing layout component from `components/layout`
4. use an existing primitive from `components/ui` through the established
common API
5. extend an existing component minimally
6. add a feature-local component in the feature area
7. add a new common component only when multiple features clearly share a
stable visual contract
Do not place a one-screen component in a common directory merely because its
name starts with `Common`.
### Low-level primitives
Treat `components/ui` as low-level primitives. If a higher-level common API
already exists for dialogues, toast, form validation, navigation, or similar
behaviour, feature code must use that API instead of assembling primitives
directly.
Examples of existing preferred entrypoints include:
- dialogue: `@/lib/dialogues/useDialogue`
- toast: the existing toast API
- internal navigation: `PrefetchLink`
- form errors: `FieldError`, `FieldWarning`, `FormField`
- buttons: `Button`
- conditional class merge: `cn`
Do not evade the rule with aliases or thin wrappers around the low-level
primitive.
### Dialogues
Feature-facing dialogue work must use `@/lib/dialogues/useDialogue`.
Reuse the existing common dialogue API and common dialogue component. Do not
import `@/components/ui/dialog` directly in feature code to assemble bespoke
dialogue shells, and do not evade this rule with aliases such as
`Dialog as Dialogue`.
Do not reimplement overlay, portal, close button, header, footer, focus
handling, Escape handling, outside-click handling, or confirmation flow in
feature code.
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
exact third-party spellings only at the external boundary where compatibility
requires them.
### API calls
Rails API calls must use `src/lib/api.ts`.
Do not create feature-local Axios instances, fetch wrappers, header injectors,
camelCase converters, or generic error converters. If blob or other special
transport behaviour is already supported by the common API, use the existing
options instead of bypassing the wrapper.
### Query keys, server state, and prefetch
Before adding query state, inspect:
- `src/lib/queryKeys.ts`
- existing domain helpers
- existing prefetchers
- the root query-key hierarchy
- current mutation invalidation patterns
- the app-wide `QueryClient`
Do not write ad hoc query-key arrays in feature code. Do not duplicate fetcher,
prefetcher, or invalidation helpers for the same resource.
### Domain helpers
For posts, tags, wiki, materials, and other domain work, inspect the existing
helpers in `src/lib/*.ts` before adding logic to a page component.
Do not accumulate these in page components when an existing helper layer should
own them:
- API request construction
- response-shape conversion
- query-key construction
- canonical URL generation
- permission calculation
- storage serialisation
- domain-specific parsing
Keep purely local one-screen display shaping local when that is the clearest
place for it.
### Permission helpers
Use the existing permission helpers such as `src/lib/users.ts` when deciding
editability, role checks, admin/member visibility, and similar UI behaviour.
Do not scatter `user?.role`, numeric role comparisons, or string comparisons
through components. Frontend visibility control should be consistent even though
backend authorization remains the final gate.
### Validation errors
Before adding feature-local validation-error handling, inspect:
- `useValidationErrors`
- `apiErrors`
- `FieldError`
- `FieldWarning`
- `FormField`
- `inputClass`
Do not create a new generic hook, field-error state shape, or error-rendering
component for a pattern the shared error stack already covers. Keep only
genuinely feature-specific business errors local.
### Forms and fields
Before creating a new input, textarea, date/time field, tag input, label, or
error layout, inspect at least:
- `Form`
- `FormField`
- `FieldError`
- `FieldWarning`
- `DateTimeField`
- `TagInput`
- `TextArea`
- `Label`
- `Button`
Do not create a same-function field component merely because the spacing or
surface styling is slightly different. Prefer feature-level composition over
bloated common-field option lists.
### Navigation and prefetch
Use `PrefetchLink` and existing router helpers for internal navigation. Do not
introduce feature-local `<a>`, `window.location`, or custom prefetch logic for
internal routes. Keep path-segment encoding aligned with the existing rules.
### State management
Before adding state, decide whether the source of truth should be:
- component-local state
- URL search params
- TanStack Query server state
- an existing Zustand store
- an existing event bus
- an existing storage helper
Do not create a new global store, context, or event bus for one screen when
local state or an existing mechanism is enough. Do not create a second store
for the same responsibility.
### Storage and settings
When touching localStorage, sessionStorage, or user settings, inspect existing
settings helpers, storage helpers, expiry handling, versioning, and sanitisers.
Do not reimplement per-component key naming, JSON parsing and serialisation,
expiry, or schema checks when a shared helper already owns the pattern.
### Hooks
Before creating a custom hook, search existing `src/lib/use*.ts` and
`src/lib/use*.tsx`.
Hooks are for shared stateful behaviour or React lifecycle integration. Do not
turn a pure function, one-off helper, or mere re-export shim into `useFoo`.
### Stores, contexts, and event buses
Add a new store, context, or event bus only when the current mechanisms cannot
express the requirement and there are multiple genuinely separate consumers.
Do not hold the same information redundantly across URL state, query cache,
local component state, Zustand, and an event bus. Keep one source of truth.
### Types
If a domain type already exists in `src/types.ts` or a domain helper, reuse it
instead of redefining the same shape in a feature file.
Small local props and draft types may stay local. Do not create giant
catch-all type files such as `CommonTypes.ts`.
### Styling utilities
Use existing styling utilities such as `cn` and `inputClass`.
Do not add feature-local class-merge helpers, generic status-colour mappers, or
responsive wrapper helpers when a shared utility already exists. Keep common
tone names visual only; feature-specific state names stay in feature code.
### Layout
Before adding page shells, padding rules, viewport-height handling, sidebar
offsets, or footer offsets, inspect existing layout components such as
`MainArea`, top navigation, sidebar, page title, and section-title patterns.
Do not create a second layout shell before checking whether the current layout
can be reused or minimally extended.
### Delimiter decision table
Use this table before accepting any edited TypeScript or TSX hunk. The table is