h-1.flutter.4/docs/project_specification.md

409 lines
No EOL
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 制作小プロジェクト - 企画設計指示書
## 1. プロジェクト概要
### 1.1 目的
リッチなマスター編集機能を持つ販売アシスタントアプリを効率的に開発するための、AILLMによる自動コーディングを支援する企画設計指示書。
### 1.2 スコープ
- マスターデータの CRUD 機能強化
- リッチな入力フィールド(画像/動画アップロード、QR コード生成)
- フォームバリデーションとヒント表示
- 汎用ウィジェットによるコード削減
---
## 2. コンテンツ定義
### 2.1 データモデル一覧
#### Customer得意先
| プロパティ | タイプ | キー | ビルンール | ヒント |
|----------|--------|------|-----------|--------|
| id | int? | PK | autoincrement | - |
| name | String | UK | not null, max 50 | 例:株式会社〇〇、個人名で可 |
| email | String | | unique, nullable, max 100 | メールアドレス形式(*@example.com|
| phone | String | | nullable, max 20 | 電話番号区切りなし090-1234-5678→09012345678|
| address | String | | nullable, max 200 | 住所(省スペース表示・多言語対応)|
| created_at | DateTime? | - | null allow | DB レコード作成時 |
#### Product商品
| プロパティ | タイプ | キー | ビルンール | ヒント |
|----------|--------|------|-----------|--------|
| id | int? | PK | autoincrement | - |
| name | String | UK | not null, max 50 | 例iPhone、ートパソコンなど |
| price | double? | - | null allow | 円単位(小数点以下 2 桁)|
| stock | int? | - | null allow | 在庫数 |
| description | String | - | nullable, max 500 | 商品の説明・特徴 |
| created_at | DateTime? | - | null allow | DB レコード作成時 |
#### Supplier仕入先
| プロパティ | タイプ | キー | ビルンール | ヒント |
|----------|--------|------|-----------|--------|
| id | int? | PK | autoincrement | - |
| name | String | UK | not null, max 50 | 例:株式会社〇〇、個人名で可 |
| email | String | | unique, nullable, max 100 | メールアドレス形式(*@example.com|
| phone | String | | nullable, max 20 | 電話番号(区切りなし)|
| address | String | | nullable, max 200 | 住所 |
| created_at | DateTime? | - | null allow | DB レコード作成時 |
#### Warehouse倉庫
| プロパティ | タイプ | キー | ビルンール | ヒント |
|----------|--------|------|-----------|--------|
| id | int? | PK | autoincrement | - |
| name | String | UK | not null, max 50 | 例:東京都千代田区〇丁目倉庫、大阪支店倉庫 |
| address | String | | nullable, max 200 | 住所 |
| capacity | int? | - | null allow | 保管容量(単位:坪)|
| created_at | DateTime? | - | null allow | DB レコード作成時 |
#### Employee担当者
| プロパティ | タイプ | キー | ビルンール | ヒント |
|----------|--------|------|-----------|--------|
| id | int? | PK | autoincrement | - |
| name | String | UK | not null, max 50 | 例:田中太郎、鈴木花子 |
| email | String | | unique, nullable, max 100 | メールアドレス形式(*@example.com|
| phone | String | | nullable, max 20 | 電話番号(区切りなし)|
| role | String | - | nullable, max 30 | 例:管理者、営業、倉庫員など |
| created_at | DateTime? | - | null allow | DB レコード作成時 |
---
## 3. UI コンポーネント定義
### 3.1 汎用ウィジェット一覧
#### RichMasterTextFieldテキスト入力
```dart
RichMasterTextField(
label: '商品名',
initialValue: 'iPhone',
hintText: '例iPhone、ートパソコンなど',
maxLines: 1,
)
```
#### RichMasterNumberField数値入力
```dart
RichMasterNumberField(
label: '価格',
initialValue: 128000.0,
hintText: '例128,000円、98,500 円など',
decimalDigits: 2,
)
```
#### RichMasterDateField日付選択
```dart
RichMasterDateField(
label: '作成日',
initialValue: DateTime.now(),
hintText: '例2024/03/10、今日などの指定可',
)
```
#### RichMasterAddressField住所入力・省スペース
```dart
RichMasterAddressField(
label: '住所',
initialValue: '東京都千代田区〇丁目 1-1',
hintText: '例:都道府県名から検索可',
)
```
#### RichMasterFileUploaderファイル・画像アップロード
```dart
RichMasterFileUploader(
label: '商品画像',
onPickImage: () => print('画像選択'),
onPickVideo: () => print('動画選択'), // Android 限定
)
```
#### RichMasterQRCodeGeneratorQR コード生成)
```dart
RichMasterQRCodeGenerator(
label: 'QR コード',
text: 'https://example.com/product/123',
)
```
#### RichMasterCheckboxFieldチェックボックス
```dart
RichMasterCheckboxField(
label: '在庫あり',
initialValue: true,
onChanged: (value) => print(value),
)
```
#### RichMasterDropdownFieldドロップダウンリスト
```dart
RichMasterDropdownField<String>(
label: '担当部署',
initialValue: '営業部',
items: ['営業部', '総務部', '開発部'],
itemToString: (item) => item,
)
```
### 3.2 アプリバーAppBar定義
| ID | 名乘 |
|-----|------|
| /S1. 見積書 | Sales - Estimate |
| /S2. 請求書 | Sales - Invoice |
| /S3. 受発注一覧 | Order List |
| /S4. 売上入力(レジ) | Sales Register |
| /S5. 売上返品入力 | Return Input |
| /M1. 商品マスタ | Master - Product |
| /M2. 得意先マスタ | Master - Customer |
| /M3. 仕入先マスタ | Master - Supplier |
| /M4. 倉庫マスタ | Master - Warehouse |
| /M5. 担当者マスタ | Master - Employee |
---
## 4. ビヘイビア仕様
### 4.1 フォームバリデーション
- **必須フィールド**: 空文字の場合は赤いエラー表示 + ヒント文の再表示
- **メール形式検証**: *@example.com の形式のみ許可(正規表現:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
- **電話番号検証**: 数字のみ、最大 11 桁まで許可
- **数値フィールド**: 小数点以下指定桁数を超える入力時の自動補正
### 4.2 ヒント・エラー表示
```dart
// エラー状態
TextField(
errorText: hintText, // 初期値がヒントとなる
)
// カスタムエラー
TextField(
decoration: InputDecoration(errorText: '必須入力をしてください'),
)
```
### 4.3 ショートカットキー対応(オプション)
```dart
RichMasterShortcutSettings(
label: '編集ヘルプ',
showShortcuts: true,
shortcuts: {
'Ctrl+S': () => print('保存'),
'Ctrl+Z': () => print('取り消し'),
},
)
```
### 4.4 セクション分割表示
```dart
RichMasterSectionHeader(
title: '基本情報',
icon: Icons.info_outline,
color: Colors.blue.shade700,
)
```
---
## 5. コーディングワークフロー
### 5.1 マスタ画面作成手順
#### ステップ 1: モデル定義
```dart
// lib/models/customer.dart
class Customer {
int? id;
String name = '';
String? email;
String? phone;
String? address;
DateTime? createdAt;
Customer({
this.id,
required this.name,
this.email,
this.phone,
this.address,
this.createdAt,
});
factory Customer.fromJson(Map<String, dynamic> json) => Customer(
id: json['id'] as int?,
name: json['name'] as String,
email: json['email'] as String?,
phone: json['phone'] as String?,
address: json['address'] as String?,
createdAt: json['created_at'] != null ? DateTime.parse(json['created_at']) : null,
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'email': email,
'phone': phone,
'address': address,
'created_at': createdAt?.toIso8601String(),
};
Customer copyWith({
int? id,
String? name,
String? email,
String? phone,
String? address,
DateTime? createdAt,
}) => Customer(
id: id ?? this.id,
name: name ?? this.name,
email: email ?? this.email,
phone: phone ?? this.phone,
address: address ?? this.address,
createdAt: createdAt ?? this.createdAt,
);
}
```
#### ステップ 2: スクリーン定義master_edit_fields.dart を使用)
```dart
// lib/screens/master/customer_master_screen.dart
class CustomerMasterScreen extends StatefulWidget {
const CustomerMasterScreen({super.key});
@override
State<CustomerMasterScreen> createState() => _CustomerMasterScreenState();
}
class _CustomerMasterScreenState extends State<CustomerMasterScreen> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
// データモデル(データベース連携)
late Customer _customer;
@override
void initState() {
super.initState();
_customer = Customer(name: ''); // 初期値設定
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('/M2. 得意先マスタ')),
body: Form(
key: _formKey,
child: ListView(
children: [
// RichMasterTextField商品名
RichMasterTextField(
label: '得意先名',
initialValue: _customer.name,
hintText: '例:株式会社〇〇、個人名で可',
onChanged: (value) => setState(() => _customer.name = value),
),
// RichMasterTextFieldメール
RichMasterTextField(
label: 'メールアドレス',
initialValue: _customer.email,
keyboardType: TextInputType.emailAddress,
hintText: '@example.com の形式info@example.com',
onChanged: (value) => setState(() => _customer.email = value),
),
// RichMasterNumberField電話番号
RichMasterTextField(
label: '電話番号',
initialValue: _customer.phone,
hintText: '例090-1234-5678、区切り不要',
onChanged: (value) => setState(() => _customer.phone = value),
),
// RichMasterDateField作成日
RichMasterDateField(
label: '登録日',
initialValue: _customer.createdAt?.toLocal(),
hintText: '例2024/03/10、今日などの指定可',
),
// 保存ボタン
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => Navigator.pop(context, _customer.toJson()),
child: Text('保存'),
),
),
],
),
),
);
}
}
```
### 5.2 汎用マスター作成テンプレートAI 生成用)
AI に自動生成させるためのプロンプト例:
```text
以下のデータモデルでマスター画面を作成してください:
- データモデル: {model_definition}
- スクリーン ID: {screen_id, e.g., /M3. 仕入先マスタ}
- 使用ウィジェット: RichMasterTextField, RichMasterNumberField, RichMasterDateField などmaster_edit_fields.dart を参照)
要件:
1. AppBar に「{screen_id}」を表示
2. フォームキーでバリデーションを行う
3. 保存ボタンでデータを JSON 形式で返す
4. 必須フィールドは空文字をエラー扱いに
```
---
## 6. テスト用データ
### 6.1 Customer得意先テストデータ
```json
{
"name": "株式会社 ABC",
"email": "info@abc-company.com",
"phone": "03-1234-5678",
"address": "東京都千代田区〇丁目 1-1"
}
```
### 6.2 Product商品テストデータ
```json
{
"name": "iPhone 15 Pro Max",
"price": 199440.0,
"description": "チタニウム素材の高級スマートフォン。A17 Pro チップ搭載。"
}
```
### 6.3 Warehouse倉庫テストデータ
```json
{
"name": "東京都千代田区支店倉庫",
"address": "東京都千代田区〇丁目 1-1",
"capacity": 50
}
```
---
## 7. まとめ
この指示書を使用することで、以下が可能になります:
1. **AI による自動コーディング**: データモデルから画面コードを生成
2. **一貫性のある UI**: 汎用ウィジェットでデザイン統一
3. **保守性の向上**: 部品レベルでの再利用・修正
4. **開発効率化**: テンプレートベースの迅速な実装
この指示書を元に、LLMGPT-4 など)に自動コーディングを依頼するか、自前で実装を進めてください。