# Budget Tracker - ระบบบันทึกรายรับรายจ่ายพร้อม AI ระบบจัดการการเงินส่วนบุคคลแบบ web application ที่ช่วยให้ผู้ใช้สามารถบันทึกรายรับรายจ่าย และใช้ AI ช่วยจัดหมวดหมู่รายการอัตโนมัติ ## 📋 สารบัญ 1. [ภาพรวมโปรเจ็ค](#ภาพรวมโปรเจ็ค) 2. [แนวคิดการออกแบบ](#แนวคิดการออกแบบ) 3. [สถาปัตยกรรมระบบ](#สถาปัตยกรรมระบบ) 4. [ระบบ AI Categorization](#ระบบ-ai-categorization) 5. [Prompt Engineering](#prompt-engineering) 6. [การติดตั้งและใช้งาน](#การติดตั้งและใช้งาน) 7. [โครงสร้างไฟล์](#โครงสร้างไฟล์) 8. [API Documentation](#api-documentation) ## ภาพรวมโปรเจ็ค Budget Tracker เป็นเว็บแอปพลิเคชันสำหรับจัดการการเงินส่วนบุคคล ที่มีจุดเด่นหลักคือการใช้ AI ช่วยจัดหมวดหมู่รายการรายรับรายจ่ายอัตโนมัติ ### ฟีเจอร์หลัก - 📝 บันทึกรายรับรายจ่ายแบบ real-time - 🤖 AI จัดหมวดหมู่อัตโนมัติ (รองรับทั้งรายรับและรายจ่าย) - 📊 สรุปยอดรวม และแสดงยอดคงเหลือ - 🔍 กรองรายการตามวันที่ - 💾 เก็บข้อมูลใน IndexedDB (ทำงานแบบ offline) - 🌐 Responsive design รองรับมือถือ ### เทคโนโลยีที่ใช้ - **Frontend**: HTML5, CSS3, Vanilla JavaScript - **Backend**: PHP 8+ - **Database**: IndexedDB (client-side) - **AI Service**: Google Generative AI (Gemini) - **Web Server**: Apache/Nginx ## แนวคิดการออกแบบ ### 1. User Experience (UX) Design - **Simple First**: ออกแบบให้ใช้งานง่าย โดยไม่ต้องสมัครสมาชิก - **Progressive Enhancement**: เริ่มจากฟีเจอร์พื้นฐาน แล้วค่อยเพิ่ม AI - **Offline-First**: ใช้ IndexedDB เพื่อให้ทำงานได้แม้ไม่มีอินเทอร์เน็ต - **Mobile-Friendly**: ออกแบบ responsive สำหรับการใช้งานบนมือถือ ### 2. Data Flow Design ``` [User Input] → [Form Validation] → [IndexedDB] → [UI Update] ↓ [AI Categorization] ← [Normalize] ← [Filter "อื่นๆ"] ``` ### 3. AI Integration Philosophy - **Human-AI Collaboration**: AI เป็นเครื่องมือช่วย ไม่ใช่ทดแทนการตัดสินใจของมนุษย์ - **Transparency**: แสดง prompt ที่ส่งให้ AI เพื่อให้ผู้ใช้เข้าใจกระบวนการ - **Privacy-Aware**: ส่งเฉพาะคำอธิบายรายการ ไม่ส่งข้อมูลยอดเงินหรือข้อมูลส่วนตัว - **Graceful Degradation**: หาก AI ไม่ทำงาน ระบบยังใช้งานได้ปกติ ### 4. Error Handling Strategy - **Client-Side Validation**: ตรวจสอบข้อมูลก่อนส่ง - **Progressive Error Display**: แสดงข้อผิดพลาดแบบไม่รบกวนผู้ใช้ - **Fallback Mechanisms**: มีทางเลือกเมื่อ AI service ไม่ทำงาน ## สถาปัตยกรรมระบบ ### Frontend Architecture ``` index.html (UI Structure) ├── styles.css (Styling) └── app.js (Business Logic) ├── BudgetTracker Class ├── IndexedDB Management ├── UI Event Handlers └── AI Integration ``` ### Backend Architecture ``` ai_categorize.php ├── Input Validation ├── Google AI API Integration ├── Error Handling └── JSON Response ``` ### Data Architecture ``` IndexedDB: BudgetTrackerDB └── transactions (Object Store) ├── id (auto-increment) ├── type (income/expense) ├── category (หมวดหมู่) ├── description (รายละเอียด) ├── amount (จำนวนเงิน) ├── date (วันที่) └── timestamp (เวลาที่บันทึก) ``` ## ระบบ AI Categorization ### การทำงานของ AI System #### 1. Detection Phase (การตรวจจับรายการที่ต้องจัดหมวด) ```javascript // ตรวจหารายการที่ยังไม่ได้จัดหมวด const uncategorizedIncome = transactions.filter(t => t.type === 'income' && (t.category === 'อื่นๆ' || !t.category) ); const uncategorizedExpenses = transactions.filter(t => t.type === 'expense' && (t.category === 'อื่นๆ' || !t.category) ); ``` #### 2. Normalization Phase (การทำให้ข้อมูลเป็นมาตรฐาน) ```javascript normalizeDescription(desc) { return desc.trim().toLowerCase() .replace(/[^\u0E00-\u0E7Fa-zA-Z0-9\s]/g, '') // เก็บแต่ไทย อังกฤษ ตัวเลข ช่องว่าง .replace(/\s+/g, ' '); // normalize whitespace } ``` **เหตุผลของการ Normalize:** - **ความถูกต้องในการจับคู่**: AI อาจส่งคำตอบที่ normalize แล้ว - **ลดความผิดพลาดจาก case sensitivity**: "ข้าวกล่อง" vs "ข้าวกล่อง " - **กำจัดเครื่องหมายพิเศษ**: ลบ emoji, เครื่องหมายวรรคตอนที่อาจรบกวน #### 3. Categorization Phase (การจัดหมวดหมู่) **แยกการประมวลผลตาม Type:** - ส่งคำขอแยกกันสำหรับ `income` และ `expense` - ใช้ prompt และ category set ที่เฉพาะเจาะจงสำหรับแต่ละประเภท **ข้อดีของการแยกส่ง:** 1. **ความแม่นยำสูงขึ้น**: prompt เฉพาะทางทำให้ AI เข้าใจบริบทดีขึ้น 2. **ความปลอดภัย**: ลดข้อมูลที่ส่งในแต่ละครั้ง 3. **Error Isolation**: หาก expense ล้มเหลว income ยังทำงานได้ 4. **Progress Tracking**: แสดงความคืบหน้าได้ชัดเจน #### 4. Mapping Phase (การแมปผลลัพธ์) ```javascript // สำหรับรายจ่าย const expenseCategoryMap = { 'Food': 'อาหาร', 'Transport': 'เดินทาง', 'Entertainment': 'บันเทิง' }; // สำหรับรายรับ const incomeCategoryMap = { 'Salary': 'เงินเดือน', 'Bonus': 'โบนัส', 'SideIncome': 'รายได้เสริม', 'Gift': 'ของขวัญ' }; ``` ## Prompt Engineering ### หลักการออกแบบ Prompt #### 1. Clear Task Definition - ระบุงานที่ต้องการให้ AI ทำอย่างชัดเจน - กำหนด input format และ output format ที่ต้องการ - ใช้ภาษาที่เข้าใจง่ายและไม่คลุมเครือ #### 2. Constraint Specification - จำกัด category ที่ AI สามารถเลือกได้ - ระบุ output format ที่ต้องการ (JSON) - ป้องกันการสร้าง category ใหม่โดยไม่ได้รับอนุญาต #### 3. Context Provision - บอกว่าข้อมูลเป็นภาษาไทย - ระบุประเภทของรายการ (รายรับ/รายจ่าย) ### Prompt Templates #### สำหรับรายจ่าย (Expense) ``` Categorize these Thai expenses into Food, Transport, Entertainment: {expense_list}. Return only a JSON object with format: {"item1": "category", "item2": "category"}. Use only these categories: Food, Transport, Entertainment. ``` **การวิเคราะห์ Prompt:** - **"Thai expenses"**: บอกภาษาและประเภทข้อมูล - **"into Food, Transport, Entertainment"**: จำกัดทางเลือก - **"Return only a JSON object"**: กำหนด output format - **"Use only these categories"**: เน้นย้ำข้อจำกัด #### สำหรับรายรับ (Income) ``` Categorize these Thai income sources into Salary, Bonus, SideIncome, Gift: {income_list}. Return only a JSON object with format: {"item1": "category", "item2": "category"}. Use only these categories: Salary, Bonus, SideIncome, Gift. ``` **เหตุผลการเลือก Categories:** **รายจ่าย:** - **Food**: ครอบคลุมอาหาร เครื่องดื่ม (รวมถึงเหล้า) - **Transport**: รถ แท็กซี่ รถเมล์ น้ำมัน - **Entertainment**: ความบันเทิง โรงหนัง เกม **รายรับ:** - **Salary**: เงินเดือน ค่าจ้างประจำ - **Bonus**: โบนัส เงินรางวัล - **SideIncome**: รายได้เสริม ขายของ งานพิเศษ - **Gift**: ของขวัญ เงินให้ ### Prompt Optimization Techniques #### 1. Response Format Control ``` "Return only a JSON object with format: {...}" ``` - ป้องกัน AI ส่งข้อความอธิบายเพิ่มเติม - ทำให้ parsing ง่ายขึ้น #### 2. Category Restriction ``` "Use only these categories: ..." ``` - ป้องกันการสร้าง category ใหม่ - รับประกันความสอดคล้องกับระบบ #### 3. Language Specification ``` "Categorize these Thai..." ``` - ช่วยให้ AI เข้าใจบริบทภาษา - ปรับปรุงความแม่นยำสำหรับข้อความภาษาไทย #### 4. Input Validation ```javascript // ตรวจสอบผลลัพธ์จาก AI if (expenseResult.success && expenseResult.categories) { // ตรวจสอบว่า category ที่ได้เป็น valid category if (aiCategory && expenseCategoryMap[aiCategory]) { // อัปเดตเฉพาะเมื่อ valid เท่านั้น } } ``` ### Error Handling in Prompts #### 1. Malformed Response - ใช้ regex ดึง JSON object จาก response ที่อาจมี markdown - มี fallback parsing เมื่อ JSON.parse() ล้มเหลว #### 2. Invalid Categories - ตรวจสอบว่า category ที่ AI ส่งมาอยู่ใน mapping table - ข้ามรายการที่ไม่สามารถแมปได้ #### 3. Partial Success - รายงานจำนวนรายการที่จัดสำเร็จ เทียบกับรายการทั้งหมด - ไม่ถือว่าล้มเหลวทั้งหมดเมื่อจัดได้เพียงบางรายการ - กรอก "จำนวนเงิน" - เลือก "วันที่" - คลิก "เพิ่มรายการ" ### 2. ดูสรุปการเงิน - รายรับรวม - รายจ่ายรวม - ยอดคงเหลือ ### 3. จัดหมวดหมู่ด้วย AI - เพิ่มรายการโดยเลือกหมวดหมู่เป็น "อื่นๆ" - คลิกปุ่ม "จัดหมวดหมู่รายการที่ยังไม่ได้จัด" - AI จะจัดหมวดหมู่รายการอัตโนมัติเป็น: - อาหาร (Food) - เดินทาง (Transport) - บันเทิง (Entertainment) ### 4. กรองรายการตามวันที่ - ใช้ช่อง "กรองตามวันที่" ในส่วนรายการ - เลือกวันที่ที่ต้องการดู ## คุณสมบัติ ### ✅ ฟีเจอร์หลัก - เพิ่ม/ลบ/แก้ไขรายการรายรับ-รายจ่าย - จัดหมวดหมู่อัตโนมัติด้วย Google AI - สรุปการเงินแบบเรียลไทม์ - เก็บข้อมูลใน IndexedDB (ไม่ต้องใช้ฐานข้อมูล) - Responsive Design ใช้งานได้บนมือถือ - กรองรายการตามวันที่ ### 📱 การรองรับอุปกรณ์ - Desktop (Chrome, Firefox, Safari, Edge) - Mobile (iOS Safari, Chrome Mobile, Firefox Mobile) - Tablet ### 🔐 ความปลอดภัย - ข้อมูลเก็บใน IndexedDB ในเครื่องผู้ใช้ - API Key ถูกซ่อนไว้ใน Server-side PHP - ไม่มีการส่งข้อมูลส่วนตัวไปยัง AI (ส่งเฉพาะชื่อรายการ) ## การแก้ไขปัญหา ### ปัญหา: AI ไม่ทำงาน ``` เหตุผลที่เป็นไปได้: 1. API Key ไม่ถูกต้อง 2. ไฟล์ PHP ไม่สามารถเข้าถึงอินเทอร์เน็ต 3. cURL extension ไม่ได้ติดตั้ง 4. Google AI API มีปัญหา การแก้ไข: 1. ตรวจสอบ API Key 2. ตรวจสอบ Network connectivity 3. ติดตั้ง php-curl extension 4. ดู Error Log ของเว็บเซิร์ฟเวอร์ ``` ### ปัญหา: ข้อมูลหาย ``` เหตุผล: Browser cache ถูกล้าง การแก้ไข: ข้อมูลจะสูญหายถาวร เพราะเก็บใน IndexedDB แนะนำ: Export ข้อมูลก่อนล้าง cache (ฟีเจอร์นี้จะเพิ่มในอนาคต) ``` ### ปัญหา: หน้าเว็บไม่แสดง ``` เหตุผล: ไฟล์ HTML ไม่ถูกต้อง การแก้ไข: ตรวจสอบไฟล์ index.html และ path ของไฟล์ ``` ## การพัฒนาเพิ่มเติม ### เพิ่มหมวดหมู่ใหม่ แก้ไขใน JavaScript ส่วน `categories`: ```javascript this.categories = { income: ['เงินเดือน', 'โบนัส', 'รายได้เสริม', 'หมวดหมู่ใหม่'], expense: ['อาหาร', 'เดินทาง', 'บันเทิง', 'หมวดหมู่ใหม่'] }; ``` ### เปลี่ยนภาษา AI Prompt แก้ไขใน `categorizeWithAI()` function: ```javascript prompt: `Categorize this list of expenses into หมวดใหม่1, หมวดใหม่2: ${expenseList}` ``` ## ข้อจำกัด ### Google AI Studio API - ฟรี: 15 requests/minute, 1,500 requests/day - ต้องการอินเทอร์เน็ตในการจัดหมวดหมู่ - รองรับเฉพาะภาษาอังกฤษในการจัดหมวดหมู่ ### IndexedDB - ข้อมูลเก็บในเครื่องผู้ใช้เท่านั้น - ข้อมูลจะหายถ้าล้าง Browser cache - ไม่สามารถ Sync ข้ามอุปกรณ์ ## การอัปเกรดในอนาคต - [ ] Export/Import ข้อมูลเป็น CSV - [ ] รายงานแบบกราฟ - [ ] การตั้งงบประมาณ - [ ] แจ้งเตือนเมื่อใกล้เกินงบ - [ ] Multi-currency support - [ ] Cloud sync --- **หมายเหตุ:** แอปนี้ใช้ API ฟรีของ Google AI Studio ซึ่งมีขีดจำกัดการใช้งาน หากต้องการใช้งานจริงในระดับ Production ควรพิจารณาอัปเกรดแพลน ## การติดตั้งและการกำหนดค่า GOOGLE_AI_API_KEY (Installation & Configuration) ด้านล่างเป็นคำอธิบายการติดตั้งเว็บเซิร์ฟเวอร์ และการกำหนดค่า `GOOGLE_AI_API_KEY` อย่างปลอดภัย ### 1) ติดตั้งเว็บเซิร์ฟเวอร์และ PHP - ติดตั้ง Apache หรือ Nginx และ PHP 8+ พร้อม extension ที่จำเป็น (เช่น curl) - ตัวอย่างบน Ubuntu/Debian: ``` sudo apt update sudo apt install -y apache2 php php-curl php-xml ``` ปรับแต่งให้ DocumentRoot ชี้ไปที่โฟลเดอร์โปรเจ็ค (`/var/www/html` หรือ path ที่คุณใช้) ### 2) รับ GOOGLE_AI_API_KEY จาก Google Cloud 1. เข้าไปที่ Google Cloud Console: https://console.cloud.google.com/ 2. เลือกหรือสร้างโปรเจ็คใหม่ 3. เปิดใช้งานบริการ Generative AI (หรือ API ที่เกี่ยวข้อง) ตามเอกสารของ Google Cloud 4. ไปที่เมนู "APIs & Services" → "Credentials" 5. คลิก "Create credentials" → "API key" 6. คัดลอก API key และเก็บไว้ในที่ปลอดภัย > หมายเหตุ: ชื่อเมนูหรือขั้นตอนใน Console อาจเปลี่ยนแปลงได้ตาม UI ของ Google Cloud ให้ดูเอกสารอย่างเป็นทางการกรณีสงสัย ### 3) กำหนดค่าคีย์อย่างปลอดภัย (แนะนำ) ไม่ควรเก็บ API Key ไว้ในซอร์สโค้ดโดยตรง ให้ใช้วิธีเก็บใน Environment Variables หรือไฟล์คอนฟิกที่ไม่ถูกรวมใน git (เช่น `.env` ที่ใส่ใน `.gitignore`) ตัวอย่างการตั้งค่า environment variable (ชั่วคราว ใน shell session): ``` export GOOGLE_AI_API_KEY="YOUR_REAL_API_KEY" ``` สำหรับ Apache (ใส่ใน VirtualHost หรือไฟล์ conf ของไซต์): ``` SetEnv GOOGLE_AI_API_KEY "YOUR_REAL_API_KEY" ``` สำหรับ systemd service ที่รัน PHP backend ให้เพิ่มในไฟล์ unit: ``` Environment=GOOGLE_AI_API_KEY=YOUR_REAL_API_KEY ``` ### 4) วิธีที่ `ai_categorize.php` อ่านค่า (ตัวอย่าง) ไฟล์ `ai_categorize.php` ถูกปรับให้ตรวจสอบตัวแปรสภาพแวดล้อมก่อนใช้ค่าเริ่มต้น ตัวอย่างที่ใช้ในโค้ด: ```php $GOOGLE_AI_API_KEY = getenv('GOOGLE_AI_API_KEY') ?: 'GOOGLE_AI_API_KEY'; ``` หากไม่ได้ตั้งค่า environment variable ไว้ โค้ดจะยังคงใช้ค่า placeholder `GOOGLE_AI_API_KEY` ซึ่งจะไม่สามารถเรียกใช้งานจริงได้ ### 5) การทดสอบหลังตั้งค่า 1. ตั้งค่าตัวแปรสภาพแวดล้อม (หรือ Restart Apache ถ้าใช้ SetEnv) 2. เรียก endpoint `ai_categorize.php` ด้วย POST JSON: ```json { "prompt": "ทดสอบการจัดหมวดหมู่ รายการอาหาร แท็กค่า" } ``` 3. ตรวจสอบว่าตอบกลับ JSON มี `success: true` หรือมี error รายละเอียด ### 6) คำแนะนำด้านความปลอดภัย - อย่า commit API Key ลงใน git - จำกัดการใช้งานของ API Key หากเป็นไปได้ (จำกัดเฉพาะ IP หรือบริการ) - เก็บ log ที่มีข้อมูลสำคัญอย่างระมัดระวัง