🧠 DOMAIN_MODEL.md - Domain Model Specification (āļ‚āđ‰āļ­āļĄāļđāļĨāļˆāļģāļĨāļ­āļ‡āđ‚āļ”āđ€āļĄāļ™)

This document defines the core business entities, their responsibilities, attributes, business constraints, lifecycles, and validation rules for the SplitDee platform.
āđ€āļ­āļāļŠāļēāļĢāļ‰āļšāļąāļšāļ™āļĩāđ‰āļāļģāļŦāļ™āļ”āđ€āļ­āļ™āļ—āļīāļ•āļĩāļ—āļēāļ‡āļ˜āļļāļĢāļāļīāļˆāđāļāļ™āļŦāļĨāļąāļ āļŦāļ™āđ‰āļēāļ—āļĩāđˆāļ„āļ§āļēāļĄāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš āļ„āļļāļ“āļĨāļąāļāļĐāļ“āļ° āļ‚āđ‰āļ­āļˆāļģāļāļąāļ”āļ—āļēāļ‡āļ˜āļļāļĢāļāļīāļˆ āļ§āļ‡āļˆāļĢāļŠāļĩāļ§āļīāļ• āđāļĨāļ°āļāļŽāļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ„āļ§āļēāļĄāļ–āļđāļāļ•āđ‰āļ­āļ‡āļŠāļģāļŦāļĢāļąāļšāđāļžāļĨāļ•āļŸāļ­āļĢāđŒāļĄ SplitDee


ðŸ‡đ🇭 āļ āļēāļĐāļēāđ„āļ—āļĒ (āļŠāļģāļŦāļĢāļąāļšāļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™)

1. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: User (āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āđāļŠāļ”āļ‡āļ–āļķāļ‡āļšāļąāļāļŠāļĩāļœāļđāđ‰āđƒāļŠāđ‰āđāļ•āđˆāļĨāļ°āļšāļļāļ„āļ„āļĨāļ—āļĩāđˆāļĨāļ‡āļ—āļ°āđ€āļšāļĩāļĒāļ™āđƒāļ™āļĢāļ°āļšāļš
  • āļ„āļ§āļēāļĄāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš: āļˆāļąāļ”āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāđ‚āļ›āļĢāđ„āļŸāļĨāđŒ āļšāļąāļāļŠāļĩāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™ āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļŠāđˆāļ­āļ‡āļ—āļēāļ‡āļžāļĢāđ‰āļ­āļĄāđ€āļžāļĒāđŒāļŠāļģāļŦāļĢāļąāļšāļŠāļĢāđ‰āļēāļ‡ QR āđ‚āļ„āđ‰āļ” āđāļĨāļ°āļšāļąāļ™āļ—āļķāļāļĒāļ­āļ”āđ€āļ‡āļīāļ™āļĢāļ§āļĄāļŠāđˆāļ§āļ™āļšāļļāļ„āļ„āļĨ
  • āļ„āļļāļ“āļĨāļąāļāļĐāļ“āļ° (Attributes):
    • id (UUID): āļ•āļąāļ§āļĢāļ°āļšāļļāđ€āļ‰āļžāļēāļ°āļ‚āļ­āļ‡āđāļ•āđˆāļĨāļ°āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™
    • email (string): āļ—āļĩāđˆāļ­āļĒāļđāđˆāļ­āļĩāđ€āļĄāļĨāļ›āļĢāļ°āļˆāļģāļšāļąāļāļŠāļĩ
    • password_hash (string): āļĢāļŦāļąāļŠāļœāđˆāļēāļ™āļ—āļĩāđˆāđāļŪāļŠāļ”āđ‰āļ§āļĒ Bcrypt
    • display_name (string): āļŠāļ·āđˆāļ­āđāļŠāļ”āļ‡āļœāļĨāđ‚āļ›āļĢāđ„āļŸāļĨāđŒāļŠāļēāļ˜āļēāļĢāļ“āļ°
    • phone_number (string, optional): āļŦāļĄāļēāļĒāđ€āļĨāļ‚āđ‚āļ—āļĢāļĻāļąāļžāļ—āđŒāļ—āļĩāđˆāļœāļđāļāļāļąāļšāļžāļĢāđ‰āļ­āļĄāđ€āļžāļĒāđŒ
    • avatar_url (string, optional): āļĨāļīāļ‡āļāđŒāļĢāļđāļ›āļ āļēāļžāđ‚āļ›āļĢāđ„āļŸāļĨāđŒāļœāļđāđ‰āđƒāļŠāđ‰
    • is_active (boolean): āļŠāļ–āļēāļ™āļ°āļ„āļ§āļēāļĄāđ€āļ„āļĨāļ·āđˆāļ­āļ™āđ„āļŦāļ§āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™āļšāļąāļāļŠāļĩ
  • āļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ (Relationships):
    • āđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļĨāļēāļĒāļāļąāļš GroupMember (āļāļĨāļļāđˆāļĄāļŠāļĄāļēāļŠāļīāļāļ—āļĩāđˆāđ€āļ‚āđ‰āļēāļĢāđˆāļ§āļĄ)
    • āđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļĨāļēāļĒāļāļąāļš Bill (āļšāļīāļĨāļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āļ‚āļķāđ‰āļ™)
    • āđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļĨāļēāļĒāļāļąāļš ExpenseShare (āļĒāļ­āļ”āļŠāđˆāļ§āļ™āđāļšāđˆāļ‡āļŦāļ™āļĩāđ‰āļ—āļĩāđˆāļ„āđ‰āļēāļ‡āļˆāđˆāļēāļĒ)
    • āđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļĨāļēāļĒāļāļąāļš Payment (āļŦāļĨāļąāļāļāļēāļ™āļāļēāļĢāđ‚āļ­āļ™āđ€āļ‡āļīāļ™āļ—āļĩāđˆāļĒāļ·āđˆāļ™āđ€āļ‚āđ‰āļēāļĄāļē)
  • āļ‚āđ‰āļ­āļˆāļģāļāļąāļ”āļ—āļēāļ‡āļ˜āļļāļĢāļāļīāļˆ: āļ­āļĩāđ€āļĄāļĨāļ•āđ‰āļ­āļ‡āđ„āļĄāđˆāļ‹āđ‰āļģāļāļąāļ™ āđ€āļšāļ­āļĢāđŒāđ‚āļ—āļĢāļĻāļąāļžāļ—āđŒāđ€āļ›āđ‡āļ™āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļĨāļ·āļ­āļāđƒāļŠāđˆ āđāļ•āđˆāļˆāļģāđ€āļ›āđ‡āļ™āļ•āđ‰āļ­āļ‡āļĢāļ°āļšāļļāļāđˆāļ­āļ™āļŠāļĢāđ‰āļēāļ‡āļ„āļīāļ§āļ­āļēāļĢāđŒāļžāļĢāđ‰āļ­āļĄāđ€āļžāļĒāđŒāđ€āļĄāļ·āđˆāļ­āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āļ—āļģāļŦāļ™āđ‰āļēāļ—āļĩāđˆāđ€āļ›āđ‡āļ™āđ€āļˆāđ‰āļēāļŦāļ™āļĩāđ‰
  • āļ§āļ‡āļˆāļĢāļŠāļĩāļ§āļīāļ• (Lifecycle): āļĨāļ‡āļ—āļ°āđ€āļšāļĩāļĒāļ™ (Created) ➔ āđƒāļŠāđ‰āļ‡āļēāļ™āļ­āļĒāļđāđˆ (Active) ➔ āļĢāļ°āļ‡āļąāļšāļŠāļąāđˆāļ§āļ„āļĢāļēāļ§ (Suspended) ➔ āļĒāļāđ€āļĨāļīāļāđƒāļŠāđ‰āļ‡āļēāļ™/āļ›āļāļ›āļīāļ”āļ•āļąāļ§āļ•āļ™ (Deactivated)
  • āļāļŽāļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ‚āđ‰āļ­āļĄāļđāļĨ: āļ­āļĩāđ€āļĄāļĨāļ•āđ‰āļ­āļ‡āļ•āļĢāļ‡āļ•āļēāļĄāļĢāļđāļ›āđāļšāļš Regex āļŠāļ·āđˆāļ­āđāļŠāļ”āļ‡āļœāļĨāļĒāļēāļ§ 2 āļ–āļķāļ‡ 100 āļ­āļąāļāļ‚āļĢāļ° āđ€āļšāļ­āļĢāđŒāđ‚āļ—āļĢāļĻāļąāļžāļ—āđŒāđ„āļ—āļĒāļĄāļĩ 10 āļŦāļĨāļąāļ (āđ€āļŠāđˆāļ™ 08XXXXXXXX)
  • āļāļēāļĢāļ‚āļĒāļēāļĒāļ•āļąāļ§āđƒāļ™āļ­āļ™āļēāļ„āļ•: āļšāļąāļāļŠāļĩ Social Login, āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āđ€āļĨāļ‚āļ—āļĩāđˆāļšāļąāļāļŠāļĩāļ˜āļ™āļēāļ„āļēāļĢ, āļ›āļļāđˆāļĄāļ›āļĢāļąāļšāđāļ•āđˆāļ‡āļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™

2. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: Group (āļāļĨāļļāđˆāļĄāļāļīāļˆāļāļĢāļĢāļĄ)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āđāļŠāļ”āļ‡āļ–āļķāļ‡āļžāļ·āđ‰āļ™āļ—āļĩāđˆāđāļšāđˆāļ‡āļ›āļąāļ™āļ„āđˆāļēāđƒāļŠāđ‰āļˆāđˆāļēāļĒāļ‚āļ­āļ‡āļĢāļđāļĄāđ€āļĄāļ— āđ€āļžāļ·āđˆāļ­āļ™āļŠāļ™āļīāļ— āļŦāļĢāļ·āļ­āļ„āļ“āļ°āđ€āļ”āļīāļ™āļ—āļēāļ‡
  • āļ„āļ§āļēāļĄāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš: āļˆāļąāļ”āļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļĄāļēāļŠāļīāļ āļ„āļ§āļšāļ„āļļāļĄāļ‚āļ­āļšāđ€āļ‚āļ•āļšāļīāļĨ āļ”āļđāđāļĨāļŠāļąāļ•āļ§āđŒāđ€āļĨāļĩāđ‰āļĒāļ‡āļ‚āļ­āļ‡āļāļĨāļļāđˆāļĄ āđāļĨāļ°āļ„āļ§āļšāļ„āļļāļĄāļāļĨāđˆāļ­āļ‡āđāļŠāļ—āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ
  • āļ„āļļāļ“āļĨāļąāļāļĐāļ“āļ° (Attributes):
    • id (UUID): āļ•āļąāļ§āļĢāļ°āļšāļļāđ€āļ‰āļžāļēāļ°āļ‚āļ­āļ‡āļāļĨāļļāđˆāļĄ
    • name (string): āļŠāļ·āđˆāļ­āļāļĨāļļāđˆāļĄ
    • description (text, optional): āļ„āļģāļ­āļ˜āļīāļšāļēāļĒāļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒāļ‚āļ­āļ‡āļāļĨāļļāđˆāļĄ
    • invite_code (string): āļĢāļŦāļąāļŠāđ€āļŠāļīāļāļŠāļ§āļ™āđ€āļ‚āđ‰āļēāļāļĨāļļāđˆāļĄāļ„āļ§āļēāļĄāļĒāļēāļ§ 10 āļŦāļĨāļąāļ
  • āļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒ (Relationships):
    • āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļĨāļēāļĒāļāļąāļš GroupMember (āļŠāļĄāļēāļŠāļīāļāļāļĨāļļāđˆāļĄ)
    • āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļĨāļēāļĒāļāļąāļš Bill (āļšāļīāļĨāļ„āđˆāļēāđƒāļŠāđ‰āļˆāđˆāļēāļĒ)
    • āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļĨāļēāļĒāļāļąāļš ChatMessage (āđāļŠāļ—āļŠāļ™āļ—āļ™āļēāļāļĨāļļāđˆāļĄ)
    • āļŦāļ™āļķāđˆāļ‡āļ•āđˆāļ­āļŦāļ™āļķāđˆāļ‡āļāļąāļš Pet (āļŠāļąāļ•āļ§āđŒāđ€āļĨāļĩāđ‰āļĒāļ‡āļ›āļĢāļ°āļˆāļģāļāļĨāļļāđˆāļĄ)
  • āļ‚āđ‰āļ­āļˆāļģāļāļąāļ”āļ—āļēāļ‡āļ˜āļļāļĢāļāļīāļˆ: āļŠāļ·āđˆāļ­āļāļĨāļļāđˆāļĄāļŦāđ‰āļēāļĄāļ§āđˆāļēāļ‡ āļĢāļŦāļąāļŠāđ€āļŠāļīāļāļŠāļ§āļ™āļ•āđ‰āļ­āļ‡āđ„āļĄāđˆāļ‹āđ‰āļģāđāļĨāļ°āļ›āļĢāļ°āļāļ­āļšāļ”āđ‰āļ§āļĒāļ•āļąāļ§āļ­āļąāļāļĐāļĢāļœāļŠāļĄāļ•āļąāļ§āđ€āļĨāļ‚
  • āļ§āļ‡āļˆāļĢāļŠāļĩāļ§āļīāļ• (Lifecycle): āļŠāļĢāđ‰āļēāļ‡āļāļĨāļļāđˆāļĄ âž” āđƒāļŠāđ‰āļ‡āļēāļ™āļ­āļĒāļđāđˆ ➔ āļˆāļąāļ”āđ€āļāđ‡āļšāļ–āļēāļ§āļĢ (Archived)
  • āļāļŽāļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļ‚āđ‰āļ­āļĄāļđāļĨ: āļŠāļ·āđˆāļ­āļāļĨāļļāđˆāļĄāļ•āđ‰āļ­āļ‡āļĄāļĩāļ„āļ§āļēāļĄāļĒāļēāļ§āļĢāļ°āļŦāļ§āđˆāļēāļ‡ 1 āļ–āļķāļ‡ 100 āļ­āļąāļāļ‚āļĢāļ°

3. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: GroupMember (āļŠāļĄāļēāļŠāļīāļāļāļĨāļļāđˆāļĄ)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āđāļŠāļ”āļ‡āļ„āļ§āļēāļĄāļŠāļąāļĄāļžāļąāļ™āļ˜āđŒāđāļĨāļ°āļ„āļ§āļēāļĄāđ€āļŠāļ·āđˆāļ­āļĄāđ‚āļĒāļ‡āļĢāļ°āļŦāļ§āđˆāļēāļ‡āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āđāļĨāļ°āļāļĨāļļāđˆāļĄ
  • āļ„āļ§āļēāļĄāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš: āļ„āļ§āļšāļ„āļļāļĄāļšāļ—āļšāļēāļ—āļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāļ—āļģāļĢāļēāļĒāļāļēāļĢāđāļĨāļ°āđ€āļ‚āđ‰āļēāļ–āļķāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ āļēāļĒāđƒāļ™āļāļĨāļļāđˆāļĄ
  • āļ„āļļāļ“āļĨāļąāļāļĐāļ“āļ° (Attributes):
    • id (UUID): āļ•āļąāļ§āļĢāļ°āļšāļļāļŠāļ–āļēāļ™āļ°āļŠāļĄāļēāļŠāļīāļ
    • group_id (UUID): āļ•āļąāļ§āļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļāļĨāļļāđˆāļĄāļŦāļĨāļąāļ
    • user_id (UUID): āļ•āļąāļ§āļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™
    • role (string): āļšāļ—āļšāļēāļ—āļŦāļ™āđ‰āļēāļ—āļĩāđˆāļŠāļīāļ—āļ˜āļīāđŒ (owner āļŦāļĢāļ·āļ­ member)
  • āļ‚āđ‰āļ­āļˆāļģāļāļąāļ”āļ—āļēāļ‡āļ˜āļļāļĢāļāļīāļˆ: āļ„āđˆāļēāđ„āļ­āļ”āļĩāļ„āļđāđˆāļāļąāļ™ (group_id, user_id) āļ•āđ‰āļ­āļ‡āđ„āļĄāđˆāļ‹āđ‰āļģāļāļąāļ™ āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™āđ„āļĄāđˆāļŠāļēāļĄāļēāļĢāļ–āđ€āļ‚āđ‰āļēāļĢāđˆāļ§āļĄāļāļĨāļļāđˆāļĄāđ€āļ”āļīāļĄāļ‹āđ‰āļģāļ‹āđ‰āļ­āļ™āđ„āļ”āđ‰

4. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: Bill (āļšāļīāļĨāļ„āđˆāļēāđƒāļŠāđ‰āļˆāđˆāļēāļĒ)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļĢāļēāļĒāļāļēāļĢāļšāļąāļ™āļ—āļķāļāļ„āđˆāļēāđƒāļŠāđ‰āļˆāđˆāļēāļĒāļŦāļ™āļķāđˆāļ‡āļĢāļēāļĒāļāļēāļĢāļ—āļĩāđˆāđ€āļāļīāļ”āļ‚āļķāđ‰āļ™āđƒāļ™āļāļĨāļļāđˆāļĄ
  • āļ„āļ§āļēāļĄāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļš: āļšāļąāļ™āļ—āļķāļāļœāļđāđ‰āļŠāļģāļĢāļ­āļ‡āļˆāđˆāļēāļĒ āļĒāļ­āļ”āđ€āļ‡āļīāļ™āļĢāļ§āļĄ āļ§āļīāļ˜āļĩāļāļēāļĢāļŦāļēāļĢāđ€āļ‡āļīāļ™ āđāļĨāļ°āļŠāļ–āļēāļ™āļ°āļŠāļģāļĢāļ°āļŦāļ™āļĩāđ‰
  • āļ„āļļāļ“āļĨāļąāļāļĐāļ“āļ° (Attributes):
    • id (UUID): āļ•āļąāļ§āļĢāļ°āļšāļļāļšāļīāļĨ
    • group_id (UUID): āļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļāļĨāļļāđˆāļĄ
    • creator_id (UUID): āđ€āļˆāđ‰āļēāļŦāļ™āļĩāđ‰āļœāļđāđ‰āļŠāļģāļĢāļ­āļ‡āļ­āļ­āļāđ€āļ‡āļīāļ™āļāđˆāļ­āļ™
    • title (string): āļŠāļ·āđˆāļ­āļšāļīāļĨāļ„āđˆāļēāđƒāļŠāđ‰āļˆāđˆāļēāļĒ
    • total_amount (numeric): āļĒāļ­āļ”āđ€āļ‡āļīāļ™āļĢāļ§āļĄāļ‚āļ­āļ‡āļšāļīāļĨ
    • category (string): āļŦāļĄāļ§āļ”āļŦāļĄāļđāđˆāļšāļīāļĨ
    • status (string): āļŠāļ–āļēāļ™āļ°āļšāļīāļĨ (active, settled, locked)
  • āļ‚āđ‰āļ­āļˆāļģāļāļąāļ”āļ—āļēāļ‡āļ˜āļļāļĢāļāļīāļˆ: āļĒāļ­āļ”āđ€āļ‡āļīāļ™āļ•āđ‰āļ­āļ‡āļĄāļēāļāļāļ§āđˆāļē 0 āļœāļĨāļĢāļ§āļĄāļŠāđˆāļ§āļ™āđāļšāđˆāļ‡āļ•āđ‰āļ­āļ‡āđ€āļ—āđˆāļēāļāļąāļšāļĒāļ­āļ”āļĢāļ§āļĄāļšāļīāļĨāļžāļ­āļ”āļĩ
  • āļ§āļ‡āļˆāļĢāļŠāļĩāļ§āļīāļ• (Lifecycle): āļĢāđˆāļēāļ‡āļˆāļ” âž” āđ€āļ›āļīāļ”āđƒāļŠāđ‰āļ‡āļēāļ™āļĢāļ­āļŠāļģāļĢāļ° âž” āļŠāļģāļĢāļ°āļ„āļĢāļšāļ–āđ‰āļ§āļ™ âž” āļĨāđ‡āļ­āļāļšāļīāļĨāļ–āļēāļ§āļĢ (Locked)

5. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: ExpenseShare (āļŠāđˆāļ§āļ™āđāļšāđˆāļ‡āļĒāļ­āļ”āļŦāļ™āļĩāđ‰)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļĒāļ­āļ”āđ€āļ‡āļīāļ™āļ„āđ‰āļēāļ‡āļˆāđˆāļēāļĒāļ—āļĩāđˆāļĨāļđāļāļŦāļ™āļĩāđ‰āđāļ•āđˆāļĨāļ°āļ„āļ™āļ•āđ‰āļ­āļ‡āđ‚āļ­āļ™āļ„āļ·āļ™āđƒāļŦāđ‰āđ€āļˆāđ‰āļēāļŦāļ™āļĩāđ‰
  • āļ„āļļāļ“āļĨāļąāļāļĐāļ“āļ° (Attributes):
    • id (UUID): āļ•āļąāļ§āļĢāļ°āļšāļļāļĒāļ­āļ”āļ„āđ‰āļēāļ‡āļŠāļģāļĢāļ°
    • bill_id (UUID): āļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļšāļīāļĨāļŦāļĨāļąāļ
    • user_id (UUID): āļ•āļąāļ§āļĢāļ°āļšāļļāļĨāļđāļāļŦāļ™āļĩāđ‰
    • share_amount (numeric): āļĒāļ­āļ”āđ€āļ‡āļīāļ™āļ—āļĩāđˆāļ•āđ‰āļ­āļ‡āļˆāđˆāļēāļĒ
    • status (string): āļŠāļ–āļēāļ™āļ°āļŠāļģāļĢāļ°āļŦāļ™āļĩāđ‰ (unpaid, processing, paid)

6. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: Payment (āļĢāļēāļĒāļāļēāļĢāļŠāļģāļĢāļ°āđ€āļ‡āļīāļ™)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļĢāļēāļĒāļāļēāļĢāļŠāļģāļĢāļ°āđ€āļ‡āļīāļ™āđāļĨāļ°āļ•āļĢāļ§āļˆāļŠāļ­āļšāļŦāļĨāļąāļāļāļēāļ™āļ‚āļ­āļ‡āļĨāļđāļāļŦāļ™āļĩāđ‰
  • āļ„āļļāļ“āļĨāļąāļāļĐāļ“āļ° (Attributes):
    • id (UUID): āļ•āļąāļ§āļĢāļ°āļšāļļ
    • bill_id (UUID): āļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļšāļīāļĨ
    • payer_id (UUID): āļĨāļđāļāļŦāļ™āļĩāđ‰āļœāļđāđ‰āđ‚āļ­āļ™āđ€āļ‡āļīāļ™
    • amount (numeric): āļĒāļ­āļ”āđ€āļ‡āļīāļ™āđ‚āļ­āļ™āļˆāļĢāļīāļ‡
    • slip_image_url (string): āļĨāļīāļ‡āļāđŒāļ—āļĩāđˆāđ€āļāđ‡āļšāđ„āļŸāļĨāđŒāļĢāļđāļ›āļ āļēāļžāļŠāļĨāļīāļ›
    • slip_trans_id (string): āđ€āļĨāļ‚āļ­āđ‰āļēāļ‡āļ­āļīāļ‡āļĢāļŦāļąāļŠāļ˜āļļāļĢāļāļĢāļĢāļĄāļ‚āļ­āļ‡āļ˜āļ™āļēāļ„āļēāļĢ
    • verification_status (string): āļŠāļ–āļēāļ™āļ°āļ•āļĢāļ§āļˆāļŠāļĨāļīāļ› (pending, verified, failed)

7. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: Receipt (āļ āļēāļžāđƒāļšāđ€āļŠāļĢāđ‡āļˆāļĢāđ‰āļēāļ™āļ„āđ‰āļē)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļ‚āđ‰āļ­āļĄāļđāļĨāļŠāđāļāļ™āđƒāļšāđ€āļŠāļĢāđ‡āļˆāļ•āđ‰āļ™āļ—āļēāļ‡āđ€āļžāļ·āđˆāļ­āļ­āļģāļ™āļ§āļĒāļ„āļ§āļēāļĄāļŠāļ°āļ”āļ§āļāđƒāļ™āļāļēāļĢāļˆāļąāļ”āļŠāļĢāļĢāļ„āđˆāļēāđƒāļŠāđ‰āļˆāđˆāļēāļĒāļŠāļĢāđ‰āļēāļ‡āļšāļīāļĨ

8. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: Notification (āļāļēāļĢāđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļšāļąāļ™āļ—āļķāļāđāļĨāļ°āļˆāļąāļ”āļŠāđˆāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāđāļˆāđ‰āļ‡āļ‚āđˆāļēāļ§āļŠāļēāļĢāđƒāļ™āļĢāļ°āļšāļšāđ„āļ›āļĒāļąāļ‡āļĄāļ·āļ­āļ–āļ·āļ­āļ‚āļ­āļ‡āļœāļđāđ‰āđƒāļŠāđ‰āļ‡āļēāļ™

9. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: ChatMessage (āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļŠāļ™āļ—āļ™āļē)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļ‚āđ‰āļ­āļ„āļ§āļēāļĄ āļāļīāļˆāļāļĢāļĢāļĄāļĢāļ°āļšāļš āļŦāļĢāļ·āļ­āļāļēāļĢāđŒāļ”āļšāļīāļĨāļ—āļĩāđˆāđāļŠāļ”āļ‡āļœāļĨāļšāļ™āļŦāđ‰āļ­āļ‡āđāļŠāļ—āļ‚āļ­āļ‡āļŦāđ‰āļ­āļ‡

10. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: Pet & PetStatus (āļŠāļąāļ•āļ§āđŒāđ€āļĨāļĩāđ‰āļĒāļ‡āđ€āļŠāļĄāļ·āļ­āļ™āđ‚āļĄāļˆāļī)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļŠāļąāļ•āļ§āđŒāđ€āļĨāļĩāđ‰āļĒāļ‡āļ›āļĢāļ°āļˆāļģāļŦāđ‰āļ­āļ‡āļ„āļ­āļĒāđāļŠāļ”āļ‡āļŠāđ€āļ•āļ•āļąāļŠāļ„āļ§āļēāļĄāļĢāļąāļšāļœāļīāļ”āļŠāļ­āļšāļāļēāļĢāđ€āļ‡āļīāļ™āļœāđˆāļēāļ™āļ•āļąāļ§āđāļ›āļĢ XP/HP āļ‚āļ­āļ‡āļāļĨāļļāđˆāļĄ

11. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: Reminder (āļĢāļēāļĒāļāļēāļĢāļŠāđˆāļ‡āļ—āļ§āļ‡)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļšāļąāļ™āļ—āļķāļāļ‚āđ‰āļ­āļĄāļđāļĨāļ›āļĢāļ°āļ§āļąāļ•āļīāļāļēāļĢāļāļ”āđ€āļ•āļ·āļ­āļ™āđ€āļ‡āļīāļ™āđāļĨāļ°āļĢāļ°āļ”āļąāļšāļ™āđ‰āļģāđ€āļŠāļĩāļĒāļ‡āļ—āļ§āļ‡āđ€āļžāļ·āđˆāļ­āļ™

12. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: AIJob (āļ„āļīāļ§āļ‡āļēāļ™ AI)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļ‡āļēāļ™āļ›āļĢāļ°āļĄāļ§āļĨāļœāļĨāļĢāļ°āļšāļš AI āļŦāļĨāļąāļ‡āļšāđ‰āļēāļ™ āđ€āļŠāđˆāļ™ āļāļēāļĢāļŠāđāļāļ™āļ āļēāļžāļŠāļĨāļīāļ›āļ˜āļ™āļēāļ„āļēāļĢ

13. āđ€āļ­āļ™āļ—āļīāļ•āļĩ: MemeTemplate (āđāļĄāđˆāđāļšāļšāļĄāļĩāļĄ)

  • āļ§āļąāļ•āļ–āļļāļ›āļĢāļ°āļŠāļ‡āļ„āđŒ: āļĢāļđāļ›āļžāļ·āđ‰āļ™āļŦāļĨāļąāļ‡āļĄāļĩāļĄāđāļĨāļ°āļ‚āđ‰āļ­āļĄāļđāļĨāļžāļīāļāļąāļ”āļ§āļēāļ‡āļ‚āđ‰āļ­āļ„āļ§āļēāļĄāļ—āļąāļš āļŠāļģāļŦāļĢāļąāļšāļĒāļīāļ‡āļ—āļ§āļ‡āļŦāļ™āļĩāđ‰āļ­āļąāļ•āđ‚āļ™āļĄāļąāļ•āļī

🇎🇧 English (For AI Agents)

1. Entity: User

  • Purpose: Represents an individual account registered in the system.
  • Responsibilities: Holds identity profiles, security credentials, contact details for PromptPay QR generation, and tracks individual financial balance aggregates.
  • Attributes:
    • id (UUID): Unique user identifier.
    • email (string): Account email address.
    • password_hash (string): Bcrypt hash of user password.
    • display_name (string): Public profile display name.
    • phone_number (string, optional): Phone number linked to PromptPay.
    • avatar_url (string, optional): Link to profile avatar.
    • is_active (boolean): Active status flags.
  • Relationships:
    • One-to-Many with GroupMember (groups joined).
    • One-to-Many with Bill (bills created).
    • One-to-Many with ExpenseShare (debts owed).
    • One-to-Many with Payment (slips submitted).
  • Business Constraints: Email must be unique. Phone number is optional, but required prior to generating PromptPay codes where the user is the creditor.
  • Lifecycle: Created (Registered) -> Active -> Suspended (optional) -> Deactivated/Anonymized.
  • Validation Rules: Email must match valid email regex. Display name must be between 2 and 100 characters. Phone number must match standard Thai mobile formats (e.g., 08XXXXXXXX or 09XXXXXXXX, total 10 digits).
  • Future Extensions: Social Login credentials, banking account details, notification preference toggles.

2. Entity: Group

  • Purpose: Represents a shared space containing roommates, friends, or travelers who share expenses.
  • Responsibilities: Manages memberships, scopes bills, contains a group pet, and scopes chat messages.
  • Attributes:
    • id (UUID): Unique group identifier.
    • name (string): Group name.
    • description (text, optional): Description of the group’s purpose.
    • invite_code (string): Unique 10-character code to join the group.
  • Relationships:
    • One-to-Many with GroupMember (members).
    • One-to-Many with Bill (bills).
    • One-to-Many with ChatMessage (chat activity feed).
    • One-to-One with Pet (shared pet).
  • Business Constraints: Name must not be blank. Invite code must be unique and alphanumeric.
  • Lifecycle: Created -> Active -> Archived.
  • Validation Rules: Group name must be between 1 and 100 characters.
  • Future Extensions: Group category, group avatars, group specific thresholds for expenses.

3. Entity: GroupMember

  • Purpose: Represents the association between a User and a Group.
  • Responsibilities: Governs role permissions inside a group.
  • Attributes:
    • id (UUID): Unique membership identifier.
    • group_id (UUID): Reference to parent Group.
    • user_id (UUID): Reference to associated User.
    • role (string): Member privileges (owner, member).
  • Relationships: Many-to-One with Group, Many-to-One with User.
  • Business Constraints: Composite uniqueness on (group_id, user_id): a user cannot join a group twice.
  • Lifecycle: Joined -> Active -> Removed/Left.
  • Validation Rules: Role must match either 'owner' or 'member'.

4. Entity: Bill

  • Purpose: Represents a single recorded expense.
  • Responsibilities: Tracks who paid, total cost, split logic, and settlement status.
  • Attributes:
    • id (UUID): Unique bill identifier.
    • group_id (UUID): Parent group.
    • creator_id (UUID): The creditor (who paid the initial cost).
    • title (string): Purpose of the bill.
    • total_amount (numeric): Total expense amount.
    • category (string): Expense category.
    • status (string): Status of the bill (active, settled, locked).
  • Relationships:
    • Many-to-One with Group.
    • Many-to-One with User (creator).
    • One-to-Many with ExpenseShare (individual splits).
    • One-to-Many with Payment (associated payments).
  • Business Constraints: Total amount must be greater than 0. Sum of associated expense shares must exactly equal the total amount.
  • Lifecycle: Draft -> Active (Published) -> Settled (all shares paid) -> Locked (archived after verification).
  • Validation Rules: Title must be between 1 and 255 characters. Total amount must have up to 2 decimal places.

5. Entity: ExpenseShare

  • Purpose: Represents an individual debtor’s share of a specific bill.
  • Responsibilities: Tracks debt status and payment details for a single user.
  • Attributes:
    • id (UUID): Unique share identifier.
    • bill_id (UUID): Parent bill.
    • user_id (UUID): Debtor.
    • share_amount (numeric): Amount this user owes.
    • status (string): Status of the share (unpaid, processing, paid).
    • paid_at (datetime, optional): Time of verification.
  • Relationships: Many-to-One with Bill, Many-to-One with User (debtor).
  • Business Constraints: Share amount must be positive. Debtor cannot be the same user as the bill creator unless it’s a multi-debtor custom split adjustment.
  • Lifecycle: Created -> Unpaid -> Processing (slip uploaded, pending OCR/manual review) -> Paid.
  • Validation Rules: Share status must be in ['unpaid', 'processing', 'paid'].

6. Entity: Payment

  • Purpose: Represents a transaction submission by a debtor.
  • Responsibilities: Houses reference numbers and links to slip photos to verify debt settlement.
  • Attributes:
    • id (UUID): Unique identifier.
    • bill_id (UUID): Associated bill.
    • payer_id (UUID): The debtor who made the payment.
    • amount (numeric): Amount transferred.
    • slip_image_url (string): Path to slip image in secure storage.
    • slip_trans_id (string, optional): Extracted bank transaction ID.
    • verification_status (string): Verification status (pending, verified, failed).
    • verified_at (datetime, optional): Time of verification completion.
  • Relationships: Many-to-One with Bill, Many-to-One with User (payer).
  • Business Constraints: slip_trans_id must be unique across the entire platform database (prevents double-spending).
  • Lifecycle: Initiated -> Pending (awaiting OCR/Bank query) -> Verified / Failed.
  • Validation Rules: Status must match ['pending', 'verified', 'failed'].

7. Entity: Receipt

  • Purpose: Represents the initial invoice or merchant receipt of a bill.
  • Responsibilities: Holds details extracted by AI/OCR to auto-populate Bill creation fields.
  • Attributes:
    • id (UUID): Unique identifier.
    • image_url (string): Path to receipt image.
    • extracted_total (numeric, optional): Extracted total cost.
    • extracted_merchant (string, optional): Extracted merchant name.
  • Relationships: Associated with Bill (optional).
  • Lifecycle: Uploaded -> Extracted -> Linked to Bill / Discarded.

8. Entity: Notification

  • Purpose: Represents a system notification to a user.
  • Responsibilities: Holds message payload and dispatch status.
  • Attributes:
    • id (UUID): Unique identifier.
    • user_id (UUID): Recipient.
    • title (string): Title of notification.
    • body (text): Content.
    • is_read (boolean): Read status.
    • channel (string): Delivery method (in-app, push).
  • Relationships: Many-to-One with User.
  • Lifecycle: Created -> Sent -> Read / Expired.

9. Entity: ChatMessage

  • Purpose: Represents a message inside a group chat feed.
  • Responsibilities: Holds text details, system events, and references to bills/payments.
  • Attributes:
    • id (UUID): Unique identifier.
    • group_id (UUID): Parent group.
    • sender_id (UUID, optional): Sender. If null, represents a system message.
    • message_type (string): Message type (text, system_event, bill_card).
    • message (text): Main message content.
    • metadata_json (JSON, optional): Auxiliary ID references.
  • Relationships: Many-to-One with Group, Many-to-One with User.
  • Lifecycle: Sent -> Delivered. No editing allowed.

10. Entity: Pet

  • Purpose: Represents the shared virtual pet (“Mochi”) belonging to a group.
  • Responsibilities: Motivates timely debt repayment through gamified health status.
  • Attributes:
    • id (UUID): Unique identifier.
    • group_id (UUID): Associated group.
    • pet_name (string): Name chosen by the group.
  • Relationships: One-to-One with Group, One-to-Many with PetStatus.
  • Lifecycle: Hatched -> Active -> Inactive (group archived).

11. Entity: PetStatus

  • Purpose: Represents the dynamic health state of a Pet.
  • Responsibilities: Manages level, HP, and Happiness levels.
  • Attributes:
    • id (UUID): Unique identifier.
    • pet_id (UUID): Parent pet.
    • level (integer): Current level.
    • xp (integer): Experience points.
    • hp (integer): Health points (0-100).
    • happiness (integer): Happiness level (0-100).
  • Relationships: Many-to-One with Pet.
  • Business Constraints: HP and Happiness must be clamped between 0 and 100.
  • Lifecycle: Updated daily via cron schedules and whenever payment events trigger updates.

12. Entity: Reminder

  • Purpose: Represents a debt-collection notification task.
  • Responsibilities: Tracks when, how, and in what tone a debtor was reminded.
  • Attributes:
    • id (UUID): Unique identifier.
    • bill_id (UUID): Reference bill.
    • debtor_id (UUID): Debtor.
    • tone (string): Reminder tone (polite, casual, meme).
    • sent_at (datetime): Time of dispatch.
  • Relationships: Many-to-One with Bill, Many-to-One with User.

13. Entity: AIJob

  • Purpose: Represents an asynchronous background task processed by the AI system (OCR or meme generation).
  • Responsibilities: Tracks job status, worker ID, and outputs.
  • Attributes:
    • id (UUID): Unique identifier.
    • job_type (string): Task type (slip_ocr, receipt_ocr, meme_generation).
    • status (string): Status (queued, processing, completed, failed).
    • result (JSON, optional): Output payload.
  • Lifecycle: Queued -> Processing -> Completed / Failed.

14. Entity: MemeTemplate

  • Purpose: Represents a predefined image layout used to generate AI reminder memes.
  • Responsibilities: Holds base paths and coordinates for text placement.
  • Attributes:
    • id (UUID): Unique identifier.
    • name (string): Name of the meme format.
    • image_url (string): Base layout image.
    • text_coordinates (JSON): Pixel boundaries for text overlays.