# Superport ERP Development Guide v4.0 *Complete Flutter ERP System with Clean Architecture + CO-STAR Framework* --- ## ๐ŸŽฏ PROJECT STATUS ```yaml Current_State: "์ƒ‰์ƒ ์ผ๋ถ€ ๋ณ€๊ฒฝ ์™„๋ฃŒ - ์‹ค์ œ UI ํ†ต์ผ์„ฑ ์ž‘์—… ํ•„์š”" API_Coverage: "100%+ (61/53 endpoints implemented)" System_Health: "Production Ready - Flutter Analyze ERROR: 0" Architecture: "Clean Architecture + shadcn_ui + 100% Backend Dependency" Framework: "CO-STAR + Design System + 1920x1080 Optimized" ``` **๐Ÿ† ACHIEVEMENT: Complete ERP system with 7 core modules + Integrated Dashboard System** --- ## ๐ŸŽฏ CO-STAR FRAMEWORK IMPLEMENTATION ### Context (C) - System Environment ```yaml System_Type: "Enterprise Resource Planning (ERP)" Technology_Stack: "Flutter + Clean Architecture + shadcn_ui" Backend_Integration: "100% API-driven with Rust backend" Data_Flow: "Unidirectional - Backend โ†’ Frontend only" ``` ### Objective (O) - Development Goals ```yaml Primary_Goal: "Create production-ready ERP with zero errors" Code_Quality: "Flutter Analyze ERROR: 0 (mandatory)" Architecture_Compliance: "100% Clean Architecture adherence" User_Experience: "Consistent UI/UX with shadcn_ui components" ``` ## โš ๏ธ CRITICAL DEVELOPMENT GUIDELINES ### ์ž‘์—… ํ’ˆ์งˆ ๊ฒ€์ฆ ์›์น™ ```yaml ์‹ค์ œ_๊ฐœ์„ _์šฐ์„ : "์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ๋А๋‚„ ์ˆ˜ ์žˆ๋Š” ๊ฐœ์„ ์—๋งŒ ์ง‘์ค‘" ๊ณผ์žฅ_๊ธˆ์ง€: "์ƒ‰์ƒ ๋ณ€๊ฒฝ์„ '์™„์ „ ์žฌ์„ค๊ณ„'๋กœ ํฌ์žฅ ๊ธˆ์ง€" agent_์ ๊ทน_ํ™œ์šฉ: "๋ณต์žกํ•œ ์ž‘์—…์€ ๋ฐ˜๋“œ์‹œ ์ ์ ˆํ•œ agent ์‚ฌ์šฉ" ๊ตฌ์ฒด์ _์™„์„ฑ๊ธฐ์ค€: "๋ชจํ˜ธํ•œ ๋ชฉํ‘œ ์„ค์ • ๊ธˆ์ง€, ์ธก์ • ๊ฐ€๋Šฅํ•œ ๊ธฐ์ค€๋งŒ ์‚ฌ์šฉ" ๋ฌธ์„œํ™”_์ตœ์†Œํ™”: "๋ณด๊ณ ์„œ ์ž‘์„ฑ๋ณด๋‹ค ์‹ค์ œ ๊ฒฐ๊ณผ๋ฌผ ํ’ˆ์งˆ ์šฐ์„ " ``` ### UI ํ†ต์ผ์„ฑ ๊ฒ€์ฆ ์ฒดํฌ๋ฆฌ์ŠคํŠธ ```yaml ํ•„์ˆ˜_ํ†ต์ผ_์š”์†Œ: - ๋ชจ๋“  ํ™”๋ฉด ๋™์ผํ•œ ํ…Œ์ด๋ธ” ์ปดํฌ๋„ŒํŠธ (ShadTable.list) - Typography ์‹œ์Šคํ…œ ํ†ต์ผ (font-size, line-height, weight) - Spacing ์‹œ์Šคํ…œ ํ†ต์ผ (padding, margin, gap) - BorderRadius ๊ฐ’ ํ†ต์ผ (ShadcnTheme.radius*) - ๋ ˆ์ด์•„์›ƒ ๊ตฌ์กฐ ํ‘œ์ค€ํ™” (BaseListScreen template) - ์ƒ‰์ƒ ์‚ฌ์šฉ ์ผ๊ด€์„ฑ (ShadcnTheme.* ์ƒ์ˆ˜๋งŒ ์‚ฌ์šฉ) ๊ฒ€์ฆ_๋ฐฉ๋ฒ•: - ๋งค ์ž‘์—… ํ›„ "์‚ฌ์šฉ์ž๊ฐ€ ์ด ์ฐจ์ด๋ฅผ ์‹ค์ œ๋กœ ๋А๋‚„๊นŒ?" ์ž๋ฌธ - Agent๋ฅผ ํ†ตํ•œ ํ™”๋ฉด๋ณ„ ์ฐจ์ด์  ๊ฐ๊ด€์  ๋ถ„์„ - ์‹ค์ œ ํ™”๋ฉด ์บก์ฒ˜ ๋น„๊ต (๊ฐ€๋Šฅ์‹œ) ``` ### Style (S) - Code & Communication Style ```yaml Code_Style: "Declarative, functional, immutable" Naming_Convention: "Backend field names = absolute truth" Documentation: "Inline comments minimal, self-documenting code" Error_Handling: "Explicit error states with user feedback" ``` ### Tone (T) - Development Approach ```yaml Execution: "Direct, efficient, no over-engineering" Problem_Solving: "Backend-first, data-driven decisions" Communication: "Clear, technical, action-oriented" Iteration: "Rapid prototyping with immediate validation" ``` ### Audience (A) - Target Users & Developers ```yaml End_Users: "Warehouse operators, inventory managers" Developers: "Senior Flutter developers familiar with Clean Architecture" Maintenance_Team: "Backend-focused with minimal frontend expertise" Stakeholders: "Business owners requiring zero-downtime operations" ``` ### Response (R) - Expected Outputs ```yaml Code_Output: "Production-ready, tested, documented" UI_Components: "100% shadcn_ui compliance" API_Integration: "Direct mapping to backend DTOs" Error_States: "Comprehensive error handling with recovery" ``` --- ## ๐Ÿ”ง CORE DEVELOPMENT PRINCIPLES ### Rule 1: UI Components (ABSOLUTE) ```dart // โœ… REQUIRED - shadcn_ui only ShadTable.list(), ShadButton.outline(), ShadSelect() // โŒ FORBIDDEN - Flutter base widgets DataTable(), ElevatedButton(), DropdownButton() ``` ### Rule 2: Backend Dependency (100%) ```yaml Policy: "Backend schema = absolute truth" Frontend_Role: "Data display only - zero business logic" API_Rule: "Use existing endpoints only - no modifications" Backend_Location: "/Users/maximilian.j.sul/Documents/flutter/superport_api/" ``` ### Rule 3: Clean Architecture (STRICT) ``` API โ† Repository โ† UseCase โ† Controller โ† UI โ””โ”€โ”€ DTO mapping with exact backend field names ``` ### Rule 4: Field Naming (CRITICAL) ```dart // โœ… CORRECT - Match backend exactly @JsonKey(name: 'companies_id') int? companiesId @JsonKey(name: 'models_id') int? modelsId // โŒ WRONG - Causes runtime exceptions @JsonKey(name: 'company_id') int? companyId ``` --- ## ๐Ÿš€ COMPLETED MODULES ### Production-Ready ERP Components 1. **Equipment Management**: CRUD + Advanced Search (Serial/Barcode/Company) 2. **Inventory Control**: Real-time stock tracking + Transaction history 3. **Maintenance System**: WARRANTY/CONTRACT/INSPECTION with 30-day alerts 4. **Rental Management**: Backend-calculated fields (isActive, daysRemaining) 5. **User Authentication**: Profile management + Password change 6. **Master Data**: Models/Vendors with vendor-specific filtering 7. **StandardDropdown**: Generic\ components with auto state management 8. **Outbound System**: Dialog-based multi-equipment processing with equipment_history API ### Key Business Value - **Warehouse Operations**: 30x faster with barcode scanning - **Maintenance Alerts**: Automatic 30-day expiry notifications - **Real-time Inventory**: Instant stock level updates - **Autonomous Management**: Zero IT dependency for master data --- ## ๐Ÿ“‹ DEVELOPMENT CHECKLIST ### Before Every Code Change - [ ] Verify backend API exists in `/superport_api/src/handlers/` - [ ] Confirm DTO field names match backend exactly - [ ] Use only shadcn_ui components (never Flutter base widgets) - [ ] Follow Clean Architecture pattern - [ ] Maintain Flutter Analyze ERROR: 0 ### Standard Form Implementation ```dart // Template for new forms class ExampleController extends ChangeNotifier { final ExampleUseCase _useCase; List _items = []; bool _isLoading = false; Future loadItems() async { _isLoading = true; notifyListeners(); final result = await _useCase.getItems(); result.fold( (failure) => _handleError(failure), (data) => _items = data, ); _isLoading = false; notifyListeners(); } } ``` ### StandardDropdown Usage ```dart StandardIntDropdown( label: '์ œ์กฐ์‚ฌ', isRequired: true, items: vendors, isLoading: _isLoadingVendors, error: errorMessage, onRetry: () => _loadVendors(), // Auto handles: Loading โ†’ Error (retry) โ†’ Success states ) ``` ### Outbound System Implementation (NEW) ```yaml Architecture_Pattern: "Dialog-based with Clean Architecture" Data_Flow: "Equipment List โ†’ Selection โ†’ Dialog โ†’ equipment_history API" Transaction_Type: "O (์ถœ๊ณ )" Backend_Endpoint: "POST /equipment-history" ``` **Implementation Details**: ```dart // Dialog Component EquipmentOutboundDialog( selectedEquipments: List, // Multi-selection support ) // Controller Pattern EquipmentOutboundController extends ChangeNotifier { // State management for companies, warehouses // Process each equipment as individual transaction // Link destination company via equipment_history_companies_link } // API Integration CreateEquipmentHistoryRequest( equipmentsId: equipment.id, warehousesId: warehouse.id, companyIds: [company.id], // Destination company linkage transactionType: 'O', // ์ถœ๊ณ  type quantity: 1, transactedAt: DateTime.now(), ) ``` **Key Features**: - Multi-equipment batch processing - Real-time inventory updates - Company/warehouse selection with StandardDropdown - Transaction history tracking - Zero backend modifications required --- ## ๐ŸŽฏ CURRENT PHASE ### ๐Ÿ”ง ์‹ค์ œ UI ํ†ต์ผ์„ฑ ์ž‘์—… (URGENT) **ํ˜„์žฌ ์ƒํƒœ**: ์ƒ‰์ƒ๋งŒ ์ผ๋ถ€ ๋ณ€๊ฒฝ๋จ - ์‹ค์ œ ํ™”๋ฉด๋ณ„ ๊ตฌ์กฐ/ํฌ๊ธฐ/๋ชจ์–‘ ๋ชจ๋‘ ๋‹ค๋ฆ„ #### **์‹ค์ œ ๋ฌธ์ œ์ ** - ๊ฐ ํ™”๋ฉด๋งˆ๋‹ค ํ…Œ์ด๋ธ” ๊ตฌ์กฐ ๋‹ค๋ฆ„ (ShadTable vs ์ˆ˜๋™ ๊ตฌ์„ฑ) - ๊ธ€์ž ํฌ๊ธฐ, ํŒจ๋”ฉ, ์—ฌ๋ฐฑ ๊ฐ’ ์ œ๊ฐ๊ฐ - ํ…Œ๋‘๋ฆฌ ๋‘ฅ๊ธ€๊ธฐ(BorderRadius) ๋ถˆ์ผ์น˜ - ๋ ˆ์ด์•„์›ƒ ๊ตฌ์กฐ ํ‘œ์ค€ํ™” ๋ฏธ์™„๋ฃŒ #### **ํ•ด์•ผ ํ•  ์‹ค์ œ ์ž‘์—…** - [ ] ๋ชจ๋“  ํ™”๋ฉด ShadTable.list()๋กœ ํ†ต์ผ - [ ] Typography ์‹œ์Šคํ…œ ์™„์ „ ํ†ต์ผ - [ ] Spacing/Padding ๊ฐ’ ํ‘œ์ค€ํ™” - [ ] BorderRadius ๊ฐ’ ํ†ต์ผ - [ ] ๋ ˆ์ด์•„์›ƒ ํ…œํ”Œ๋ฆฟ ํ‘œ์ค€ํ™” --- ## ๐Ÿ”— CRITICAL PATHS ```bash # Backend API Reference Backend: /Users/maximilian.j.sul/Documents/flutter/superport_api/ Handlers: src/handlers/*.rs Routes: src/handlers/mod.rs โ†’ configure_routes() # Frontend Structure Frontend: /Users/maximilian.j.sul/Documents/flutter/superport/ Architecture: lib/{data,domain,screens,services}/ ``` --- ## โš ๏ธ COMMON PITFALLS ### Type Safety Issues ```dart // โŒ Runtime Exception Risk _items = List.from(response.items); // โœ… Safe Type Conversion _items = (response.items as List).whereType().toList(); ``` ### Provider in Dialogs ```dart // โŒ Provider Missing showDialog(builder: (context) => MyDialog()); // โœ… Provider Wrapped showDialog( builder: (context) => ChangeNotifierProvider( create: (_) => MyController(), child: MyDialog(), ), ); ``` --- ## ๐Ÿ”ง ShadTable ์ „ํ™˜ ์ž‘์—… ๊ฐ€์ด๋“œ ### ๐ŸŽฏ ํ•ต์‹ฌ ๋ชฉํ‘œ - **๋ชจ๋“  ํ™”๋ฉด์„ shadcn_ui์˜ ๊ณต์‹ ShadTable ์ปดํฌ๋„ŒํŠธ๋กœ ํ†ต์ผ** - **์ปค์Šคํ…€ StandardDataTable ์‚ฌ์šฉ ๊ธˆ์ง€** (์œ ์ง€๋ณด์ˆ˜ ์–ด๋ ค์›€) - **์ˆ˜๋™ Row/Column ๊ตฌ์„ฑ ์™„์ „ ์ œ๊ฑฐ** ### ๐Ÿ“‹ ํ™”๋ฉด๋ณ„ ์ „ํ™˜ ํƒœ์Šคํฌ #### **Phase 1: Equipment List (ํŒŒ์ผ๋Ÿฟ)** **ํŒŒ์ผ**: `lib/screens/equipment/equipment_list.dart` **ํ˜„์žฌ**: `_buildFlexibleTable()` ์ˆ˜๋™ ๊ตฌ์„ฑ **๋ชฉํ‘œ**: `ShadTable.list()` ์ „ํ™˜ **๊ฒ€์ฆ**: - [ ] ์ฒดํฌ๋ฐ•์Šค ์„ ํƒ ๊ธฐ๋Šฅ ์ •์ƒ ๋™์ž‘ - [ ] ํŽ˜์ด์ง€๋„ค์ด์…˜ ์—ฐ๋™ - [ ] ์ถœ๊ณ /์ž…๊ณ  ๋ฒ„ํŠผ ์ด๋ฒคํŠธ - [ ] ํ˜ธ๋ฒ„/ํด๋ฆญ ์ด๋ฒคํŠธ #### **Phase 2: ๋‹จ์ˆœ ํ™”๋ฉด ์ „ํ™˜** 1. **Vendor Management** (`vendor_list_screen.dart`) 2. **Model Management** (`model_list_screen.dart`) ๊ฐ ํ™”๋ฉด: - [ ] ํ—ค๋” ๊ตฌ์กฐ๋ฅผ `ShadTableCell.header`๋กœ ๋ณ€ํ™˜ - [ ] ๋ฐ์ดํ„ฐ ํ–‰์„ `ShadTableCell`๋กœ ๋ณ€ํ™˜ - [ ] ์ปฌ๋Ÿผ ๋„ˆ๋น„๋ฅผ `columnSpanExtent`๋กœ ์„ค์ • - [ ] ๊ธฐ์กด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ `onRowTap`์œผ๋กœ ์—ฐ๊ฒฐ #### **Phase 3: ๋ณต์žก ํ™”๋ฉด ์ „ํ™˜** 1. **User List** (`user_list.dart`) 2. **Company List** (`company_list.dart`) 3. **Inventory History** (`inventory_history_screen.dart`) **์ฃผ์˜์‚ฌํ•ญ**: - ๊ถŒํ•œ๋ณ„ ๋ฐฐ์ง€ ์ปดํฌ๋„ŒํŠธ ๋ณด์กด - ํ•„ํ„ฐ/๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์˜ํ–ฅ ์ตœ์†Œํ™” - ์ƒํƒœ ๊ด€๋ฆฌ ๋กœ์ง ๋ณ€๊ฒฝ ๊ธˆ์ง€ ### โš ๏ธ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ ๋ฐฉ์ง€ ์ „๋žต #### **1. ์ปจํŠธ๋กค๋Ÿฌ ๊ฒฉ๋ฆฌ** - ํ…Œ์ด๋ธ” UI ๋ณ€๊ฒฝ๋งŒ ์ง„ํ–‰ - Controller/Repository/UseCase ์ˆ˜์ • ๊ธˆ์ง€ - ์ƒํƒœ ๊ด€๋ฆฌ ๋กœ์ง ์œ ์ง€ #### **2. ์ ์ง„์  ์ „ํ™˜** ```dart // Step 1: ๊ธฐ์กด ๊ตฌ์กฐ ๋ฐฑ์—… Widget _buildFlexibleTable_backup() { ... } // Step 2: ์ƒˆ ShadTable ๋ณ‘๋ ฌ ๊ตฌํ˜„ Widget _buildShadTable() { return ShadTable.list(...); } // Step 3: ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์œผ๋กœ ํ…Œ์ŠคํŠธ bool useShadTable = true; // ํ”Œ๋ž˜๊ทธ๋กœ ์ „ํ™˜ ``` #### **3. ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ ๋ณด์กด** - ๊ธฐ์กด `controller.equipments` ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ - `map()` ํ•จ์ˆ˜๋กœ ShadTableCell ๋ณ€ํ™˜๋งŒ ์ˆ˜ํ–‰ - ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ 1:1 ๋งคํ•‘ #### **4. ์Šคํƒ€์ผ ์ผ๊ด€์„ฑ** - ShadcnTheme ์ƒ์ˆ˜๋งŒ ์‚ฌ์šฉ - ์ปค์Šคํ…€ ์ƒ‰์ƒ ๊ธˆ์ง€ - padding/margin ๊ฐ’ ํ‘œ์ค€ํ™” ### ๐Ÿ” ๊ฒ€์ฆ ์ฒดํฌ๋ฆฌ์ŠคํŠธ ๊ฐ ํ™”๋ฉด ์ „ํ™˜ ํ›„ ํ•„์ˆ˜ ํ™•์ธ: - [ ] ๋ฐ์ดํ„ฐ ํ‘œ์‹œ ์ •ํ™•์„ฑ - [ ] ์ฒดํฌ๋ฐ•์Šค ์„ ํƒ/ํ•ด์ œ - [ ] ์ •๋ ฌ ๊ธฐ๋Šฅ (์žˆ๋Š” ๊ฒฝ์šฐ) - [ ] ํ•„ํ„ฐ๋ง ๋™์ž‘ - [ ] ํŽ˜์ด์ง€๋„ค์ด์…˜ - [ ] ํ–‰ ํด๋ฆญ ์ด๋ฒคํŠธ - [ ] ํŽธ์ง‘/์‚ญ์ œ ๋ฒ„ํŠผ - [ ] ๋ฐ˜์‘ํ˜• ๋ ˆ์ด์•„์›ƒ - [ ] Flutter Analyze ์—๋Ÿฌ 0๊ฐœ ### ๐Ÿ“š ShadTable ์‚ฌ์šฉ ํŒจํ„ด #### **๊ธฐ๋ณธ ๊ตฌ์กฐ** ```dart ShadTable.list( header: [ ShadTableCell.header(child: Text('์ปฌ๋Ÿผ1')), ShadTableCell.header(child: Text('์ปฌ๋Ÿผ2')), ], children: items.map((item) => [ ShadTableCell(child: Text(item.field1)), ShadTableCell(child: Text(item.field2)), ]).toList(), columnSpanExtent: (index) { switch(index) { case 0: return FixedTableSpanExtent(80); case 1: return FlexTableSpanExtent(2); default: return null; } }, onRowTap: (index) => _handleRowClick(items[index]), ) ``` #### **์ฒดํฌ๋ฐ•์Šค ํฌํ•จ** ```dart ShadTable.list( header: [ ShadTableCell.header( child: ShadCheckbox( value: _isAllSelected, onChanged: _onSelectAll, ) ), ShadTableCell.header(child: Text('๋ฐ์ดํ„ฐ')), ], children: items.map((item) => [ ShadTableCell( child: ShadCheckbox( value: _selectedItems.contains(item.id), onChanged: (v) => _onItemSelect(item.id, v), ) ), ShadTableCell(child: Text(item.data)), ]).toList(), ) ``` ### ๐Ÿšจ ๊ธˆ์ง€ ์‚ฌํ•ญ - **StandardDataTable ์‚ฌ์šฉ** โŒ - **์ˆ˜๋™ Row/Column ๊ตฌ์„ฑ** โŒ - **Container + ListView.builder ํŒจํ„ด** โŒ - **์ปค์Šคํ…€ ํ…Œ์ด๋ธ” ์ปดํฌ๋„ŒํŠธ ์ƒ์„ฑ** โŒ - **๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜์ •** โŒ ### โœ… ์™„๋ฃŒ ๊ธฐ์ค€ - ๋ชจ๋“  ํ™”๋ฉด์ด ShadTable ์‚ฌ์šฉ - Flutter Analyze ERROR: 0 - ๊ธฐ๋Šฅ regression ์—†์Œ - ์‹œ๊ฐ์  ์ผ๊ด€์„ฑ 100% --- ## ๐ŸŽฏ ์ž‘์—… ์‹œ์ž‘ ๋ฐฉ๋ฒ• ### Agent ์‚ฌ์šฉ ํ•„์ˆ˜ ```yaml ๋ณต์žกํ•œ_๋ถ„์„: general-purpose agent ์‚ฌ์šฉ UI_๋น„๊ต: agent๋ฅผ ํ†ตํ•œ ํ™”๋ฉด๋ณ„ ์ฐจ์ด์  ๋ถ„์„ ๊ฒ€์ฆ: agent๋ฅผ ํ†ตํ•œ ์™„์„ฑ๋„ ๊ฐ๊ด€์  ํ‰๊ฐ€ ``` ### ๊ฒ€์ฆ ๊ธฐ์ค€ - "์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ์ด ์ฐจ์ด๋ฅผ ๋А๋‚„๊นŒ?" - Equipment List์™€ ์‹œ๊ฐ์ ์œผ๋กœ ๋™์ผํ•œ๊ฐ€? - Typography/Spacing์ด ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜๋Š”๊ฐ€? --- *Document updated: 2025-09-05 - ์‹ค์ œ UI ํ†ต์ผ์„ฑ ์ž‘์—… ๊ณ„ํš ์ˆ˜๋ฆฝ*