Skip to content

sovon1/kangal-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

120 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

One-tap meals ยท Auto meal rates ยท Transparent finances ยท PDF reports

No more paper khatas. No more accusations. Just math. โœจ


Live Demo Next.js Supabase TypeScript Tailwind CSS React


GitHub stars GitHub forks GitHub issues License


๐Ÿ’ก The Problem

Every university mess in Bangladesh runs on WhatsApp groups, paper khatas, and mental math. Managers get accused of stealing money, members forget which meals they ate, and month-end calculations take hours.

๐Ÿ“ฑ WhatsApp Groups ๐Ÿ““ Paper Khatas ๐Ÿงฎ Mental Math
๐Ÿ˜ฉ "เฆญเฆพเฆ‡ เฆ†เฆœเฆ•เง‡ เฆ–เฆพเฆฌเง‹ เฆจเฆพ" เฆนเฆพเฆฐเฆฟเฆฏเฆผเง‡ เฆ—เง‡เฆ›เง‡ "เฆฎเฆจเง‡ เฆจเฆพเฆ‡ เฆญเฆพเฆ‡"
๐Ÿ˜ค "เฆ•เง‡ เฆฌเฆพเฆœเฆพเฆฐ เฆ•เฆฐเฆฌเง‡?" เฆญเงเฆฒ เฆนเฆฟเฆธเฆพเฆฌ "เฆคเง‹เฆฎเฆพเฆฐ เงซเงฆ เฆŸเฆพเฆ•เฆพ เฆฌเฆพเฆ•เฆฟ"
๐Ÿคฌ "เฆฎเงเฆฏเฆพเฆจเง‡เฆœเฆพเฆฐ เฆŸเฆพเฆ•เฆพ เฆฎเฆพเฆฐเฆ›เง‡!" เฆ›เง‡เฆเฆกเฆผเฆพ เฆชเง‡เฆœ "เฆ†เฆฎเฆฟ เงจ เฆฌเง‡เฆฒเฆพเฆ‡ เฆ–เฆพเฆ‡เฆจเฆฟ!"

โฌ‡๏ธ

โœ… KANGAL fixes all of this. Permanently. No more drama.


โœจ Features at a Glance

Feature What it does Vibe
๐Ÿฝ๏ธ Meal Tracking Toggle breakfast/lunch/dinner with one tap "เฆ†เฆœเฆ•เง‡ เฆฒเฆพเฆžเงเฆš เฆ…เฆซ"
๐Ÿ›’ Bazaar Logs Record every shopping trip item-by-item "เฆ†เฆœ เฆชเง‡เฆเฆฏเฆผเฆพเฆœ เงง เฆ•เง‡เฆœเฆฟ, เงชเงฆ เฆŸเฆพเฆ•เฆพ"
๐Ÿ“Š Auto Meal Rate Total Bazaar รท Total Meals = Rate โ€” live "เฆ†เฆœเฆ•เง‡เฆฐ เฆฐเง‡เฆŸ เงฉเงฎ.เงซเงฆ"
๐Ÿ’ฐ Deposits Track every taka deposited, with approval "เงงเงซเงฆเงฆ เฆฌเฆฟเฆ•เฆพเฆถเง‡ เฆฆเฆฟเฆฒเฆพเฆฎ"
๐Ÿ“„ PDF Reports One-click export for any member or full mess "เฆเฆ‡ เฆจเฆพเฆ“ PDF"
๐Ÿ“ˆ Spending Charts Visualize who ate how much with bar charts "เฆธเฆฌเฆšเง‡เฆฏเฆผเง‡ เฆฌเง‡เฆถเฆฟ เฆคเงเฆฎเฆฟ เฆ–เฆพเฆ“ เฆญเฆพเฆ‡"
๐Ÿ‘ฅ Manager Tools Month closing, member management, role transfer "เฆจเฆคเงเฆจ เฆฎเงเฆฏเฆพเฆจเง‡เฆœเฆพเฆฐ เฆจเฆฟเฆฏเงเฆ•เงเฆค"
โฐ Cutoff Locking Auto-lock meals after configurable cutoff times "เฆฐเฆพเฆค เงฏเฆŸเฆพเฆฐ เฆชเฆฐ เฆฌเฆจเงเฆง"
๐Ÿ” Full Auth Email/password + Google OAuth + password reset "เฆญเงเฆฒเง‡ เฆ—เง‡เฆ›เฆฟ? Reset!"
๐Ÿ“ฑ PWA Ready Install on home screen, works like native app "เฆ…เงเฆฏเฆพเฆช เฆเฆฐ เฆฎเฆคเง‹เฆ‡!"

๐Ÿ—๏ธ System Architecture

graph TB
    subgraph Client ["๐Ÿ–ฅ๏ธ Client Layer"]
        A["โš›๏ธ React 19 + Next.js 16<br/><i>App Router + Turbopack</i>"]
        B["๐ŸŽจ Tailwind CSS v4 + shadcn/ui"]
        C["๐Ÿ“Š Recharts + jsPDF"]
    end

    subgraph Server ["โš™๏ธ Server Layer"]
        D["๐Ÿ”„ Server Actions<br/><i>Type-safe RPC</i>"]
        E["๐Ÿ›ก๏ธ Auth Middleware<br/><i>Protected Routes</i>"]
        F["๐Ÿ—‚๏ธ React Query<br/><i>Smart Caching</i>"]
    end

    subgraph Database ["๐Ÿ—„๏ธ Supabase (PostgreSQL)"]
        G["๐Ÿ“‹ 14 Tables<br/><i>3NF Normalized</i>"]
        H["๐Ÿ”’ Row Level Security<br/><i>Per-mess isolation</i>"]
        I["โšก Triggers & RPCs<br/><i>Atomic operations</i>"]
    end

    A --> D
    B --> A
    C --> A
    D --> E
    E --> G
    F --> D
    G --> H
    G --> I

    style Client fill:#1a1a2e,stroke:#FF6B6B,color:#fff
    style Server fill:#16213e,stroke:#FFA94D,color:#fff
    style Database fill:#0f3460,stroke:#3FCF8E,color:#fff
Loading

๐Ÿ—„๏ธ Database Schema

๐Ÿ“ Click to expand Entity Relationship Diagram
erDiagram
    profiles ||--o{ mess_members : "has membership"
    profiles ||--o{ messes : "creates"
    messes ||--o{ mess_members : "has"
    messes ||--o{ mess_cycles : "has"
    messes ||--o{ bazaar_expenses : "has"
    messes ||--o{ fixed_costs : "has"
    messes ||--o{ individual_costs : "has"
    messes ||--o{ inventory : "tracks"
    messes ||--o{ meal_cutoff_config : "configures"
    messes ||--o{ activity_log : "logs"
    messes ||--o{ announcements : "posts"
    mess_cycles ||--o{ daily_meals : "contains"
    mess_cycles ||--o{ transactions : "records"
    mess_cycles ||--o{ bazaar_expenses : "tracks"
    mess_cycles ||--o{ fixed_costs : "includes"
    mess_cycles ||--o{ individual_costs : "includes"
    mess_cycles ||--o{ month_snapshots : "archives"
    mess_members ||--o{ daily_meals : "logs"
    mess_members ||--o{ transactions : "makes"
    mess_members ||--o{ individual_costs : "incurs"
    bazaar_expenses ||--o{ bazaar_items : "contains"

    profiles {
        uuid id PK
        text full_name
        text email
        text phone
        text avatar_url
    }

    messes {
        uuid id PK
        text name
        text address
        uuid created_by FK
        text invite_code
        int max_members
    }

    mess_members {
        uuid id PK
        uuid mess_id FK
        uuid user_id FK
        user_role role
        user_status status
        date join_date
        date leave_date
    }

    mess_cycles {
        uuid id PK
        uuid mess_id FK
        text name
        date start_date
        date end_date
        cycle_status status
        numeric final_meal_rate
    }

    daily_meals {
        uuid id PK
        uuid mess_id FK
        uuid cycle_id FK
        uuid member_id FK
        date meal_date
        boolean breakfast
        boolean lunch
        boolean dinner
        int guest_breakfast
        int guest_lunch
        int guest_dinner
    }

    transactions {
        uuid id PK
        uuid mess_id FK
        uuid cycle_id FK
        uuid member_id FK
        numeric amount
        payment_method method
        text reference_no
    }

    bazaar_expenses {
        uuid id PK
        uuid mess_id FK
        uuid cycle_id FK
        uuid shopper_id FK
        date expense_date
        numeric total_amount
    }

    bazaar_items {
        uuid id PK
        uuid expense_id FK
        text item_name
        numeric quantity
        text unit
        numeric unit_price
        numeric total_price
    }

    fixed_costs {
        uuid id PK
        uuid mess_id FK
        uuid cycle_id FK
        fixed_cost_type cost_type
        numeric amount
    }

    individual_costs {
        uuid id PK
        uuid mess_id FK
        uuid cycle_id FK
        uuid member_id FK
        text description
        numeric amount
        approval_status status
    }

    inventory {
        uuid id PK
        uuid mess_id FK
        text item_name
        numeric current_qty
        text unit
    }

    month_snapshots {
        uuid id PK
        uuid cycle_id FK
        uuid member_id FK
        int total_meals
        numeric meal_rate
        numeric closing_balance
    }

    meal_cutoff_config {
        uuid id PK
        uuid mess_id FK
        time breakfast_cutoff
        time lunch_cutoff
        time dinner_cutoff
    }

    activity_log {
        uuid id PK
        uuid mess_id FK
        uuid actor_id FK
        text action
        jsonb details
    }

    announcements {
        uuid id PK
        uuid mess_id FK
        text title
        text content
        text priority
    }
Loading

๐Ÿ’ธ The Balance Formula

graph LR
    A["๐Ÿ’ต Opening Balance<br/><i>from previous month</i>"] --> E
    B["โž• Deposits<br/><i>cash, bKash, Nagad</i>"] --> E
    E["๐Ÿ“Š Credits"] --> F

    C1["๐Ÿฝ๏ธ Meals ร— Rate"] --> G
    C2["๐Ÿ  Prorated Fixed Costs<br/><i>rent, gas, wifi...</i>"] --> G
    C3["๐Ÿ‘ค Individual Costs"] --> G
    G["๐Ÿ“‰ Debits"] --> F

    F["๐Ÿ’ฐ Current Balance<br/><i>=  Credits - Debits</i>"]

    style A fill:#22c55e,stroke:#16a34a,color:#fff
    style B fill:#22c55e,stroke:#16a34a,color:#fff
    style E fill:#3b82f6,stroke:#2563eb,color:#fff
    style C1 fill:#ef4444,stroke:#dc2626,color:#fff
    style C2 fill:#ef4444,stroke:#dc2626,color:#fff
    style C3 fill:#ef4444,stroke:#dc2626,color:#fff
    style G fill:#f97316,stroke:#ea580c,color:#fff
    style F fill:#8b5cf6,stroke:#7c3aed,color:#fff
Loading
Balance = (Opening + Deposits) โˆ’ (Meals ร— Rate + Fixed Costs + Individual Costs)

โšก Month Close Flow

sequenceDiagram
    participant M as ๐Ÿ‘ค Manager
    participant S as โš™๏ธ Server Action
    participant DB as ๐Ÿ—„๏ธ PostgreSQL

    M->>S: Click "Close Month"
    S->>DB: BEGIN TRANSACTION
    
    Note over DB: ๐Ÿ”’ Lock cycle row (FOR UPDATE)
    
    DB->>DB: Calculate final meal rate
    DB->>DB: Snapshot every member's balance
    DB->>DB: Archive current cycle โ†’ 'closed'
    DB->>DB: Create next month's cycle
    DB->>DB: Log activity
    
    DB->>S: COMMIT โ†’ Return new_cycle_id
    S->>M: โœ… "Month closed successfully!"
    
    Note over M,DB: ๐ŸŽ‰ All atomic โ€” if anything<br/>fails, everything rolls back!
Loading

๐Ÿ› ๏ธ Tech Stack

Layer Technology Why
โš›๏ธ Frontend Next.js 16 + React 19 App Router, Server Actions, Turbopack
๐ŸŽจ Styling Tailwind CSS v4 + shadcn/ui Beautiful, consistent, accessible
๐Ÿ—„๏ธ Database Supabase (PostgreSQL) RLS, Triggers, RPCs, Realtime
๐Ÿ” Auth Supabase Auth Email/Password + Google OAuth
๐Ÿ“Š Charts Recharts Interactive, responsive visualizations
๐Ÿ“„ PDF jsPDF + AutoTable Generate reports client-side
๐Ÿ“ฆ State React Query (TanStack) Smart caching, auto-refetch
โœ… Validation Zod Runtime type safety
๐Ÿš€ Deploy Vercel Zero-config, edge-optimized
๐Ÿ“ฑ PWA Web Manifest Installable, native-like

๐Ÿ“ Project Structure

kangal-app/
โ”œโ”€โ”€ ๐ŸŒ public/
โ”‚   โ”œโ”€โ”€ manifest.json              # PWA configuration
โ”‚   โ””โ”€โ”€ icons/                     # App icons (192ร—192, 512ร—512)
โ”‚
โ”œโ”€โ”€ ๐Ÿ“ฆ src/
โ”‚   โ”œโ”€โ”€ ๐Ÿ—‚๏ธ app/
โ”‚   โ”‚   โ”œโ”€โ”€ (auth)/                # ๐Ÿ”‘ Login, Signup, Forgot Password
โ”‚   โ”‚   โ”œโ”€โ”€ auth/callback/         # ๐Ÿ”„ OAuth callback handler
โ”‚   โ”‚   โ”œโ”€โ”€ dashboard/             # ๐Ÿ“Š Main app
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ page.tsx           # ๐Ÿ  Dashboard overview
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ meals/             # ๐Ÿฝ๏ธ Meal toggles + chart + manage
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ bazaar/            # ๐Ÿ›’ Bazaar expense logs
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ deposits/          # ๐Ÿ’ฐ Deposit management
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ options/           # โš™๏ธ Cycle & mess settings
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ settings/          # ๐Ÿ‘ค User profile settings
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ admin/             # ๐Ÿ‘‘ Manager-only
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ costs/         # ๐Ÿ’ธ Fixed & individual costs
โ”‚   โ”‚   โ”‚       โ”œโ”€โ”€ members/       # ๐Ÿ‘ฅ Member management
โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ month-close/   # ๐Ÿ“‹ Monthly settlement
โ”‚   โ”‚   โ””โ”€โ”€ page.tsx               # ๐Ÿ  Landing page (marketing)
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿงฉ components/
โ”‚   โ”‚   โ”œโ”€โ”€ dashboard/             # Stats cards, charts, meal toggles
โ”‚   โ”‚   โ”œโ”€โ”€ landing/               # Animated hero, feature cards
โ”‚   โ”‚   โ”œโ”€โ”€ mess-context.tsx       # ๐Ÿ”— Shared context (perf optimization)
โ”‚   โ”‚   โ””โ”€โ”€ ui/                    # shadcn/ui primitives
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ ๐Ÿ“š lib/
โ”‚   โ”‚   โ”œโ”€โ”€ actions/               # Server actions (meals, bazaar, finance)
โ”‚   โ”‚   โ”œโ”€โ”€ supabase/              # Client & middleware setup
โ”‚   โ”‚   โ”œโ”€โ”€ pdf-export.ts          # PDF generation logic
โ”‚   โ”‚   โ””โ”€โ”€ validations.ts         # Zod schemas
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ ๐Ÿ“ types/                  # TypeScript type definitions
โ”‚
โ””โ”€โ”€ ๐Ÿ—„๏ธ supabase/
    โ”œโ”€โ”€ schema.sql                 # Complete DB schema (14 tables, RLS, triggers)
    โ”œโ”€โ”€ migration_fixes.sql        # Post-deploy fixes
    โ””โ”€โ”€ migration_approval_system.sql  # Approval workflow

๐Ÿ”’ Security Model

graph TD
    subgraph Auth ["๐Ÿ” Authentication"]
        A1["Supabase Auth<br/><i>JWT Tokens</i>"]
        A2["Next.js Middleware<br/><i>Route Protection</i>"]
    end

    subgraph RLS ["๐Ÿ›ก๏ธ Row Level Security"]
        R1["is_mess_member()"]
        R2["is_mess_manager()"]
    end

    subgraph Policies ["๐Ÿ“œ Access Policies"]
        P1["Members โ†’ own mess data only"]
        P2["Managers โ†’ full CRUD"]
        P3["Cross-mess โ†’ impossible"]
    end

    A1 --> A2
    A2 --> R1
    A2 --> R2
    R1 --> P1
    R2 --> P2
    R1 --> P3

    style Auth fill:#1a1a2e,stroke:#FF6B6B,color:#fff
    style RLS fill:#16213e,stroke:#FFA94D,color:#fff
    style Policies fill:#0f3460,stroke:#3FCF8E,color:#fff
Loading
  • Every table has RLS enabled โ€” no data leaks between messes
  • Server-side auth via Supabase SSR middleware
  • No secrets in client โ€” all sensitive operations are Server Actions
  • Atomic transactions โ€” month closing uses SECURITY DEFINER RPCs

๐Ÿš€ Getting Started

Prerequisites

  • Node.js 18+ and npm
  • A Supabase project (free tier works!)

Quick Setup

# 1๏ธโƒฃ Clone the repo
git clone https://github.com/sovon1/kangal-app.git
cd kangal-app

# 2๏ธโƒฃ Install dependencies
npm install

# 3๏ธโƒฃ Set up environment variables
cp .env.local.example .env.local
# Edit .env.local with your Supabase URL and anon key

# 4๏ธโƒฃ Set up the database
# Copy supabase/schema.sql โ†’ Supabase SQL Editor โ†’ Run

# 5๏ธโƒฃ Start the dev server
npm run dev

Open http://localhost:3000 and you're live! ๐ŸŽ‰

Environment Variables

Variable Description
NEXT_PUBLIC_SUPABASE_URL Your Supabase project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY Your Supabase anonymous key

๐Ÿ“ฑ Install as App (PWA)

๐Ÿ“ฑ Open kangal.software on your phone
     โ†“
๐Ÿ“ฅ Tap "Add to Home Screen"
     โ†“
๐Ÿš€ Done! Works like a native app!

๐Ÿงฎ Database Stored Procedures

Function Purpose
calculate_meal_rate(cycle_id) ฮฃ Bazaar รท ฮฃ Meals โ€” the core formula
prorate_fixed_costs(member_id, cycle_id) Fair share based on days present
calculate_member_balance(member_id, cycle_id) Full financial breakdown
close_mess_month(cycle_id) Atomic month close (snapshot โ†’ archive โ†’ new cycle)
enforce_meal_cutoff() Trigger: blocks meal changes after cutoff (managers bypass)
deduct_inventory_on_bazaar() Auto-updates inventory on bazaar entry
update_bazaar_total() Auto-recalculates expense totals

๐Ÿ“Š Enum Types

user_role         โ†’ 'manager' | 'member' | 'cook'
user_status       โ†’ 'active' | 'inactive' | 'on_leave'
payment_method    โ†’ 'cash' | 'bkash' | 'nagad' | 'bank_transfer' | 'other'
approval_status   โ†’ 'pending' | 'approved' | 'rejected'
cycle_status      โ†’ 'open' | 'closed' | 'archived'
fixed_cost_type   โ†’ 'cook_salary' | 'wifi' | 'gas' | 'electricity' | 'water' | 'rent' | ...

๐Ÿค Contributing

Contributions are welcome! Feel free to:

  1. ๐Ÿด Fork the repo
  2. ๐ŸŒฟ Create a branch (git checkout -b feature/amazing-feature)
  3. ๐Ÿ’พ Commit changes (git commit -m 'Add amazing feature')
  4. ๐Ÿ“ค Push (git push origin feature/amazing-feature)
  5. ๐Ÿ”ƒ Open a Pull Request

๐Ÿ“ License

This project is open source under the MIT License.


Built with โค๏ธ for mess-er เฆญเฆพเฆ‡เฆฐเฆพ everywhere.

"เฆฎเงเฆฏเฆพเฆจเง‡เฆœเฆพเฆฐ เฆคเงเฆฎเฆฟ เฆŸเฆพเฆ•เฆพ เฆฎเฆพเฆฐเฆ›เง‹ โ€” เฆเฆ‡ เฆ•เฆฅเฆพ เฆถเงเฆจเฆคเง‡ เฆนเฆฌเง‡ เฆจเฆพ เฆ†เฆฐเฅค" ๐Ÿ•


Try KANGAL

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors