# 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 ที่มีข้อมูลสำคัญอย่างระมัดระวัง