Files
OMT-SM/README.md
T

101 lines
4.5 KiB
Markdown

# CRM OMT — Cash Collection Management System
A multi-shop POS / cash control / reconciliation web app for the typical
Lebanese cell-phone or mixed-retail shop that also runs an OMT and/or Whish
counter alongside repair and item sales.
## The problem
Most Lebanese cell shops don't just sell phones and do repairs — they also act
as **OMT and/or Whish agents**, sell **Alfa / Touch / Ogero** recharges, take
**EDL** bill payments, and swap between USD and LBP. All of that money flows
through one drawer, in two currencies, across multiple employees and shifts,
mixed with goods and repair income.
The result for the owner is the recurring "incompatible cash" pain: at the end
of the day the drawer doesn't match what the system *should* hold, and there
is no clear accountability per cashier or per shift.
## What this app gives the owner
- **Per-employee, per-shift accountability** with a blind close: the cashier
declares the cash count, the system computes what was expected, and any
variance is recorded against that exact shift.
- **Live variance panel** at end-of-shift (Expected / Counted / Δ in USD and LBP).
- **Owner overview tab** — open shifts, open alerts, today's gross, recent
closed-shift variances, and a 30-day cashier scorecard.
- **All money streams in one ledger** — OMT send/receive, Whish, Alfa/Touch/Ogero
recharge, EDL bill, FX swap, deposits/withdrawals, refunds, voids, mid-day
safe drops, repair, goods sale.
- **DB-enforced accounting**: atomic sale coupling, cash-movement sign guards,
voids reverse movements, idempotency keys, RLS by shop and role.
- **Alerts pipeline** for chronic shorts, void spikes, override spikes,
reconciliation backlog, after-hours activity, voucher write-offs, stock
shrinkage.
## Architecture
The schema started life on Supabase but the app **no longer uses Supabase at
runtime**. It runs against a self-hosted Postgres + a thin Express API:
- **DB:** `postgres:16-alpine` via [docker-compose.yml](docker-compose.yml).
The Supabase migrations under [`supabase/migrations/`](supabase/migrations/)
are replayed on first boot by [`server/db/init/01_run_migrations.sh`](server/db/init/01_run_migrations.sh),
preceded by an `auth.users` shim ([`00_auth_shim.sql`](server/db/init/00_auth_shim.sql))
so the original `auth.uid()` / RLS policies keep working.
- **API:** [`server/src/index.js`](server/src/index.js) — Express. Issues JWTs
with `bcrypt` + `jsonwebtoken`, opens a pooled connection per request, sets
`request.jwt.claim.*` and `SET LOCAL ROLE authenticated` so RLS evaluates
against the caller. Generic `/rpc/:fn` route forwards to `app.<fn>(...)`
SQL functions; `/from/:view` exposes an allow-listed set of read views.
- **Frontend:** Vite + React 18 + TypeScript + shadcn/ui + Tailwind. The
module at [`src/integrations/supabase/client.ts`](src/integrations/supabase/client.ts)
is **a drop-in shim** over [`src/lib/api.ts`](src/lib/api.ts) — same
`.auth`, `.rpc`, `.from(...)` surface, but talks to the Express server.
See [CLAUDE.md](CLAUDE.md) for the full design notes and conventions.
## Run it
```bash
# one-time
cp server/.env.example server/.env # set JWT_SECRET, etc.
npm install
npm --prefix server install
# day-to-day (DB + API + Web all together)
npm run dev:all
# DB → docker container crm_omt_db on :5432
# API → node server on :4000
# WEB → vite on :5173
# build the frontend
npm run build
# wipe & rebuild the DB (reruns migrations + reseeds the admin)
npm run db:reset
```
Default seed admin (override via env in [docker-compose.yml](docker-compose.yml)):
- email: `admin@local.test`
- password: `ChangeMe123!`
## Tech stack
React 18, TypeScript, Vite, shadcn/ui, Tailwind, TanStack Query, react-hook-form,
zod · Express 4, pg, bcrypt, jsonwebtoken · PostgreSQL 16 · Docker Compose.
💼 Employee Payment Reconciliation Dashboard
A mini web application built with React and Supabase that tracks daily collection vs deposit transactions for employees and enforces a carry-forward balance logic. If an employee's deposit on a given day is less than the collection amount, the shortfall is rolled over and must be cleared by future deposits. The app processes transaction data, maintains a running balance, and generates an intuitive dashboard to visualize employee payment behavior.
Key Features:
Fetch and display employee-wise transaction data
Calculate running outstanding balances per employee
Apply deposit payments to past shortfalls based on business rules
Built using React, TypeScript, and Supabase (PostgreSQL backend)