Skip to content
ExodazPublic

About

The best open-source, self-hostable personal subscription tracker.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

🇹🇭 ภาษาไทย  |  🇬🇧 English

Zublo

ระบบติดตาม subscription แบบ self-hosted พร้อม AI ที่ใช้งานได้จริง

โอเพนซอร์ส · ใช้ Docker เป็นหลัก · สร้างมาสำหรับคนที่โฮสต์เอง, homelab และคนที่อยากคุมรายจ่ายประจำด้วยตัวเอง

ติดตั้งในไม่กี่นาที · ดูตัวอย่างหน้าจอ · อ่านสถาปัตยกรรม

Apache 2.0 License GitHub stars GitHub issues Docker deployment PocketBase AI built in

Zublo คือแอปติดตาม subscription แบบโอเพนซอร์ส สำหรับคนที่อยากเห็นรายจ่ายประจำทุกอย่างในที่เดียว และอยากเก็บข้อมูลไว้กับตัวเองทั้งหมด ติดตั้งเสร็จได้ในไม่กี่นาที ไม่ต้องเสียทั้งวันหยุด

ในแอปมี:

  • หน้าเว็บที่ใช้งานง่าย เห็นรายจ่ายที่เกิดซ้ำทั้งหมด
  • การแจ้งเตือน และมุมมองปฏิทินกับสถิติ
  • การเข้าถึงผ่าน API
  • การติดตั้งด้วย Docker สำหรับคนที่โฮสต์เอง

จุดที่ต่างจากแอปอื่นคือมี AI ในตัว ใช้วิเคราะห์การใช้จ่าย และคุยผ่านแชทได้ เชื่อมต่อผู้ให้บริการ LLM ได้หลายเจ้า ไม่ผูกติดกับเจ้าใดเจ้าหนึ่ง

fork นี้ เพิ่มฟีเจอร์สำหรับคนที่แชร์หรือขายต่อแพ็กเกจ Family:

  • สมาชิกและวันหมดอายุพร้อมแจ้งเตือน
  • โลโก้แบรนด์ และแท็บแยกตาม Service
  • Payment account และหน้าสรุป
  • Export/Import รวมสมาชิก
  • อัตราแลกเปลี่ยนฟรีจาก Frankfurter

ดูรายละเอียดที่ ฟีเจอร์ที่เพิ่มใน fork นี้ และติดตั้งจาก ghcr.io/exodaz/zublo

ทำไม Zublo น่าสนใจ

  • แก้ปัญหาจริง ขอบเขตแคบและใช้งานได้จริง
  • โฮสต์เอง ข้อมูลอยู่ในมือคุณ
  • ติดตั้งง่าย และเข้าใจโค้ดได้ง่าย
  • ใช้ stack ที่กะทัดรัด ไม่ต้องมีโครงสร้างพื้นฐานมากมาย
  • ใช้ประโยชน์ได้ตั้งแต่วันแรก แม้จะไม่เคยแตะโค้ดเลย

ภาพรวม

สิ่งที่สำคัญ ทำไมถึงตอบโจทย์
ทำหน้าที่เดียวให้ดี ติดตามรายจ่ายประจำ โดยไม่กลายเป็นโปรแกรมบัญชีเต็มรูปแบบ
ติดตั้งเร็ว ใช้ Docker ตั้งค่าไม่กี่บรรทัดก็รันได้
เป็นเจ้าของข้อมูลจริง ข้อมูลอยู่บนเซิร์ฟเวอร์ของคุณเอง
AI ที่มีประโยชน์จริง แชท คำแนะนำ และเลือกผู้ให้บริการ AI ได้เอง
สถาปัตยกรรมกะทัดรัด หน้าเว็บ React + PocketBase ไม่มีส่วนเกิน
fork ไปต่อยอดได้ โค้ดเล็กพอจะเข้าใจ และพร้อมให้ขยายต่อ

เหมาะกับใคร

กลุ่มผู้ใช้ ทำไม Zublo ถึงเหมาะ
คนที่โฮสต์เอง container เดียว เก็บข้อมูลด้วย SQLite ไม่ต้องใช้ระบบหนัก ๆ
ผู้ใช้ homelab ใช้ทรัพยากรน้อย สำรองข้อมูลง่าย ต่อกับ reverse proxy ง่าย
คนที่ห่วงความเป็นส่วนตัว ข้อมูล subscription อยู่บนเครื่องของคุณเอง
นักพัฒนาอิสระ โค้ด full-stack กะทัดรัด fork ไปต่อยอดได้จริง
ทีมที่แชร์ค่าใช้จ่าย เห็นค่าใช้จ่ายประจำชัดเจน โดยไม่ต้องใช้โปรแกรมการเงินเต็มรูปแบบ
คนที่แชร์/ขายต่อแพ็กเกจ Family จดสมาชิก ยอดที่แต่ละคนจ่าย และวันหมดอายุ พร้อมแจ้งเตือนก่อนหมด

ตัวอย่างหน้าจอ

แดชบอร์ด Zublo

หน้ารายการ subscription

หน้าปฏิทิน

หน้าสถิติ

หน้าแชท

ฟีเจอร์ทั้งหมด

ส่วน สิ่งที่ได้
Subscription รอบการเรียกเก็บเงิน, วันครบกำหนด, ข้อมูลการชำระเงิน, ประวัติการเปลี่ยนแปลงพร้อมยอดใช้จ่ายรวม
หน้าสรุป Subscription คลิก subscription ใดก็ได้เพื่อดูสรุปในหน้าเดียว: ค่าใช้จ่ายต่อรอบ/เดือน/ปี, รอบบิล, บัญชีที่ชำระ, สมาชิก, โน้ต
สมาชิกในครอบครัว (Family Sharing) คนที่แชร์ subscription แต่ละตัว: ชื่อ, อีเมล, ยอดที่จ่าย, วันหมดอายุ
แจ้งเตือนวันหมดอายุ แจ้งเตือนก่อนสมาชิกหมดอายุ ผ่านช่องทางเดียวกับแจ้งเตือนค่าบริการ
Service และโลโก้แบรนด์ 48 บริการยอดนิยม (Netflix, YouTube, Spotify, Prime Video, HBO Max, Microsoft 365 …) และค้นหาแบรนด์อื่นผ่าน Brandfetch พร้อมโลโก้
แท็บ Service และการจัดกลุ่ม แท็บแยกตาม Service (MS365, Netflix, Spotify …) สร้างอัตโนมัติจาก Service หรือ URL ของแต่ละรายการ และโหมดจัดกลุ่มที่แสดงจำนวน ค่าใช้จ่ายต่อปี และจำนวนสมาชิกของแต่ละ Service
Payment account บันทึกว่า subscription เรียกเก็บเงินจากบัญชีไหน เช่น Apple ID
Export / Import สำรองและกู้คืนข้อมูลครบถ้วนเป็น JSON หรือ Excel รวมสมาชิก และนำเข้าไฟล์จาก Wallos ได้
ปฏิทิน แสดงวันชำระเงินและวันหมดอายุของสมาชิก
แดชบอร์ด ภาพรวมค่าใช้จ่ายและตัวเลขสรุป
สถิติ แยกค่าใช้จ่ายตามหมวดและดูแนวโน้ม
กระเป๋าเครดิต (App Store Credit) บันทึกการเติมเงินต่อ Apple ID ประมาณยอดคงเหลือ วันที่เครดิตจะหมด และแจ้งเตือนก่อนหมด
สกุลเงิน รองรับหลายสกุลเงิน อัปเดตอัตราแลกเปลี่ยนจาก Frankfurter (ฟรี ไม่ต้องใช้ API key รองรับกว่า 200 สกุล), Fixer.io หรือ APILayer
API ใช้งาน REST ผ่าน API key ที่กำหนดขอบเขตได้
AI แชท คำแนะนำ และเลือกผู้ให้บริการได้
การยืนยันตัวตน 2FA แบบ TOTP
การติดตั้ง แอปเดียวแบบ self-hosted ด้วย Docker

ฟีเจอร์ที่เพิ่มใน fork นี้

fork นี้ต่อยอด Zublo ให้เหมาะกับคนที่แชร์หรือขายต่อแพ็กเกจแบบ Family เช่น Microsoft 365 Family, Spotify Family หรือ YouTube Premium Family ที่หารกันหลายคน ต้องจดว่าใครจ่ายเท่าไหร่ และใครใกล้หมดอายุ

# ฟีเจอร์ อยู่ตรงไหน เวอร์ชัน
1 สมาชิกในครอบครัว ปุ่ม Members บนการ์ด 0.7.0-family.1
2 แจ้งเตือนสมาชิกใกล้หมดอายุ ทำงานอัตโนมัติ 0.7.0-family.1
3 วันหมดอายุในปฏิทิน หน้า Calendar 0.7.0-family.1
4 Service และโลโก้แบรนด์ ฟอร์ม subscription 0.7.0-family.1
5 Payment account ฟอร์ม subscription 0.7.0-family.1
6 หน้าสรุป Subscription คลิกที่การ์ด 0.7.0-family.1
7 Export, Import และลบหลายรายการ ปุ่มบนหน้า Subscriptions 0.7.0-family.2 / .6
8 อัตราแลกเปลี่ยนจาก Frankfurter Settings → Exchange Rate API 0.7.0-family.3
9 แท็บ Service และการจัดกลุ่ม ด้านบนหน้า Subscriptions 0.7.0-family.4
10 รับชำระเงินสมาชิก (สลิป + ต่ออายุ) ปุ่ม 💵 ในหน้าสมาชิก 0.8.0
11 หน้าสมาชิกและรายรับ เมนู Members & Income 0.8.0
12 App Store Credit / กระเป๋าเครดิต เมนู Credit 0.9.0
13 สกุลเงินของบริการและสมาชิก, รอบการจ่ายของสมาชิก การ์ด, Select, Settings → Currencies, หน้าสมาชิก 0.10.0

1. สมาชิกในครอบครัว (Family Sharing)

บันทึกว่า subscription แต่ละตัวแชร์กับใครบ้าง

  • กดปุ่ม Members (ไอคอนรูปคน) บนการ์ด หรือปุ่ม "จัดการสมาชิก" ในหน้าสรุป
  • เพิ่ม แก้ไข หรือลบสมาชิกได้ แต่ละคนมีข้อมูล:
ข้อมูล จำเป็นไหม หมายเหตุ
ชื่อ จำเป็น ใส่อีเมลเป็นชื่อก็ได้
อีเมล ไม่บังคับ ในหน้าสมาชิกกดเพื่อส่งอีเมลได้
รอบการจ่าย ไม่บังคับ รายเดือน / 6 เดือน / รายปี หรือกำหนดจำนวนเดือนเอง
ยอดต่อรอบ ไม่บังคับ ยอดที่สมาชิกจ่ายต่อ 1 รอบ ในสกุลเงินที่สมาชิกจ่าย (ดูข้อ 13) ใช้แสดงยอดรวมที่เก็บได้เท่านั้น ไม่นับรวมในสถิติค่าใช้จ่าย
วันหมดอายุ ไม่บังคับ ถ้าเว้นว่าง ถือว่าไม่มีวันหมด
โน้ต ไม่บังคับ เช่น ช่องทางที่โอนเงินมา
  • สมาชิกแต่ละคนมีป้ายสถานะ:
    • 🟢 Active: ยังไม่หมดอายุ
    • 🟡 เหลือ N วัน / หมดวันนี้: หมดภายใน 7 วัน
    • 🔴 Expired: หมดอายุแล้ว
  • บนการ์ดมีตัวเลขจำนวนสมาชิก สีตามสมาชิกที่สถานะน่าห่วงที่สุดในกลุ่ม
  • ลบ subscription แล้ว สมาชิกของ subscription นั้นถูกลบตามไปด้วย

2. แจ้งเตือนสมาชิกใกล้หมดอายุ

  • ระบบตรวจทุกชั่วโมง และส่งแจ้งเตือนเมื่อสมาชิกใกล้หมดอายุ
  • ใช้จำนวนวันล่วงหน้าและเวลาเดียวกับที่ตั้งไว้ใน Settings → Notifications
  • ส่งผ่านช่องทางเดิมทั้งหมด (อีเมล, Telegram, Discord, Gotify, ntfy, webhook ฯลฯ)
  • ข้อความบอกชื่อ อีเมล subscription และวันหมดอายุของแต่ละคน
  • แจ้งเตือนเดิมไม่ส่งซ้ำในวันเดียวกัน
  • ไม่ส่งแจ้งเตือนของ subscription ที่เป็น Inactive

3. วันหมดอายุของสมาชิกในปฏิทิน

  • หน้า Calendar แสดงวันหมดอายุของสมาชิกเป็นป้ายสีฟ้าเส้นประ คู่กับวันชำระเงิน
  • วันหมดอายุไม่นับรวมในยอดชำระของวันหรือของเดือน
  • กดที่วันเพื่อดูรายชื่อสมาชิกที่หมดวันนั้นในส่วน "Member expiries"
  • กดที่ชื่อสมาชิกเพื่อเปิดหน้าจัดการสมาชิก (เช่น ต่ออายุ) ได้ทันที

4. Service และโลโก้แบรนด์

  • ช่อง Service อยู่บนสุดของฟอร์ม subscription เลือกได้ 3 แบบ:
    1. บริการสำเร็จรูป 48 ตัว เช่น Netflix, YouTube Premium, Spotify, Prime Video, HBO Max, Disney+, Microsoft 365, Google One, iCloud+, ChatGPT, Claude, Canva, Viu, WeTV, TrueID, JOOX
    2. ค้นหาจาก Brandfetch พิมพ์ชื่อแบรนด์ใดก็ได้ ผลค้นหาแสดงต่อจากรายการสำเร็จรูป
    3. พิมพ์โดเมนเอง เช่น canva.com แล้วเลือก "Use canva.com"
  • เลือกแล้วระบบกรอกชื่อและ URL ให้ถ้ายังว่าง และตั้งโลโก้ให้อัตโนมัติ
  • ส่วน Logo ในฟอร์มแสดงตัวอย่างโลโก้จาก Brandfetch ถ้าต้องการรูปอื่น ค้นหาหรืออัปโหลดเองได้
  • ลำดับที่ใช้เลือกโลโก้:
    1. โลโก้ที่อัปโหลดเอง
    2. Service ที่เลือก
    3. โดเมนใน URL ของ subscription (รายการเก่าจึงได้โลโก้อัตโนมัติ)
    4. ตัวอักษรแรกของชื่อ
  • โลโก้แสดงบนการ์ด (ทั้ง Grid และ List), หน้าสรุป, ปฏิทิน และแดชบอร์ด
  • เงื่อนไขของ Brandfetch:
    • ต้องโหลดรูปจาก CDN ของ Brandfetch โดยตรง (hotlink) Zublo จึงเก็บแค่โดเมน ไม่ดาวน์โหลดรูปมาเก็บ
    • ต้องตั้งค่า BRANDFETCH_CLIENT_ID (ดู การตั้งค่า) ถ้าไม่ตั้ง จะแสดงเป็นตัวอักษรแทน และค้นหาจาก Brandfetch ไม่ได้

5. Payment account

  • ช่อง Payment account ในฟอร์ม ใช้บันทึกว่า subscription เรียกเก็บเงินจากบัญชีไหน เช่น Apple ID หรือบัญชี Google ที่ใช้สมัคร
  • เป็นข้อความอิสระ แยกจาก Payment method (Visa, PayPal …) ที่บอกว่าจ่ายด้วยอะไร
  • แสดงบนการ์ดข้างไอคอนวิธีชำระเงิน อีเมลที่ยาวจะถูกย่อ ชี้เมาส์เพื่อดูเต็ม

6. หน้าสรุป Subscription

คลิกที่ใดก็ได้บนการ์ด subscription (หรือกด Enter เมื่อเลือกการ์ดด้วยคีย์บอร์ด) เพื่อเปิดหน้าสรุป ซึ่งมี:

ส่วน รายละเอียด
หัวข้อ โลโก้, ชื่อ, หมวดหมู่, สถานะ Active/Inactive
ค่าใช้จ่าย ราคาต่อรอบ, ต่อเดือน, ต่อปี และยอดที่จ่ายไปแล้วทั้งหมด
รอบบิล วันชำระถัดไป (อีกกี่วัน), วันเริ่ม, ต่ออายุอัตโนมัติ, จำนวนงวด/วันสิ้นสุด, วันยกเลิก, การแจ้งเตือน
การชำระเงิน สกุลเงิน, วิธีชำระเงิน, Payment account, ผู้จ่าย
สมาชิก จำนวนสมาชิก, ยอดรวมที่เก็บได้, รายชื่อพร้อมสถานะวันหมดอายุ
โน้ต URL (กดเปิดได้) และโน้ตทั้งหมด

ด้านล่างมีปุ่ม ประวัติ, จัดการสมาชิก และ แก้ไข ปุ่มต่าง ๆ บนการ์ดยังทำงานตามปกติ ไม่เปิดหน้าสรุป

7. Export และ Import

ปุ่ม Export และ Import อยู่ในหน้า Subscriptions ใช้สำรองข้อมูล หรือย้ายข้อมูลระหว่างบัญชี/เครื่อง ข้อมูลที่ export ออกมามี:

  • ทุกฟิลด์: ราคา, รอบบิล, วันที่ต่าง ๆ, จำนวนงวด, การแจ้งเตือน, auto mark paid, โน้ต, URL
  • Service (โดเมนแบรนด์) และ Payment account
  • หมวดหมู่, วิธีชำระเงิน และผู้จ่าย (อ้างอิงด้วยชื่อ)
  • สมาชิกในครอบครัวทั้งหมด
รูปแบบ ได้อะไร Import กลับได้
JSON ไฟล์เดียว { "format": "zublo", "version": 2, "subscriptions": [...] } สมาชิกซ้อนอยู่ในแต่ละ subscription ✓
Excel (.xlsx) 2 ชีต: Subscriptions และ Members ผูกกันด้วยคอลัมน์ subscription_id ✓ แก้ใน Excel แล้ว import กลับได้
Wallos JSON ไฟล์ export จาก Wallos ✓

การ import ทำงานแบบนี้ (ตั้งแต่ 0.7.0-family.6 อัปเดตข้อมูลเดิมได้):

  • จับคู่ subscription เดิม:
    • ใช้ id ในไฟล์ก่อน (ไฟล์ที่ export จากระบบเดียวกัน)
    • ถ้าไม่มี id ใช้ชื่อ ไม่สนตัวพิมพ์เล็ก-ใหญ่
    • ถ้าไม่เจอทั้งสองแบบ จะสร้างใหม่
    • import ไฟล์เดิมซ้ำจึงไม่เกิดข้อมูลซ้ำ
  • แก้บางช่องได้: ช่องที่ไม่มีในไฟล์ใช้ค่าเดิม เช่น ไฟล์ที่มีแค่ name กับ price จะเปลี่ยนแค่ราคา ส่วนช่องที่มีแต่เว้นว่างถือว่าต้องการล้างค่า
  • สมาชิกรวมกับของเดิม:
    • จับคู่สมาชิกด้วยอีเมล ถ้าไม่มีอีเมลใช้ชื่อ
    • คนที่มีอยู่แล้วจะอัปเดตยอดจ่าย วันหมดอายุ และโน้ต คนใหม่จะถูกเพิ่ม
    • คนที่ไม่มีในไฟล์ไม่ถูกลบ
    • ถ้าไฟล์ไม่มีคอลัมน์สมาชิกเลย สมาชิกเดิมไม่ถูกแตะ
  • การเปลี่ยนราคา รอบบิล หรือสกุลเงิน ถูกบันทึกในประวัติ (History) อัตโนมัติ
  • หลัง import มีข้อความบอกจำนวนที่เพิ่มใหม่ อัปเดต และข้าม รวมถึงสมาชิกที่เพิ่ม/อัปเดต
  • ไฟล์จาก Wallos จะถูกเพิ่มใหม่เสมอ
  • หมวดหมู่, วิธีชำระเงิน และผู้จ่าย จับคู่ด้วยชื่อ ถ้ายังไม่มีระบบสร้างให้
  • สกุลเงินจับคู่ด้วยรหัส (เช่น THB) ถ้าไม่พบจะใช้สกุลเงินหลักของคุณ
  • ไฟล์ export จาก Zublo เวอร์ชันเก่า ก็ยัง import ได้

ลบหลายรายการพร้อมกัน

  1. กดปุ่ม Select บนแถบเครื่องมือ
  2. ติ๊กเลือก subscription ที่ต้องการ (หรือกดที่การ์ด) ใช้ Select all เพื่อเลือกทุกรายการที่แสดงอยู่ (ตามช่องค้นหา ตัวกรอง และแท็บ Service) หรือกด Clear เพื่อยกเลิกการเลือก
  3. กด Delete selected แล้วยืนยัน สมาชิกและประวัติของรายการที่ลบจะถูกลบตามไปด้วย

8. อัตราแลกเปลี่ยนจาก Frankfurter

  • ไปที่ Settings → Exchange Rate API แล้วเลือก Frankfurter (free, no API key) จากนั้นกด Save ก็ใช้งานได้ทันที
    • เป็นค่าเริ่มต้นสำหรับผู้ใช้ใหม่
    • ใช้ได้ฟรี ไม่ต้องสมัคร ไม่ต้องใช้ API key
    • ใช้อัตราอ้างอิงรายวันจากธนาคารกลาง รองรับกว่า 200 สกุลเงิน รวมถึง THB
  • อัปเดตอัตโนมัติวันละ 2 ครั้ง (เที่ยงคืนและเที่ยงวัน) หรือกด Update exchange เพื่ออัปเดตทันที
  • เปลี่ยนสกุลเงินหลักแล้ว อัตราจะอัปเดตใหม่อัตโนมัติ
  • ยังเลือกใช้ Fixer.io หรือ APILayer (ต้องมี API key) ได้เหมือนเดิม และ API key ที่เคยบันทึกไว้ไม่หายเมื่อสลับไปมา

9. แท็บ Service และการจัดกลุ่ม

  • ด้านบนหน้า Subscriptions มีแท็บแยกตาม Service เช่น [All 50] [Microsoft 365 49] [Google Gemini 1] พร้อมโลโก้และจำนวน
    • แท็บสร้างอัตโนมัติจาก Service ที่เลือกไว้ หรือโดเมนใน URL
    • รายการที่ไม่มีทั้งสองอย่างอยู่ในแท็บ Other
  • กดแท็บเพื่อดูเฉพาะ Service นั้น ใช้ร่วมกับช่องค้นหาและตัวกรองเดิมได้
  • ปุ่ม Group by service จัดการ์ดเป็นกลุ่มตาม Service หัวข้อของแต่ละกลุ่มแสดง:
    • โลโก้และชื่อ Service
    • จำนวนรายการ
    • ค่าใช้จ่ายต่อปี (แปลงเป็นสกุลเงินหลัก นับเฉพาะรายจ่ายที่ Active)
    • จำนวนสมาชิกรวม
  • ระบบจำการเลือกโหมดจัดกลุ่มไว้ในเบราว์เซอร์

10. รับชำระเงินสมาชิก

บันทึกการชำระเงินของสมาชิกแต่ละคน พร้อมสลิป แล้วต่ออายุให้อัตโนมัติ เช่น สมาชิก A1 (test1@email.com) ในกลุ่ม X1

  1. เปิดหน้า Members ของ subscription แล้วกดปุ่ม 💵 Record payment ที่แถวของสมาชิก
  2. กรอก:
    • วันที่ชำระ (ค่าเริ่มต้นคือวันนี้)
    • ยอดเงิน
    • ระยะเวลา: 1 เดือน / 1 ปี / กำหนดเอง (กี่เดือน)
    • สลิป: แนบรูปหรือ PDF หรือ วางลิงก์สลิป (เช่น ลิงก์รูปจาก LINE หรือ Google Drive) ไม่บังคับ รับเฉพาะลิงก์ที่ขึ้นต้นด้วย http:// หรือ https://
    • โน้ต
  3. ระบบคำนวณ วันหมดอายุใหม่ ให้ทันที:
    • ถ้ามีวันหมดอายุเดิม จะต่อจากวันนั้น เช่น หมด 14/03/2027 ต่อ 1 ปี → 14/03/2028
    • ถ้ายังไม่มีวันหมดอายุ จะนับจากวันที่ชำระ
    • วันสิ้นเดือนปรับให้ถูกต้อง เช่น 31/01 + 1 เดือน = 28/02 หรือ 29/02 ในปีอธิกสุรทิน
    • แก้วันหมดอายุเองได้ และกด "Recalculate" เพื่อกลับไปใช้ค่าที่คำนวณ
  4. กด Save payment แล้ววันหมดอายุของสมาชิกจะอัปเดต ระบบจำระยะเวลาที่เลือกไว้ใช้ครั้งต่อไป

ประวัติการชำระ

  • แต่ละรายการแสดง วันที่ชำระ, ยอด, ระยะเวลา, วันหมดอายุเดิม → ใหม่, โน้ต และปุ่มเปิดสลิป
  • แถวสมาชิกแสดง "Paid DD-MM-YY" ของการชำระล่าสุด
  • ลบรายการล่าสุด: วันหมดอายุของสมาชิกกลับเป็นค่าก่อนหน้า
  • ลบรายการเก่ากว่า: วันหมดอายุไม่เปลี่ยน
  • แก้ไขรายการไม่ได้: ถ้าบันทึกผิดให้ลบแล้วบันทึกใหม่ ประวัติจึงตรงกับความจริงเสมอ

สลิปเก็บแบบป้องกัน

  • เปิดดูได้เฉพาะเจ้าของบัญชีที่ login อยู่ ผ่าน token ชั่วคราว
  • ลิงก์ไฟล์ตรง ๆ หรือผู้ใช้อื่นเปิดไม่ได้ เหมาะกับข้อมูลการเงินตาม PDPA
  • ลบสมาชิกแล้ว ประวัติการชำระและสลิปจะถูกลบตามไปด้วย

การชำระเงินและสลิปยังไม่รวมอยู่ในไฟล์ Export/Import

11. หน้าสมาชิกและรายรับ

เมนู Members & Income (ไอคอนกระเป๋าเงิน) รวมรายรับจากสมาชิกทุกกลุ่ม และสถานะสมาชิกทุกคนไว้ในหน้าเดียว

ช่วงเวลา

  • เปิดมาเห็น เดือนนี้ สลับเป็น ปี หรือ ทั้งหมด ได้
  • กด ‹ › เพื่อดูเดือนหรือปีก่อนหน้า/ถัดไป

การ์ดสรุป

  • รายรับในช่วงเวลา: แปลงเป็นสกุลเงินหลักแล้ว
  • จำนวนการชำระ
  • จำนวนสมาชิกที่ยังใช้งานได้ ใกล้หมด และหมดแล้ว

แท็บ Ledger (สมุดบัญชีรายรับ)

  • การชำระทุกรายการในช่วงเวลานั้น แต่ละรายการแสดง: วันที่, สมาชิก, กลุ่ม (พร้อมโลโก้), ระยะเวลา, ยอด, วันหมดอายุใหม่ และสลิป
  • ด้านล่างมีจำนวนรายการและยอดรวม
  • กดชื่อสมาชิกเพื่อเปิดหน้ารับชำระของคนนั้น ดูประวัติ บันทึกเพิ่ม หรือลบรายการได้

แท็บ Members (ทะเบียนสมาชิก)

  • สมาชิกทุกคนทุกกลุ่ม เรียงคนที่ต้องตามก่อน: หมดแล้ว → ใกล้หมด → ปกติ → ไม่มีวันหมด
  • แต่ละคนแสดง: วันหมดอายุ, สถานะ, วันที่ชำระล่าสุด, ยอดที่เคยจ่ายทั้งหมด และปุ่ม 💵 รับชำระ
  • กรองตามสถานะได้

ตัวกรองและ Export

  • ทั้งสองแท็บกรองตามกลุ่ม และค้นหาชื่อ/อีเมล/กลุ่มได้
  • Export Excel ได้ไฟล์ zublo-income-<ช่วงเวลา>.xlsx มี 2 ชีต ตามตัวกรองที่เลือกอยู่:
    • Ledger: วันที่, สมาชิก, อีเมล, กลุ่ม, ระยะเวลา, ยอด, สกุลเงิน, ยอดในสกุลเงินหลัก, วันหมดอายุก่อน/หลัง, โน้ต, มีสลิปไหม
    • Members

12. App Store Credit / กระเป๋าเครดิต

สำหรับบัญชีที่เติมเงินไว้ล่วงหน้า เช่น App Store Credit ของ Apple ID ที่เติมครั้งละ 1,000–2,000 บาท แล้วถูกหักค่า subscription ทุกเดือน เมนู Credit (ไอคอนกระปุกออมสิน) บอกว่าเหลือเงินเท่าไหร่ และ จะหมดวันไหน

ตั้งค่า

  1. กด Add wallet ใส่ Account ให้ตรงกับช่อง Payment account ของ subscription (เช่น Apple ID) ระบบมีรายการ account ที่ใช้อยู่ให้เลือก
    • ถ้ายังไม่มีกระเป๋า กด Create wallets from payment accounts เพื่อสร้างให้ทุก account ที่ใช้วิธีชำระ App Store Credit ในครั้งเดียว
  2. เลือกสกุลเงินของกระเป๋า (ค่าเริ่มต้นคือสกุลเงินหลัก) ราคาของ subscription สกุลอื่นจะแปลงให้อัตโนมัติ
  3. กด Top up ทุกครั้งที่เติมเงิน

ประมาณการคำนวณอย่างไร

  • subscription ทุกตัวที่ Payment account ตรงกับกระเป๋า (ไม่สนตัวพิมพ์เล็ก/ใหญ่) จะถูกหักตามวันเรียกเก็บจริง (วันชำระถัดไป, รอบบิล, ความถี่) โดยไม่นับรายการที่ปิดใช้งาน ยกเลิก หรือหมดอายุแล้ว
  • ยอดคงเหลือ = ยอดเติม − ค่าบริการที่ถึงกำหนดแล้ว
  • Runs out on คือวันแรกที่ยอดคงเหลือไม่พอจ่ายค่าบริการ บอกด้วยว่าอีกกี่วัน และขาดอีกเท่าไหร่ ถ้าพอใช้เกิน 2 ปีจะขึ้นว่า Enough for 2 years+
  • หน้า Credit แสดงเป็นรายการ 1 แถวต่อ 1 Apple ID: ยอดคงเหลือ, วันที่จะหมด, ค่าใช้จ่ายต่อเดือน และปุ่ม Top up เรียงตัวที่ใกล้หมดที่สุดไว้บนสุด
  • กดที่แถวเพื่อดูรายละเอียด: การเติมครั้งล่าสุด, ค่าบริการ 3 รายการถัดไปพร้อมยอดที่จะเหลือ (รายการที่จ่ายไม่ผ่านเป็นสีแดง), subscription ที่ผูกอยู่ และปุ่มแก้ไข/ลบ
  • สีของยอด: แดง = เหลือไม่ถึง 7 วันหรือหมดแล้ว, ส้ม = ไม่เกิน 30 วัน, เขียว = ปกติ

Set real balance (แนะนำให้ทำเป็นครั้งคราว) ราคาจริงอาจต่างจากที่บันทึกไว้ (ภาษี โปรโมชัน ซื้อของในแอป) ให้เปิดดูยอดใน Settings → Apple ID แล้วกด Set real balance เพื่อบันทึกยอดจริง ระบบจะคำนวณต่อจากยอดนั้น ประวัติการเติมและยอดที่บันทึกดูหรือลบได้ใน History

แจ้งเตือน เปิด Remind me before it runs out ในกระเป๋า (เปิดไว้เป็นค่าเริ่มต้น) ระบบใช้วัน/เวลาแจ้งเตือนเดียวกับใน Settings → Notifications เช่น ตั้งไว้ 3 วัน 8 โมง เมื่อเครดิตจะหมดในอีก 3 วันจะได้ข้อความผ่านทุกช่องทางที่เปิดไว้ (อีเมล Telegram Discord webhook …) เช่น

💳 Zublo — Credit running low · Estimated balance: ฿343 · Runs out in 3 day(s) — 05-12-26: the ฿279 charge for Spotify will fail (short by ฿35).

ส่งครั้งเดียวต่อรอบแจ้งเตือนต่อวัน

13. สกุลเงินของบริการและสมาชิก

เหมาะกับกรณีที่สมัครบริการด้วยสกุลหนึ่ง (เช่น TRY) แต่เก็บเงินสมาชิกอีกสกุล (เช่น THB)

สกุลเงินของบริการ

  • แต่ละ subscription เลือกสกุลเงินได้ที่ช่อง Currency ข้างราคา
  • การ์ดแสดงรหัสสกุลเงินที่เรียกเก็บจริง (เช่น TRY) ใต้ราคาเสมอ ถ้าเปิดแปลงเป็นสกุลเงินหลัก จะแสดงยอดเดิมด้วย เช่น TRY 279.99 ₺
  • เปลี่ยนหลายรายการพร้อมกัน: กด Select เลือก subscription แล้วเลือกสกุลในแถบด้านบน กด Set currency (เปลี่ยนแค่สกุล ไม่แปลงราคา)
  • สกุลเริ่มต้นตอนเพิ่มใหม่: Settings → Currencies → Default for new subscriptions เช่น ตั้งเป็น TRY (ค่าเริ่มต้นคือสกุลเงินหลัก)

สกุลเงินที่สมาชิกจ่าย

  • ในหน้าสมาชิกของแต่ละกลุ่ม เลือก Members pay in (ค่าเริ่มต้นคือสกุลเงินหลัก) ยอดของสมาชิก ยอดรับชำระ หน้า Members & Income และสรุปในปฏิทินจะใช้สกุลนี้
  • ข้อมูลเดิมที่บันทึกไว้ถือเป็นสกุลเงินหลัก

รอบการจ่ายของสมาชิก

  • ในฟอร์มสมาชิกเลือก Billing period: รายเดือน / 6 เดือน / รายปี / กำหนดเอง และใส่ ยอดต่อรอบ
  • รายการสมาชิกแสดงเป็น 80.00 ฿ / month, 450.00 ฿ / 6 months, 900.00 ฿ / year
  • หน้ารับชำระมีปุ่ม 1 เดือน / 6 เดือน / 1 ปี และเลือกรอบของสมาชิกให้อัตโนมัติ ทุกครั้งที่รับชำระ รอบของสมาชิกจะอัปเดตตามรอบที่จ่ายล่าสุด
  • Export/Import เก็บสกุลเงินของสมาชิกและรอบการจ่ายไว้ด้วย

Dashboard: รายจ่ายและรายรับ

  • การ์ดแถวแรก (Total monthly ฯลฯ) คือ รายจ่าย: ราคาจริงของบริการทุกตัว แปลงเป็นสกุลเงินหลักด้วยอัตราแลกเปลี่ยน (เช่น ₺ → ฿) จึงควรตั้งสกุลของบริการให้ตรงกับที่จ่ายจริง และตั้ง Exchange Rate API ให้อัปเดตอัตราอัตโนมัติ
  • เมื่อมีสมาชิก จะมีอีกแถวสำหรับ รายรับจากสมาชิก:
    • Member income / month: ยอดต่อรอบของสมาชิกที่ยังไม่หมดอายุ ÷ จำนวนเดือนของรอบ (ไม่ได้ตั้งรอบ → ใช้รอบบิลของกลุ่ม)
    • Received this month: ยอดที่รับชำระจริงในเดือนนี้
    • Net / month: รายรับจากสมาชิก − รายจ่ายต่อเดือน

ตัวอย่าง: จัดการ Microsoft 365 Family ที่แชร์ 5 คน

  1. Add subscription: ช่อง Service เลือก Microsoft 365 ระบบใส่ชื่อ URL และโลโก้ให้
    • ใส่ราคาต่อปี รอบบิล Yearly และวันชำระถัดไป
    • ช่อง Payment account ใส่ Apple ID ที่ใช้จ่าย
  2. กดปุ่ม Members บนการ์ด แล้วเพิ่มลูกค้าทั้ง 5 คน พร้อมอีเมล ยอดที่จ่าย (เช่น 400) และวันหมดอายุ
  3. ตั้งเวลาแจ้งเตือนใน Settings → Notifications เช่น 7 วันก่อน เวลา 9 โมง ระบบจะเตือนทั้งวันชำระเงินและวันที่ลูกค้าแต่ละคนหมดอายุ
  4. ใช้แท็บ Microsoft 365 และ Group by service เพื่อดูทุกบัญชีพร้อมยอดรวมต่อปี
  5. Export เป็น Excel เพื่อสำรองข้อมูล หรือแก้ไขจำนวนมากแล้ว Import กลับ

ประวัติเวอร์ชัน

เวอร์ชัน (image tag) สิ่งที่เพิ่ม Migration
0.7.0-family.1 สมาชิกในครอบครัว, แจ้งเตือนหมดอายุ, วันหมดอายุในปฏิทิน, Service และโลโก้แบรนด์, Payment account, หน้าสรุป มี (ตารางสมาชิก, brand_domain, payment_account)
0.7.0-family.2 Export/Import เต็มรูปแบบ (รวมสมาชิก, Excel) และแก้ปัญหา import ทำวันเริ่มต้นหาย ไม่มี
0.7.0-family.3 อัตราแลกเปลี่ยนจาก Frankfurter มี (เพิ่มตัวเลือก frankfurter)
0.7.0-family.4 แท็บ Service และการจัดกลุ่มตาม Service ไม่มี
0.7.0-family.5 วิธีชำระเงิน App Store Credit พร้อมโลโก้ App Store มี (เพิ่ม App Store Credit ให้ผู้ใช้เดิม)
0.7.0-family.6 Import อัปเดตข้อมูลเดิมได้ (จับคู่ด้วย id/ชื่อ, รวมสมาชิกและวันหมดอายุ) และลบหลายรายการพร้อมกัน ไม่มี
0.7.0-family.7 สรุปจำนวนสมาชิกที่หมดอายุและยอดต่ออายุของเดือนในหน้าปฏิทิน ไม่มี
0.7.1 แสดงวันที่เป็นรูปแบบ DD-MM-YY ทั้งแอป (image tag 0.7.1, 0.7, latest) ไม่มี
0.7.2 ช่องกรอกวันที่เป็น DD/MM/YYYY ทุกช่อง (วันหมดอายุสมาชิก และวันที่ในฟอร์ม subscription) พร้อมปฏิทินให้เลือก ไม่มี
0.8.0 รับชำระเงินสมาชิก (ยอด สลิป ระยะเวลา ต่ออายุอัตโนมัติ ประวัติ) และหน้า Members & Income (สมุดบัญชีรายรับ ทะเบียนสมาชิก Export Excel) มี (ตาราง member_payments, ช่อง renewal_months)
0.9.0 เมนู Credit: กระเป๋าเครดิต (App Store Credit) บันทึกการเติม/ยอดจริง ประมาณวันที่เครดิตหมด และแจ้งเตือนก่อนหมด มี (ตาราง credit_wallets, credit_entries)
0.10.0 แสดงสกุลเงินบนการ์ด, เปลี่ยนสกุลหลายรายการพร้อมกัน, สกุลเริ่มต้นของ subscription ใหม่, สกุลเงินที่สมาชิกจ่ายต่อกลุ่ม, รอบการจ่ายของสมาชิก (1/6/12 เดือน) มี (ช่อง member_currency, default_currency)
0.11.0 Dashboard แสดงรายรับจากสมาชิก (คาดการณ์ต่อเดือน, รับจริงเดือนนี้) และกำไร/ขาดทุนสุทธิเทียบกับรายจ่าย ไม่มี
0.12.0 บันทึกสลิปเป็นลิงก์ได้ (แทนการแนบไฟล์) เปิดดูได้จากประวัติและ Ledger และ Export Excel ใส่ลิงก์ให้ มี (ช่อง slip_url)

migration ทำงานอัตโนมัติตอนเปิดแอป และข้อมูลเดิมไม่หาย

AI ในตัว

AI ในนี้ไม่ได้ใส่มาแค่ให้มี

Zublo มีระบบ AI ที่ทำงานกับข้อมูล subscription ของคุณได้จริง:

  • คำแนะนำจาก AI ตามข้อมูลการใช้จ่าย
  • หน้าแชทที่เชื่อมกับความสามารถของแอป
  • เลือกใช้ผู้ให้บริการได้หลายเจ้า ไม่ผูกกับเจ้าเดียว
  • ใช้กับโมเดลที่รันในเครื่องหรือโฮสต์เองได้

ผู้ให้บริการที่รองรับ:

  • Google Gemini
  • OpenAI
  • Ollama
  • endpoint ที่เข้ากันได้กับ OpenAI เช่น OpenRouter, Groq, Mistral เป็นต้น

ทำไมโฮสต์เองแล้วสบาย

คุณสมบัติ ในทางปฏิบัติหมายถึง
รันแอปเดียว หน้าเว็บและ backend มาด้วยกัน
เก็บข้อมูลด้วย SQLite สำรองข้อมูลง่าย ดูแลน้อย
ใช้ PocketBase เป็นแกน มีระบบ auth, ข้อมูล และหน้า admin โดยไม่ต้องมี backend ใหญ่
แพ็กมากับ Docker รันได้บน VPS, NAS, mini-PC หรือ homelab
ขอบเขตแคบ ดูแลง่ายกว่าแพลตฟอร์มการเงินทั่วไป

Zublo ไม่ใช่

  • ไม่ใช่โปรแกรมบัญชีเต็มรูปแบบ
  • ไม่ใช่ระบบทำบัญชี (bookkeeping)
  • ไม่ใช่ระบบเชื่อมบัญชีธนาคาร
  • ไม่ใช่ SaaS ที่ต้องใช้บน cloud เท่านั้น

ขอบเขตที่แคบคือความตั้งใจ

Stack

ส่วน เทคโนโลยี
หน้าเว็บ React 18, Vite, TypeScript, TanStack Router, React Query, Tailwind CSS
Backend runtime PocketBase
ส่วนขยาย backend PocketBase JS hooks และ migrations
ฐานข้อมูล SQLite ผ่าน PocketBase
การแพ็ก Docker, Docker Compose, GHCR

ติดตั้งในไม่กี่นาที

Image อยู่บน GitHub Container Registry รองรับทั้ง linux/amd64 และ linux/arm64 (เช่น Raspberry Pi, Mac M-series, NAS ที่ใช้ ARM):

Tag ใช้เมื่อ
ghcr.io/exodaz/zublo:latest ต้องการเวอร์ชันล่าสุดของ fork นี้
ghcr.io/exodaz/zublo:0.7.0-family.1 ต้องการล็อกเวอร์ชัน (แนะนำสำหรับเซิร์ฟเวอร์)

fork นี้เพิ่มฟีเจอร์สมาชิกครอบครัว, Service พร้อมโลโก้แบรนด์, Payment account และหน้าสรุป subscription ส่วน image ต้นฉบับที่ไม่มีฟีเจอร์เหล่านี้คือ ghcr.io/danielalves96/zublo

1. สร้างโฟลเดอร์และไฟล์ .env

mkdir zublo && cd zublo
cat > .env <<'ENV'
PB_ENCRYPTION_KEY=ใส่ข้อความสุ่มยาวๆ
BRANDFETCH_CLIENT_ID=
ENV

สร้างคีย์สุ่มได้ด้วย openssl rand -hex 32 ส่วน BRANDFETCH_CLIENT_ID ไม่บังคับ (ดู การตั้งค่า)

2. สร้างไฟล์ docker-compose.yml

services:
  zublo:
    image: ghcr.io/exodaz/zublo:latest
    container_name: zublo
    restart: unless-stopped
    ports:
      - "9597:9597"
    environment:
      PB_ENCRYPTION_KEY: ${PB_ENCRYPTION_KEY}
      BRANDFETCH_CLIENT_ID: ${BRANDFETCH_CLIENT_ID:-}
    volumes:
      - ./zublo-data:/pb/pb_data

3. เริ่มรัน

docker compose up -d

หรือใช้ Docker อย่างเดียว:

docker run -d --name zublo --restart unless-stopped \
  -p 9597:9597 \
  -e PB_ENCRYPTION_KEY=ใส่ข้อความสุ่มยาวๆ \
  -e BRANDFETCH_CLIENT_ID= \
  -v "$(pwd)/zublo-data:/pb/pb_data" \
  ghcr.io/exodaz/zublo:latest

อัปเดตเวอร์ชัน

docker compose pull && docker compose up -d

ฐานข้อมูลจะ migrate อัตโนมัติตอนเริ่มรัน ควรสำรองโฟลเดอร์ zublo-data ก่อนอัปเดตข้ามเวอร์ชัน

ย้ายมาจาก image ต้นฉบับ

เปลี่ยน image: เป็น ghcr.io/exodaz/zublo:latest แล้วใช้ volume pb_data เดิมได้เลย migration ใหม่แค่เพิ่มคอลัมน์และตาราง ข้อมูลเดิมไม่หาย

จากนั้นเปิด:

  • http://localhost:9597 หน้าแอป
  • http://localhost:9597/_/ หน้า admin ของ PocketBase
  • http://localhost:9597/api/ REST API

ข้อควรรู้:

  • ต้องเก็บ /pb/pb_data ไว้ถาวร (volume หรือ bind mount)
  • ตั้ง PB_ENCRYPTION_KEY เสมอเมื่อใช้งานจริง
  • ผู้ใช้คนแรกที่สมัคร จะเป็น admin คนแรก
  • ตั้ง BRANDFETCH_CLIENT_ID ถ้าต้องการโลโก้แบรนด์ (ไม่บังคับ ดูด้านล่าง)

การตั้งค่า

ตัวแปร จำเป็นไหม ใช้ทำอะไร
PB_ENCRYPTION_KEY แนะนำ เข้ารหัสการตั้งค่าของ PocketBase ที่เก็บไว้ ใช้ค่าสุ่มยาว ๆ ในการใช้งานจริง
BRANDFETCH_CLIENT_ID ไม่บังคับ เปิดใช้โลโก้แบรนด์และการค้นหาแบรนด์ใน Service สมัครฟรีที่ https://developers.brandfetch.com/register (ดูในส่วน Logo API)

เกี่ยวกับ BRANDFETCH_CLIENT_ID:

  • ต้องใช้ Client ID ไม่ใช่ API key Client ID สั้น ขึ้นต้นด้วย 1id… และออกแบบมาให้อยู่ใน URL รูปภาพสาธารณะได้
  • API key เป็นความลับ และใช้กับ CDN โลโก้ไม่ได้
  • แพ็กเกจฟรีใช้ได้ถึง 1 ล้านครั้งต่อเดือน
  • ถ้าใช้ Docker Compose ใส่ค่าในไฟล์ .env ข้าง docker-compose.yml ได้:
PB_ENCRYPTION_KEY=change-me-in-production
BRANDFETCH_CLIENT_ID=1idXXXXXXXXXXXXXXX

ใช้หลัง Reverse Proxy

Zublo เป็น PocketBase process เดียว proxy ใดก็ได้ที่ส่ง HTTP ธรรมดาไปที่พอร์ต 9597 โดยไม่ buffer หรือแก้ไข request body ก็ใช้ได้ ตัวอย่าง Caddy:

zublo.example.com {
    reverse_proxy localhost:9597
}

ถ้าเปิด MFA หรือแก้โปรไฟล์แล้วเจอ error 400 แบบไม่คาดคิด สาเหตุที่พบบ่อยคือ proxy ไป buffer, บีบอัด หรือแก้ request body ให้ตั้ง proxy แบบส่งผ่านตรง ๆ ให้มากที่สุด

พัฒนาในเครื่อง

ถ้าต้องการแก้โค้ด:

bun install
bun run dev

คำสั่งนี้จะเปิด:

  • Vite ที่ http://localhost:5173
  • PocketBase ที่ http://127.0.0.1:8080

ต้องมีไฟล์ PocketBase ที่ apps/backend/pocketbase ไฟล์นี้ไม่ได้อยู่ใน git ให้ดาวน์โหลดเวอร์ชันเดียวกับที่ระบุใน Dockerfile (PB_VERSION) สำหรับเครื่องของคุณได้จาก PocketBase releases

ถ้าต้องการลองโลโก้แบรนด์ในเครื่อง ให้ใส่ Client ID ตอนรัน:

BRANDFETCH_CLIENT_ID=1idXXXXXXXXXXXXXXX bun run dev

รันเทสต์:

bun run test            # หน้าเว็บ + backend
bun run test:coverage   # เหมือนกัน แต่บังคับ coverage 100% แบบเดียวกับ CI
bun run lint

สถาปัตยกรรมโดยย่อ

Zublo ตั้งใจออกแบบให้กะทัดรัด

  • apps/web คือแอป React
  • apps/backend คือ PocketBase hooks, migrations และส่วนที่ทำงานฝั่ง backend
  • หน้าเว็บจะถูก build ไปไว้ที่ apps/backend/pb_public สำหรับใช้งานจริง
  • ตอนใช้งานจริง PocketBase เสิร์ฟทั้ง API และหน้าเว็บ
  • ข้อมูลที่เปลี่ยนแปลงระหว่างใช้งานอยู่ที่ /pb/pb_data

ตอนพัฒนาในเครื่อง:

  • Vite เสิร์ฟหน้าเว็บ
  • PocketBase เสิร์ฟ API
  • Vite ส่งต่อ /api ไปที่ PocketBase

ตอนใช้งานจริง:

  • container เดียวเสิร์ฟทั้งหน้าเว็บและ backend

รายละเอียดสถาปัตยกรรมทั้ง repo ดูที่ ARCHITECTURE.md โครงสร้างฝั่งหน้าเว็บดูที่ apps/web/ARCHITECTURE.md

โครงสร้าง Repository

.
├── apps/
│   ├── backend/   # PocketBase hooks, migrations, runtime assets
│   └── web/       # แอป React
├── scripts/       # เครื่องมือสำหรับผู้ดูแล
├── Dockerfile
├── docker-compose.yml
├── Makefile
├── README.md      # ภาษาไทย (หลัก)
└── README.en.md   # ภาษาอังกฤษ

Repository นี้เหมาะกับใคร

  • คนที่โฮสต์เอง
  • ผู้ใช้ homelab
  • ผู้ร่วมพัฒนาที่อยากได้แอป full-stack เล็ก ๆ ที่เข้าใจง่าย
  • นักพัฒนาที่สนใจผลิตภัณฑ์ที่สร้างบน PocketBase

ทำไมโค้ดยังเข้าใจง่าย

  • หน้าเว็บ React และ backend PocketBase อยู่ใน repo เดียวกัน
  • logic ฝั่ง backend จัดกลุ่มตามหน้าที่ในไฟล์ hook
  • runtime ตอนใช้งานจริงกะทัดรัด เข้าใจง่าย
  • วิธีติดตั้งง่ายพอสำหรับคนดูแลคนเดียว
  • ขอบเขตผลิตภัณฑ์ถูกจำกัดไว้โดยตั้งใจ

ร่วมพัฒนา

Zublo ยังอยู่ระหว่างปรับส่วนที่เปิดเป็นโอเพนซอร์ส การมีส่วนร่วมที่ดีตอนนี้คือสิ่งที่ช่วยให้โค้ดชัดเจนขึ้น เริ่มต้นใช้ง่ายขึ้น ดูแลง่ายขึ้น และเปลี่ยนพฤติกรรมในขอบเขตแคบ ๆ

เริ่มที่:

ผู้ดูแล

Zublo ดูแลโดย Daniel Luiz Alves

GitHub: @danielalves96

License

Zublo ใช้สัญญาอนุญาต Apache License 2.0

Copyright Daniel Luiz Alves

ดู LICENSE และ NOTICE

About

The best open-source, self-hostable personal subscription tracker.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages