mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-05-19 23:33:07 +08:00
docs: add native Japanese translation of ECC documentation (ja-JP)
Translate everything-claude-code repository to Japanese including: - 17 root documentation files - 60 agent documentation files - 80 command documentation files - 99 rule files across 18 language directories (common, angular, arkts, cpp, csharp, dart, fsharp, golang, java, kotlin, perl, php, python, ruby, rust, swift, typescript, web) - 199 skill documentation files Total: 455 files translated to Japanese with: - Consistent terminology glossary applied throughout - YAML field names preserved in English (name, description, etc.) - Code blocks and examples untouched (comments translated) - Markdown structure and relative links preserved - Professional translation maintaining technical accuracy This translation expands ECC accessibility to Japanese-speaking developers and teams. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
86
docs/ja-JP/rules/kotlin/coding-style.md
Normal file
86
docs/ja-JP/rules/kotlin/coding-style.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.kt"
|
||||
- "**/*.kts"
|
||||
---
|
||||
# Kotlin コーディングスタイル
|
||||
|
||||
> このファイルは [common/coding-style.md](../common/coding-style.md) を Kotlin 固有のコンテンツで拡張します。
|
||||
|
||||
## フォーマット
|
||||
|
||||
- **ktlint** または **Detekt** でスタイルを強制
|
||||
- 公式 Kotlin コードスタイル(`gradle.properties` に `kotlin.code.style=official`)
|
||||
|
||||
## 不変性
|
||||
|
||||
- `var` よりも `val` を優先 — デフォルトは `val`、ミューテーションが必要な場合のみ `var` を使用
|
||||
- 値型には `data class` を使用する; public API では不変コレクション(`List`、`Map`、`Set`)を使用
|
||||
- 状態更新にはコピーオンライト: `state.copy(field = newValue)`
|
||||
|
||||
## 命名
|
||||
|
||||
Kotlin の慣例に従う:
|
||||
- `camelCase` — 関数とプロパティ
|
||||
- `PascalCase` — クラス、インターフェース、オブジェクト、型エイリアス
|
||||
- `SCREAMING_SNAKE_CASE` — 定数(`const val` または `@JvmStatic`)
|
||||
- インターフェースの接頭辞は振る舞いで付ける、`I` ではない: `Clickable` であって `IClickable` ではない
|
||||
|
||||
## Null 安全性
|
||||
|
||||
- `!!` は使用しない — `?.`、`?:`、`requireNotNull()`、または `checkNotNull()` を優先
|
||||
- スコープ付き null 安全操作には `?.let {}` を使用
|
||||
- 正当に結果がない可能性がある関数からは nullable 型を返す
|
||||
|
||||
```kotlin
|
||||
// BAD
|
||||
val name = user!!.name
|
||||
|
||||
// GOOD
|
||||
val name = user?.name ?: "Unknown"
|
||||
val name = requireNotNull(user) { "User must be set before accessing name" }.name
|
||||
```
|
||||
|
||||
## シールド型
|
||||
|
||||
閉じた状態階層のモデリングにはシールドクラス/インターフェースを使用する:
|
||||
|
||||
```kotlin
|
||||
sealed interface UiState<out T> {
|
||||
data object Loading : UiState<Nothing>
|
||||
data class Success<T>(val data: T) : UiState<T>
|
||||
data class Error(val message: String) : UiState<Nothing>
|
||||
}
|
||||
```
|
||||
|
||||
シールド型に対しては常に網羅的な `when` を使用する — `else` ブランチは使わない。
|
||||
|
||||
## 拡張関数
|
||||
|
||||
ユーティリティ操作には拡張関数を使用するが、発見しやすくする:
|
||||
- レシーバー型にちなんだファイル名にする(`StringExt.kt`、`FlowExt.kt`)
|
||||
- スコープを限定する — `Any` や過度に汎用的な型に拡張を追加しない
|
||||
|
||||
## スコープ関数
|
||||
|
||||
適切なスコープ関数を使用する:
|
||||
- `let` — null チェック + 変換: `user?.let { greet(it) }`
|
||||
- `run` — レシーバーを使って結果を計算: `service.run { fetch(config) }`
|
||||
- `apply` — オブジェクトの設定: `builder.apply { timeout = 30 }`
|
||||
- `also` — 副作用: `result.also { log(it) }`
|
||||
- スコープ関数の深いネストは避ける(最大2レベル)
|
||||
|
||||
## エラーハンドリング
|
||||
|
||||
- `Result<T>` またはカスタムシールド型を使用
|
||||
- throwable コードのラッピングには `runCatching {}` を使用
|
||||
- `CancellationException` は絶対にキャッチしない — 常に再スローする
|
||||
- 制御フローに `try-catch` を使用しない
|
||||
|
||||
```kotlin
|
||||
// BAD — 制御フローに例外を使用
|
||||
val user = try { repository.getUser(id) } catch (e: NotFoundException) { null }
|
||||
|
||||
// GOOD — nullable 戻り値
|
||||
val user: User? = repository.findUser(id)
|
||||
```
|
||||
17
docs/ja-JP/rules/kotlin/hooks.md
Normal file
17
docs/ja-JP/rules/kotlin/hooks.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.kt"
|
||||
- "**/*.kts"
|
||||
- "**/build.gradle.kts"
|
||||
---
|
||||
# Kotlin フック
|
||||
|
||||
> このファイルは [common/hooks.md](../common/hooks.md) を Kotlin 固有のコンテンツで拡張します。
|
||||
|
||||
## PostToolUse フック
|
||||
|
||||
`~/.claude/settings.json` で設定:
|
||||
|
||||
- **ktfmt/ktlint**: 編集後に `.kt` と `.kts` ファイルを自動フォーマット
|
||||
- **detekt**: Kotlin ファイル編集後に静的解析を実行
|
||||
- **./gradlew build**: 変更後にコンパイルを検証
|
||||
146
docs/ja-JP/rules/kotlin/patterns.md
Normal file
146
docs/ja-JP/rules/kotlin/patterns.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.kt"
|
||||
- "**/*.kts"
|
||||
---
|
||||
# Kotlin パターン
|
||||
|
||||
> このファイルは [common/patterns.md](../common/patterns.md) を Kotlin および Android/KMP 固有のコンテンツで拡張します。
|
||||
|
||||
## 依存性注入
|
||||
|
||||
コンストラクタインジェクションを優先する。Koin(KMP)または Hilt(Android のみ)を使用:
|
||||
|
||||
```kotlin
|
||||
// Koin — モジュール宣言
|
||||
val dataModule = module {
|
||||
single<ItemRepository> { ItemRepositoryImpl(get(), get()) }
|
||||
factory { GetItemsUseCase(get()) }
|
||||
viewModelOf(::ItemListViewModel)
|
||||
}
|
||||
|
||||
// Hilt — アノテーション
|
||||
@HiltViewModel
|
||||
class ItemListViewModel @Inject constructor(
|
||||
private val getItems: GetItemsUseCase
|
||||
) : ViewModel()
|
||||
```
|
||||
|
||||
## ViewModel パターン
|
||||
|
||||
単一の状態オブジェクト、イベントシンク、単方向データフロー:
|
||||
|
||||
```kotlin
|
||||
data class ScreenState(
|
||||
val items: List<Item> = emptyList(),
|
||||
val isLoading: Boolean = false
|
||||
)
|
||||
|
||||
class ScreenViewModel(private val useCase: GetItemsUseCase) : ViewModel() {
|
||||
private val _state = MutableStateFlow(ScreenState())
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
fun onEvent(event: ScreenEvent) {
|
||||
when (event) {
|
||||
is ScreenEvent.Load -> load()
|
||||
is ScreenEvent.Delete -> delete(event.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## リポジトリパターン
|
||||
|
||||
- `suspend` 関数は `Result<T>` またはカスタムエラー型を返す
|
||||
- リアクティブストリームには `Flow`
|
||||
- ローカルとリモートのデータソースを調整する
|
||||
|
||||
```kotlin
|
||||
interface ItemRepository {
|
||||
suspend fun getById(id: String): Result<Item>
|
||||
suspend fun getAll(): Result<List<Item>>
|
||||
fun observeAll(): Flow<List<Item>>
|
||||
}
|
||||
```
|
||||
|
||||
## UseCase パターン
|
||||
|
||||
単一責任、`operator fun invoke`:
|
||||
|
||||
```kotlin
|
||||
class GetItemUseCase(private val repository: ItemRepository) {
|
||||
suspend operator fun invoke(id: String): Result<Item> {
|
||||
return repository.getById(id)
|
||||
}
|
||||
}
|
||||
|
||||
class GetItemsUseCase(private val repository: ItemRepository) {
|
||||
suspend operator fun invoke(): Result<List<Item>> {
|
||||
return repository.getAll()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## expect/actual(KMP)
|
||||
|
||||
プラットフォーム固有の実装に使用:
|
||||
|
||||
```kotlin
|
||||
// commonMain
|
||||
expect fun platformName(): String
|
||||
expect class SecureStorage {
|
||||
fun save(key: String, value: String)
|
||||
fun get(key: String): String?
|
||||
}
|
||||
|
||||
// androidMain
|
||||
actual fun platformName(): String = "Android"
|
||||
actual class SecureStorage {
|
||||
actual fun save(key: String, value: String) { /* EncryptedSharedPreferences */ }
|
||||
actual fun get(key: String): String? = null /* ... */
|
||||
}
|
||||
|
||||
// iosMain
|
||||
actual fun platformName(): String = "iOS"
|
||||
actual class SecureStorage {
|
||||
actual fun save(key: String, value: String) { /* Keychain */ }
|
||||
actual fun get(key: String): String? = null /* ... */
|
||||
}
|
||||
```
|
||||
|
||||
## コルーチンパターン
|
||||
|
||||
- ViewModel では `viewModelScope`、構造化された子作業には `coroutineScope` を使用
|
||||
- コールド Flow から StateFlow への変換には `stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), initialValue)` を使用
|
||||
- 子の失敗を独立させる場合は `supervisorScope` を使用
|
||||
|
||||
## DSL を使った Builder パターン
|
||||
|
||||
```kotlin
|
||||
class HttpClientConfig {
|
||||
var baseUrl: String = ""
|
||||
var timeout: Long = 30_000
|
||||
private val interceptors = mutableListOf<Interceptor>()
|
||||
|
||||
fun interceptor(block: () -> Interceptor) {
|
||||
interceptors.add(block())
|
||||
}
|
||||
}
|
||||
|
||||
fun httpClient(block: HttpClientConfig.() -> Unit): HttpClient {
|
||||
val config = HttpClientConfig().apply(block)
|
||||
return HttpClient(config)
|
||||
}
|
||||
|
||||
// 使用例
|
||||
val client = httpClient {
|
||||
baseUrl = "https://api.example.com"
|
||||
timeout = 15_000
|
||||
interceptor { AuthInterceptor(tokenProvider) }
|
||||
}
|
||||
```
|
||||
|
||||
## リファレンス
|
||||
|
||||
スキル: `kotlin-coroutines-flows` で詳細なコルーチンパターンを参照してください。
|
||||
スキル: `android-clean-architecture` でモジュールとレイヤーパターンを参照してください。
|
||||
82
docs/ja-JP/rules/kotlin/security.md
Normal file
82
docs/ja-JP/rules/kotlin/security.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.kt"
|
||||
- "**/*.kts"
|
||||
---
|
||||
# Kotlin セキュリティ
|
||||
|
||||
> このファイルは [common/security.md](../common/security.md) を Kotlin および Android/KMP 固有のコンテンツで拡張します。
|
||||
|
||||
## シークレット管理
|
||||
|
||||
- API キー、トークン、認証情報をソースコードにハードコードしない
|
||||
- ローカル開発のシークレットには `local.properties`(git で無視)を使用する
|
||||
- リリースビルドには CI シークレットから生成される `BuildConfig` フィールドを使用する
|
||||
- ランタイムのシークレット保存には `EncryptedSharedPreferences`(Android)または Keychain(iOS)を使用する
|
||||
|
||||
```kotlin
|
||||
// BAD
|
||||
val apiKey = "sk-abc123..."
|
||||
|
||||
// GOOD — BuildConfig から(ビルド時に生成)
|
||||
val apiKey = BuildConfig.API_KEY
|
||||
|
||||
// GOOD — ランタイム時にセキュアストレージから
|
||||
val token = secureStorage.get("auth_token")
|
||||
```
|
||||
|
||||
## ネットワークセキュリティ
|
||||
|
||||
- HTTPS のみを使用する — クリアテキストをブロックするため `network_security_config.xml` を設定する
|
||||
- 機密性の高いエンドポイントには OkHttp の `CertificatePinner` または Ktor 相当で証明書ピンニングを行う
|
||||
- すべての HTTP クライアントにタイムアウトを設定する — デフォルト(無限の場合がある)のまま放置しない
|
||||
- すべてのサーバーレスポンスを使用前に検証・サニタイズする
|
||||
|
||||
```xml
|
||||
<!-- res/xml/network_security_config.xml -->
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="false" />
|
||||
</network-security-config>
|
||||
```
|
||||
|
||||
## 入力検証
|
||||
|
||||
- 処理や API 送信前にすべてのユーザー入力を検証する
|
||||
- Room/SQLDelight にはパラメータ化クエリを使用する — ユーザー入力を SQL に連結しない
|
||||
- パストラバーサルを防ぐためユーザー入力のファイルパスをサニタイズする
|
||||
|
||||
```kotlin
|
||||
// BAD — SQL インジェクション
|
||||
@Query("SELECT * FROM items WHERE name = '$input'")
|
||||
|
||||
// GOOD — パラメータ化
|
||||
@Query("SELECT * FROM items WHERE name = :input")
|
||||
fun findByName(input: String): List<ItemEntity>
|
||||
```
|
||||
|
||||
## データ保護
|
||||
|
||||
- Android では機密性の高いキーバリューデータに `EncryptedSharedPreferences` を使用する
|
||||
- 明示的なフィールド名で `@Serializable` を使用する — 内部プロパティ名を漏洩させない
|
||||
- 不要になった機密データはメモリからクリアする
|
||||
- シリアライズされたクラスの名前マングリングを防ぐため `@Keep` または ProGuard ルールを使用する
|
||||
|
||||
## 認証
|
||||
|
||||
- トークンはプレーンな SharedPreferences ではなくセキュアストレージに保存する
|
||||
- 適切な 401/403 ハンドリングでトークンリフレッシュを実装する
|
||||
- ログアウト時にすべての認証状態をクリアする(トークン、キャッシュされたユーザーデータ、Cookie)
|
||||
- 機密性の高い操作にはバイオメトリクス認証(`BiometricPrompt`)を使用する
|
||||
|
||||
## ProGuard / R8
|
||||
|
||||
- すべてのシリアライズされたモデル(`@Serializable`、Gson、Moshi)の Keep ルール
|
||||
- リフレクションベースのライブラリ(Koin、Retrofit)の Keep ルール
|
||||
- リリースビルドをテストする — 難読化はシリアライズを無言で壊す可能性がある
|
||||
|
||||
## WebView セキュリティ
|
||||
|
||||
- 明示的に必要でない限り JavaScript を無効にする: `settings.javaScriptEnabled = false`
|
||||
- WebView にロードする前に URL を検証する
|
||||
- 機密データにアクセスする `@JavascriptInterface` メソッドを公開しない
|
||||
- `WebViewClient.shouldOverrideUrlLoading()` を使用してナビゲーションを制御する
|
||||
128
docs/ja-JP/rules/kotlin/testing.md
Normal file
128
docs/ja-JP/rules/kotlin/testing.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.kt"
|
||||
- "**/*.kts"
|
||||
---
|
||||
# Kotlin テスト
|
||||
|
||||
> このファイルは [common/testing.md](../common/testing.md) を Kotlin および Android/KMP 固有のコンテンツで拡張します。
|
||||
|
||||
## テストフレームワーク
|
||||
|
||||
- **kotlin.test** — マルチプラットフォーム(KMP)用(`@Test`、`assertEquals`、`assertTrue`)
|
||||
- **JUnit 4/5** — Android 固有のテスト用
|
||||
- **Turbine** — Flow と StateFlow のテスト用
|
||||
- **kotlinx-coroutines-test** — コルーチンテスト用(`runTest`、`TestDispatcher`)
|
||||
|
||||
## Turbine を使った ViewModel テスト
|
||||
|
||||
```kotlin
|
||||
@Test
|
||||
fun `loading state emitted then data`() = runTest {
|
||||
val repo = FakeItemRepository()
|
||||
repo.addItem(testItem)
|
||||
val viewModel = ItemListViewModel(GetItemsUseCase(repo))
|
||||
|
||||
viewModel.state.test {
|
||||
assertEquals(ItemListState(), awaitItem()) // 初期状態
|
||||
viewModel.onEvent(ItemListEvent.Load)
|
||||
assertTrue(awaitItem().isLoading) // ローディング中
|
||||
assertEquals(listOf(testItem), awaitItem().items) // ロード完了
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## モックよりもフェイクを優先
|
||||
|
||||
モッキングフレームワークよりも手書きのフェイクを優先する:
|
||||
|
||||
```kotlin
|
||||
class FakeItemRepository : ItemRepository {
|
||||
private val items = mutableListOf<Item>()
|
||||
var fetchError: Throwable? = null
|
||||
|
||||
override suspend fun getAll(): Result<List<Item>> {
|
||||
fetchError?.let { return Result.failure(it) }
|
||||
return Result.success(items.toList())
|
||||
}
|
||||
|
||||
override fun observeAll(): Flow<List<Item>> = flowOf(items.toList())
|
||||
|
||||
fun addItem(item: Item) { items.add(item) }
|
||||
}
|
||||
```
|
||||
|
||||
## コルーチンテスト
|
||||
|
||||
```kotlin
|
||||
@Test
|
||||
fun `parallel operations complete`() = runTest {
|
||||
val repo = FakeRepository()
|
||||
val result = loadDashboard(repo)
|
||||
advanceUntilIdle()
|
||||
assertNotNull(result.items)
|
||||
assertNotNull(result.stats)
|
||||
}
|
||||
```
|
||||
|
||||
`runTest` を使用する — 仮想時間を自動的に進め、`TestScope` を提供する。
|
||||
|
||||
## Ktor MockEngine
|
||||
|
||||
```kotlin
|
||||
val mockEngine = MockEngine { request ->
|
||||
when (request.url.encodedPath) {
|
||||
"/api/items" -> respond(
|
||||
content = Json.encodeToString(testItems),
|
||||
headers = headersOf(HttpHeaders.ContentType, ContentType.Application.Json.toString())
|
||||
)
|
||||
else -> respondError(HttpStatusCode.NotFound)
|
||||
}
|
||||
}
|
||||
|
||||
val client = HttpClient(mockEngine) {
|
||||
install(ContentNegotiation) { json() }
|
||||
}
|
||||
```
|
||||
|
||||
## Room/SQLDelight テスト
|
||||
|
||||
- Room: インメモリテストには `Room.inMemoryDatabaseBuilder()` を使用
|
||||
- SQLDelight: JVM テストには `JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)` を使用
|
||||
|
||||
```kotlin
|
||||
@Test
|
||||
fun `insert and query items`() = runTest {
|
||||
val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
|
||||
Database.Schema.create(driver)
|
||||
val db = Database(driver)
|
||||
|
||||
db.itemQueries.insert("1", "Sample Item", "description")
|
||||
val items = db.itemQueries.getAll().executeAsList()
|
||||
assertEquals(1, items.size)
|
||||
}
|
||||
```
|
||||
|
||||
## テスト命名
|
||||
|
||||
バッククォートで囲んだ説明的な名前を使用する:
|
||||
|
||||
```kotlin
|
||||
@Test
|
||||
fun `search with empty query returns all items`() = runTest { }
|
||||
|
||||
@Test
|
||||
fun `delete item emits updated list without deleted item`() = runTest { }
|
||||
```
|
||||
|
||||
## テストの構成
|
||||
|
||||
```
|
||||
src/
|
||||
├── commonTest/kotlin/ # 共有テスト(ViewModel、UseCase、Repository)
|
||||
├── androidUnitTest/kotlin/ # Android ユニットテスト(JUnit)
|
||||
├── androidInstrumentedTest/kotlin/ # インストルメンテッドテスト(Room、UI)
|
||||
└── iosTest/kotlin/ # iOS 固有のテスト
|
||||
```
|
||||
|
||||
最低限のテストカバレッジ: すべての機能に対して ViewModel + UseCase。
|
||||
Reference in New Issue
Block a user