# コーディング規約 (Coding Standards)

本ドキュメントでは，MiniTIAS プロジェクトの Dart / Flutter コーディング規約を定義する．
基本方針として [Effective Dart](https://dart.dev/effective-dart) に準拠し，プロジェクト固有のルールのみ本書で定める．

## フォーマット (Formatting)

- `dart format` のデフォルト設定に従う（行幅 80 文字）
- VS Code の「保存時フォーマット」を有効にする（`.vscode/settings.json` で設定済み）
- 手動でのフォーマット調整は行わない

## 命名規則 (Naming Conventions)

Effective Dart の命名規則に従う．プロジェクト固有の補足は以下の通り．

| 対象 | 規則 | 例 |
| --- | --- | --- |
| ファイル名 | snake_case | `camera_provider.dart` |
| クラス名 | UpperCamelCase | `CameraProvider` |
| 変数・関数 | lowerCamelCase | `takePhoto()` |
| 定数 | lowerCamelCase | `defaultImageQuality` |
| プライベート | 先頭に `_` | `_controller` |
| Provider | `〇〇Provider` | `CameraProvider` |
| Service | `〇〇Service` | `FileService` |
| Screen（画面） | `〇〇Screen` | `CaptureScreen` |
| Widget（部品） | 機能を表す名前 | `ShutterButton` |

## import 順序 (Import Order)

以下の順序で記述し，各グループ間は空行で区切る．

```dart
// 1. Dart SDK
import 'dart:async';
import 'dart:io';

// 2. Flutter SDK
import 'package:flutter/material.dart';

// 3. 外部パッケージ（pub.dev）
import 'package:camera/camera.dart';
import 'package:provider/provider.dart';

// 4. プロジェクト内
import 'package:mini_tias/providers/camera_provider.dart';
import 'package:mini_tias/services/file_service.dart';
```

※ `dart fix --apply` および `dart format` で自動整列されるため，手動調整は不要．

## ディレクトリ構造 (Directory Structure)

[SPEC_01_画面機能仕様書](../04_SPEC/SPEC_01_画面機能仕様書.md) のアーキテクチャセクションで定義したディレクトリ構成に従う．

```text
lib/
├── main.dart                  # エントリポイント，Provider 登録
├── app.dart                   # MaterialApp，テーマ
├── providers/                 # 状態管理（ChangeNotifier）
├── screens/                   # 画面（Scaffold 単位）
├── widgets/                   # 再利用可能な UI 部品
└── services/                  # 外部リソースとの橋渡し
```

### 配置ルール

- **1 ファイル 1 クラス** を原則とする．ファイル名はクラス名の snake_case 版
- **screens/**: 各画面に対応する 1 ファイル．画面固有のロジックは対応する Provider に置く
- **widgets/**: 複数画面で再利用する UI 部品，または画面ファイルが大きくなった場合に切り出す部品
- **providers/**: 画面または機能ごとに 1 ファイル．ChangeNotifier を継承する
- **services/**: プラットフォーム API やファイルシステムへのアクセスを担う

## 型の使い方 (Type Usage)

- ローカル変数は型推論（`var` / `final`）を活用する
- 関数の引数・戻り値には明示的に型を記述する
- `dynamic` は避け，`Object?` を使用する
- `final` をデフォルトとし，再代入が必要な場合のみ `var` を使用する

## エラーハンドリング (Error Handling)

### 基本方針

- **Service 層**: 例外をキャッチし，呼び出し元に結果を返す．想定外の例外はそのまま上位に伝播させる
- **Provider 層**: Service の結果を受け取り，状態（エラーメッセージ等）として保持する
- **Screen 層**: Provider の状態を参照し，ユーザーにフィードバックを表示する（スナックバー等）

### 想定するエラー

| エラー | 発生箇所 | 対処 |
| --- | --- | --- |
| カメラ初期化失敗 | CameraProvider | エラーメッセージを画面に表示 |
| パーミッション拒否 | PermissionService | 設定画面への誘導を表示 |
| ストレージ書き込み失敗 | FileService | スナックバーでエラー通知 |
| ファイル削除失敗 | FileService | スナックバーでエラー通知 |

### ログ出力

- 開発中は `debugPrint()` を使用する（リリースビルドでは自動的に無効化される）
- `print()` は使用しない

## ドキュメント (Documentation)

### コード内コメント

- **DartDoc コメント（`///`）**: 公開 API（public なクラス・メソッド）に記述する
- **実装コメント（`//`）**: ロジックが自明でない箇所にのみ記述する
- 「何をしているか」ではなく「なぜそうしているか」を書く

### DartDoc の書き方

```dart
/// 撮影画像を PNG 形式で共有ストレージに保存する．
///
/// [imageBytes] は JPEG エンコード済みの画像データ．
/// 保存先は `Pictures/MiniTIAS/` ディレクトリ．
/// 同秒の重複ファイルが存在する場合は連番サフィックスを付与する．
Future<String> saveImage(Uint8List imageBytes) async {
  // ...
}
```

- 1 行目は動詞で始める簡潔な要約（句点で終わる）
- 詳細が必要な場合は空行を挟んで続ける
- パラメータの説明は `[paramName]` 記法を使用する
