Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"includeCoAuthoredBy": false,
"enableAllProjectMcpServers": true,
"permissions": {
"allow": [
"Bash(gemini:*)",
"Bash(git:*)"
],
"deny": [
"Bash(sudo:*)",
"Read(.env.*)",
"Read(id_rsa)",
"Read(id_ed25519)",
"Read(**/*token*)",
"Read(**/*key*)",
"Write(.env*)",
"Write(**/secrets/**)",
"Bash(wget:*)",
"Bash(nc:*)",
"Bash(rm:*)",
"Bash(npm uninstall:*)",
"Bash(npm remove:*)",
"Bash(psql:*)",
"Bash(mysql:*)",
"Bash(mongod:*)",
"mcp__supabase__execute_sql"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "if jq -r '.tool_input.command' | grep -q '^git commit' && jq -r '.tool_input.command' | grep -q '🤖 Generated with'; then echo 'Error: コミットメッセージに AI 署名が含まれている' 1>&2; exit 2; fi"
}
]
}
],
"PostToolUse": [],
"Notification": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"確認待ち\" with title \"Claude Code\"'"
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"タスク完了\" with title \"Claude Code\"'"
}
]
}
]
}
}
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.{kt,kts}]
ktlint_code_style = ktlint_official
ktlint_standard_no-wildcard-imports = disabled
ktlint_standard_filename = disabled
48 changes: 48 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"mcpServers": {
"serena": {
"type": "stdio",
"command": "uvx",
"args": [
"--from",
"git+https://github.com/oraios/serena",
"serena-mcp-server",
"--context",
"ide-assistant",
"--project",
"."
],
"env": {}
},
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
},
"sequential-thinking": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sequential-thinking"
]
},
"context7": {
"command": "npx",
"args": [
"-y",
"@upstash/context7-mcp"
]
}
},
"scopes": {
"ide-assistant": {
"mcpServers": [
"serena",
"playwright",
"sequential-thinking",
"context7"
]
}
}
}
103 changes: 103 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## プロジェクト情報
- **名称**: KidsPOS for Android - キッズビジネスタウンいちかわ用POSシステム
- **パッケージ**: info.nukoneko.cuc.android.kidspos
- **Android SDK**: minSdk 23, targetSdk 33 (buildSrc/Versions.ktで管理)
- **Kotlin JVM Target**: 17

## 開発コマンド

### ビルド
```bash
# Prodビルド(本番用)
./gradlew assembleProdDebug # デバッグビルド
./gradlew assembleProdRelease # リリースビルド

# Demoビルド(デモ用)
./gradlew assembleDemoDebug
./gradlew assembleDemoRelease

# クリーンビルド
./gradlew clean assembleProdDebug
```

### テストとLint
```bash
# ユニットテスト実行
./gradlew test
./gradlew testProdDebugUnitTest

# Lint実行(必須)
./gradlew lint
./gradlew lintProdDebug

# Lint自動修正
./gradlew lintFix
```

### デバイスへのインストール
```bash
./gradlew installProdDebug
./gradlew uninstallProdDebug
```

## アーキテクチャ構造

### MVVMパターン
- **View層**: Activity/Fragment (DataBinding/ViewBinding使用)
- **ViewModel層**: AndroidX ViewModelを継承
- **Model層**: Repository、API、Entity

### 依存性注入
- **Koin**: メインのDIフレームワーク(modules: coreModule, apiModule, viewModelModule)
- **Hilt**: Dagger Hiltも併用可能
- 新規依存は `di/module/` 配下の適切なモジュールに追加

### イベント駆動
- **EventBus** (org.greenrobot): アプリ全体のイベント通信
- イベントクラスは `event/` パッケージに配置
- `@Subscribe(threadMode = ThreadMode.MAIN)` でハンドラー定義

### 非同期処理
- **Kotlin Coroutines**: `viewModelScope`、`lifecycleScope` を使用
- **Retrofit + OkHttp**: API通信(ServerSelectionInterceptorで動的サーバー切替)

## コーディング規則

### ログ出力(重要)
```kotlin
// ❌ 禁止
print("message")
println("message")
debugPrint("message")

// ✅ 必須:Logger使用
Logger.d("Debug message")
Logger.e("Error message")
Logger.i("Info message")
```

### ファイル命名
- Activity: `*Activity.kt`
- Fragment: `*Fragment.kt`
- ViewModel: `*ViewModel.kt`
- レイアウト: `activity_*.xml`, `fragment_*.xml`, `item_*.xml`

### バーコード機能
- `BarcodeReadDelegate` インターフェースを実装
- `BaseBarcodeReadableActivity` を継承してActivity作成

### リソース管理
- 全ての文字列は `strings.xml` に定義(日本語のみ)
- 既存実装パターンを必ず参照・踏襲する

## タスク完了時の確認事項

1. **ビルド成功確認**: `./gradlew assembleProdDebug`
2. **Lintエラーゼロ**: `./gradlew lint`
3. **テスト合格**: `./gradlew test`
4. **Logger使用確認**: print文が含まれていないこと
5. **既存パターン準拠**: 類似機能の実装を参照したこと
40 changes: 37 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import dependencies.Dep
import dependencies.Packages
import dependencies.Versions
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id 'com.android.application'
Expand All @@ -11,6 +12,7 @@ plugins {
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'com.google.dagger.hilt.android'
id 'org.openapi.generator'
}

android {
Expand Down Expand Up @@ -117,9 +119,7 @@ dependencies {
implementation libs.androidx.preference.ktx
implementation libs.androidx.constraintlayout

implementation(Dep.Zxing.android) {
transitive = false
}
implementation(Dep.Zxing.android)

coreLibraryDesugaring libs.desugar.jdk.libs

Expand All @@ -133,7 +133,41 @@ dependencies {

implementation libs.retrofit.client
implementation libs.retrofit.converter.serialization
implementation libs.converter.scalars

implementation libs.logger
implementation libs.eventbus
}

// OpenAPI Generator Configuration
openApiGenerate {
generatorName.set("kotlin")
inputSpec.set("$projectDir/openapi/api.yaml")
outputDir.set("$buildDir/generated/openapi")
apiPackage.set("info.nukoneko.cuc.android.kidspos.api.generated")
modelPackage.set("info.nukoneko.cuc.android.kidspos.api.generated.model")
invokerPackage.set("info.nukoneko.cuc.android.kidspos.api.generated.invoker")
configOptions.set([
"library" : "jvm-retrofit2",
"useCoroutines" : "true",
"serializationLibrary": "kotlinx_serialization",
"dateLibrary" : "java8",
"enumPropertyNaming" : "UPPERCASE",
"collectionType" : "list"
])
additionalProperties.set([
"generateApiDocumentation" : "false",
"generateModelDocumentation": "false"
])
}

// Add generated sources to source sets
android.sourceSets {
main.kotlin.srcDirs += "$buildDir/generated/openapi/src/main/kotlin"
}

// Make sure code is generated before compilation
tasks.withType(KotlinCompile).configureEach {
dependsOn tasks.openApiGenerate
}

Loading