尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证kotasa by VIMMIK - Share it. Settle it.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Share it. Settle it. Shared expenses for offices, friends, trips and families. Anyone pays, Kotasa keeps count, and everyone settles once a week. කොටස (kotasa) means "a share" in Sinhala. In most offices and friend groups, one person buys lunch, another pays for the Uber, someone else picks up the birthday cake. By Friday nobody remembers who owes whom.查看完整 README ↗
Share it. Settle it.
Shared expenses for offices, friends, trips and families. Anyone pays, Kotasa keeps count, and everyone settles once a week.
කොටස (kotasa) means "a share" in Sinhala.
In most offices and friend groups, one person buys lunch, another pays for the Uber, someone else picks up the birthday cake. By Friday nobody remembers who owes whom.
Kotasa writes every shared cost down, splits it fairly, and nets it into one clear amount per person. Each week, everyone gets an SMS with their total and a link that shows exactly where each rupee came from, whether or not they use the app.
| Benefit | What it means |
|---|---|
| No more "who paid?" | Every cost records who paid and who it was for. |
| Fair to the cent | Equal splits are worked out exactly. Leftover cents never go missing. |
| Fewer payments | What you owe a person is netted against what they owe you. |
| Works for everyone | People without the app still get the weekly SMS and a read-only bill. |
| Nothing gets lost | Unpaid balances carry over to the next week automatically. |
Every expense share, meal order, SMS fee and payment becomes one ledger line: A owes B an amount.
The database function pair_balances() nets those lines for each pair of people, so the app can show
simple instructions such as "Pay Nimal Rs. 450". Every number can be traced back to the entries behind it.
A payment from A to B is stored as B owes A, which cancels A's debt.
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router, Cache Components, server actions), React 19, TypeScript |
| Styling | Tailwind CSS v4 (CSS-first config), Phosphor icons, self-hosted Geist font |
| Data and auth | Supabase: Postgres, Auth, row-level security |
| Hosting | Vercel, with Supabase pg_cron calling the weekly SMS route every hour |
| SMS | Text.lk (Sri Lanka). Notify.lk is also supported. |
git clone https://github.com/kavishkadinajara/kotasa.git
cd kotasa
npm install
cp .env.example .env.local # then fill in the values below
Apply the SQL files in supabase/migrations/ in filename order, either with the Supabase CLI
(supabase db push) or by running them in the SQL editor.
In Supabase, go to Authentication → URL Configuration and set:
<your-app>/auth/callback and http://localhost:3000/auth/callbacknpm run dev
Open http://localhost:3000/setup to create the first account and the first group.
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase publishable key |
SUPABASE_SERVICE_ROLE_KEY | Supabase secret key. Server only, never expose it. |
NEXT_PUBLIC_APP_URL | Public URL of the app, used in bill links and sign-in redirects |
AUTH_EMAIL_DOMAIN | Internal email domain for PIN logins (for example kotasa.local) |
NEXT_PUBLIC_GOOGLE_LOGIN | on shows the Google button, off hides it |
CRON_SECRET | Bearer token pg_cron sends to /api/cron/weekly-sms (also stored in Supabase Vault) |
SMS_PROVIDER | textlk (default) or notifylk |
TEXTLK_API_KEY, TEXTLK_SENDER_ID | Text.lk API token and approved sender ID |
NOTIFY_USER_ID, NOTIFY_API_KEY, NOTIFY_SENDER_ID | Only needed when SMS_PROVIDER=notifylk |
.env.example has a template.
NEXT_PUBLIC_APP_URL to the production URL./api/cron/weekly-sms every hour at :30 UTC (:00 in Sri Lanka). Each group is only
messaged on its own billing day, from its send hour. In the Supabase SQL editor, store the URL and secret once:
select vault.create_secret('https://<app domain>', 'kotasa_app_url'); and
select vault.create_secret('<CRON_SECRET>', 'kotasa_cron_secret');. Without them the job does nothing.https://<project-ref>.supabase.co/auth/v1/callback.NEXT_PUBLIC_GOOGLE_LOGIN=on and redeploy.TEXTLK_API_KEY. Use TEXTLK_SENDER_ID=TextLKDemo until your own sender ID is approved./b/<token>) shows one member's data only, and is excluded from search engines.src/proxy.ts session refresh and login redirect
src/app/
groups/ join/[code]/ your groups, create a group, accept an invite
g/[slug]/ one group: home, expenses, meals, budgets, settle, account, guide, admin
b/[token]/ public read-only bill
api/cron/weekly-sms/ scheduled weekly SMS
actions/ server actions: every write, each with permission checks
src/lib/ auth, ledger, SMS, permissions, group config, dates, money helpers
src/components/ UI components
supabase/migrations/ schema, ledger view, pair_balances(), RLS
npm run dev # start the dev server
npx next typegen && npx tsc --noEmit # type-check
npx eslint src # lint
npm run build # production build
node scripts/make-icons.mjs # regenerate app icons after changing the logo
Built by Vimmik
© 2026 Vimmik. All rights reserved.