個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證💎 Sooda — Liquid-glass profit, price & discount calculator. Offline-first PWA, bilingual (EN/FA), zero dependencies on servers.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
You made 20% profit — but can you still afford to restock? Sooda answers that question. A profit, price and discount calculator for sellers. Works fully offline, speaks English and فارسی, and tracks nothing. Sixty seconds, no narration: the 20% that turns out to be 10.32% once you try to restock, the suggested price that puts the shelf back the way it was, and the health chip that tells you whether a product is still worth selling.檢視完整 README ↗
You made 20% profit — but can you still afford to restock? Sooda answers that question.
A profit, price and discount calculator for sellers. Works fully offline, speaks English and فارسی, and tracks nothing.
Sixty seconds, no narration: the 20% that turns out to be 10.32% once you try to restock, the suggested price that puts the shelf back the way it was, and the health chip that tells you whether a product is still worth selling.
https://github.com/user-attachments/assets/3dbf0248-3ff3-4caf-a576-fc36ea4ead07
The loop above is silent — press play for the whole sixty seconds, with sound. The interface in it is drawn rather than screen-recorded; the real thing is one click away at mahdi-mortazavi.github.io/sooda, and it opens with no account and no install. The file is in the repo as docs/marketing/sooda-film.mp4.
It's 9pm and Reza is pulling down the shutter. He sold ten shawls today, each at 20% profit, and he's pleased. He bought them three months ago at 400,000 toman each.
The next morning his wholesaler calls: prices are up. Only now does he realise that the money from those ten shawls will not buy ten shawls. His profit looked like 80,000 each — but restocking the same shawl now costs about 442,203. Of that 20%, roughly 8.55% is actually left.
That is the moment Sooda is built for. Reza enters his purchase and selling price, and next to the nominal profit Sooda shows the real profit — flagged as thin, with a suggested price that covers buying the goods again.
That afternoon a customer wants a 10,000,000 item on instalments. Reza opens "Is my deal profitable?" and finds that the flat 2%/month he has always charged now barely breaks even — a 0.12% loss, which is to say he is working for free. He fixes the number, and sends the customer a payment schedule with no mention of his own margin.
And the imported item priced in dollars? Sooda estimates a monthly price-growth rate for each product separately — and tells him where that number came from.
Selling price 480,000 · Profit 80,000.
That's it. The rest of this guide is about what Sooda does beyond that.
When is it for? The first time you open Sooda, and any time afterwards that you want to learn a part of it. There is nothing to read — you work on the real buttons.
What to do
Example — the first exercise: Reza bought a shawl for 100,000 and wants 20% profit. Four taps later you see that if the same shawl sits on his shelf for three months, that 20% on paper is really under 10%. The whole thing takes about a minute.
Tip — all of it happens in a practice shop: five sample products made only for the lesson and deleted when it ends. Your own products, prices and history are never touched. If you get stuck, "Show me" does the step in front of you.
There are eight lessons — profit percentage, discounts, real profit, instalments, products, smart rates, everyday use, and backups — each 50 to 90 seconds. Each ends with a small question, marked by Sooda's own calculation engine, and a wrong answer is never called wrong: you just try again.
When you need it — you know what you paid and want to sell at a set margin.
What to do — open Profit %, enter Purchase price and Desired profit, tap Calculate.
Example — a 400,000 shawl at 20%: selling price 480,000, profit 80,000.
Tip — that's the nominal profit. For what's left after restocking, use the real-profit lens below.
When you need it — a price is already on the item and you want to know the margin.
What to do — open Selling price, enter Purchase price and Selling price, tap Calculate.
Example — bought 400,000, sold 480,000: 20%, i.e. 80,000.
Tip — a loss is flagged in words as well as colour ("You're losing money at this price."), never colour alone.
When you need it — running a sale, or working out what the original price was.
What to do — open Discount (or Reverse discount), enter the price and the percentage, tap Calculate.
Example — 15% off 480,000: final price 408,000, saved 72,000. And back the other way: a 408,000 price that was 15% off started at 480,000.
Tip — reverse discount is the quick way to check an advertised "70% off".
When you need it — always. This is the heart of Sooda.
What to do
Example — the 400,000 shawl sold at 480,000, money back in 3 months:
| Monthly inflation | 3.4% |
| Restock cost (estimate) | about 442,203 |
| Real profit | about 8.55% — thin |
| Suggested price | about 530,644 |
Tip — the default inflation figure comes from the Statistical Center of Iran and can be changed in Settings. If your wholesaler has quoted you a new price, enter that instead — it beats any estimate.
When you need it — selling on instalments without quietly losing money.
What to do
Example 1 — How much should I add? A 10,000,000 item, 4,000,000 down, 6 payments:
| Monthly payment | 1,122,313 |
| Total collected | 10,733,880 |
| Markup needed | about 7.34% |
| Equivalent flat monthly | about 2.04% |
Example 2 — Is my deal profitable? The same item at the flat 2%/month many shops charge: payments of 1,120,000, but worth only 9,987,633 today — about a 0.12% loss against selling for cash. Barely break-even.
Tip — open the payment schedule and send it to the customer: every date and amount in the Persian calendar, with nothing about your margin.
When you need it — you carry dozens of lines and don't want prices drifting behind costs.
What to do
Example — the same shawl, three months after its cost was last recorded: restock cost about 442,203, real margin about 8.55%, health chip thin.
Tip — bulk reprice has a 10-second undo. Rounding always goes up, so margin is never lost: 530,643.5 with a 5,000 step becomes 535,000.
When you need it — when you want the inflation estimate to fit your product rather than one national number for the whole market.
What to do
Example — a product with three purchase prices recorded over six months (320,000 · 355,000 · 400,000):
| Price growth | about 4.11% a month |
| From your own prices | 60% |
| Estimate quality | medium |
| Restock cost today (estimate) | about 416,453 |
Tip — "medium" means Sooda is blending your own prices with the national figures. Every purchase price you record sharpens it. For an imported product, Sooda separately shows how far the dollar has moved since your last purchase.
Backup — Settings → back up to a file before changing phones, then restore on the new one (merge or replace). Products, their price history, basket and settings are all in that file.
Settings — language, light/dark, currency, rounding, the inflation figure, Store profile, and automatic rate updates.
Tip — Erase all data really does erase everything: history, basket, products and their price history. Only language, theme and currency are kept.
Open Sooda in a browser. Android offers an install button; on iPhone use Share → Add to Home Screen. After the first load it works with no internet at all, and updates itself automatically — there is nothing to install by hand.
What is "real profit"? Nominal profit is selling price minus purchase price. Real profit is what's left once you've bought the same goods again. In a market where prices rise, the two are very different numbers.
Where does the price-growth rate come from, and how accurate is it? Three things: the purchase prices you record yourself, the inflation figure for your product's category, and the dollar (for imported goods). It is always an estimate — which is why Sooda says "about" everywhere, and why Why this number? breaks down where each part came from.
I don't know the inflation rate — is that a problem? No. Sooda ships with a default (currently 3.4% a month, from the Statistical Center of Iran — CPI, Mordad 1405). Change it in Settings if you have a better figure. And if you know the new purchase price, you don't need inflation at all: enter it directly.
Where is my data stored? On this device, and only here. No account, no server, and nothing from your device is ever sent. The only thing Sooda downloads is a public rates file from its own site — and you can turn that off in Settings.
What if I change phones? Back up to a file in Settings and restore it on the new phone. Because the data lives on the device, clearing your browser without a backup loses it.
How does the app update? Automatically. Sooda checks periodically and shows you what's new next time you open it.
Is it free? Yes — free and open source under the MIT licence.
| Profit % | Selling price (loss) | Discount |
|---|---|---|
| My products | Basket | History |
|---|---|---|
| Smart rate & "Why this number?" | Price check-in | Store profile |
|---|---|---|
| First launch | iOS install guide | Settings |
|---|---|---|
Mahdi Mortazavi · مهدی مرتضوی
Maker of Sooda — feedback, ideas and hellos all welcome.
May your work and trade be blessed 🌿✨
Contributions welcome — see CONTRIBUTING.md and the Code of Conduct. Released under the MIT licence.
React 18 · TypeScript (strict) · Vite 6 · Tailwind v4 · Dexie (IndexedDB) · i18next · motion · vite-plugin-pwa (Workbox).
src/lib/ as pure, UI-free, tested functions.src/lib/rates/: exponentially weighted least squares over
your recorded prices, blended with a category index and a dollar sensitivity, and held inside
a cautious −5%…+25% monthly band.public/data/rates.json) is deliberately not precached, so a daily rate
refresh doesn't push an app update to every installed device. See docs/rates.md.npm run docs:examples from the real engine.Size and performance (measured, not claimed) — first-paint payload is about 126 KB gzipped
(npm run budget). Lighthouse on this build scores accessibility 100 and
best practices 100. The Performance score is deliberately not quoted here: the local test
server has neither the gzip nor the cache headers GitHub Pages serves, so any number it produces
would be misleading.
npm install
npm run dev # dev server
npm run verify # typecheck + tests + build
npm run budget # first-paint payload ceiling
npm run docs:examples -- --check # do the README numbers still match the engine?