A parallel stocktaking web application for SMACC ERP. It reads item data from a read-only SOURCE company database, lets warehouse teams scan, count, and amend items, then transfers the reconciled counts into a write-destination TARGET company database — without ever touching the source company's live data.
- Frontend — Next.js 15 (App Router) + React 19 + TypeScript + Tailwind CSS 4. Arabic-first, RTL, with a 5-language UI (العربية / English / اردو / বাংলা / हिन्दी).
- Backend — Python FastAPI JSON API over Microsoft SQL Server (
pyodbc, no ORM), JWT Bearer auth, inparallel_stocktake/.
The SOURCE company (default
42) is read-only. All counted quantities, price changes, item-metadata edits, and images are staged in the app and written only to the TARGET company (default43). The company pair — and a source + target warehouse — are chosen per session, and the backend enforces the invariant end to end.
- Barcode scanning & counting — scan an item, see every unit of measure with quantities and prices in one compact table, and record counts with keyboard-first entry.
- Deferred item edits — rename items, change barcodes, units, conversion factors, tax files, and categories; edits are queued and only applied to the target during transfer.
- Transfer pipeline (source → target) — pre-transfer review classifies items as new (created in target) vs. existing (updated), with a full transfer log and revert support.
- Item images — upload and view item photos, served via short-lived media-scoped tokens (the session JWT is never embedded in image URLs).
- Dashboard — inventory value for both companies, out-of-stock / low-stock drill-downs, and session statistics.
- Users, roles & permissions — admin / supervisor / counter roles plus a per-user, per-feature × per-action permission matrix.
- Audit trail — every operation is recorded (who did what, and when).
.
├── app/ # Next.js App Router (single-page shell)
├── components/ # One React component per view (scan, transfer, users, …)
├── context/ # AppStateContext: global state + 5-language dictionary
├── lib/ # api.ts (backend client + mappers), seed.ts (domain types)
├── docs/ # Arabic developer docs (architecture, screens, workflows, API)
└── parallel_stocktake/ # FastAPI backend (routers, services, SQL access, config)
The two applications are deliberately separated: backend code lives exclusively in
parallel_stocktake/, frontend code lives at the repo root. Each has its own AGENTS.md
with conventions for contributors.
- Node.js 20+ and npm
- Python 3.10+
- Microsoft SQL Server hosting the SMACC databases, plus ODBC Driver 17 or 18 for SQL Server
cd parallel_stocktake
python -m venv .venv && source .venv/bin/activate # Windows: start.bat does all of this
pip install -r requirements.txt
python -m uvicorn main:app --host 0.0.0.0 --port 8060 --reloadThe API is served under http://localhost:8060/api/v1 with a health probe at /healthz.
On first run the backend bootstraps its own STK_* tables (users, permissions, sessions,
counted items, edits, audit and transfer logs) inside the source company database and
creates a default admin account (admin / Admin@12345 — change it after first login).
Key environment variables (see parallel_stocktake/config.py
for the full list):
| Variable | Default | Purpose |
|---|---|---|
SMACC_SQL_SERVER |
SmaccDatabase |
SQL Server host/instance or client alias |
SMACC_SOURCE_COMPANY_ID |
1000064442 |
Source (read-only) company ID |
SMACC_TARGET_COMPANY_ID |
1000064443 |
Target (write) company ID |
SMACC_JWT_SECRET |
(dev sentinel) | Required in production — app refuses to boot with the default |
SMACC_APP_ENV |
development |
production enables hard startup checks |
SMACC_CORS_ORIGINS |
http://localhost:3000 |
Allowed frontend origins (comma-separated, never *) |
SMACC_APP_PORT |
8060 |
Backend port |
npm install
cp .env.example .env.local # then point NEXT_PUBLIC_API_URL at the backend
npm run devOpen http://localhost:3000. The frontend only needs one setting:
| Variable | Default | Purpose |
|---|---|---|
NEXT_PUBLIC_API_URL |
http://localhost:8060/api/v1 |
Base URL of the FastAPI JSON API |
npm run lint # eslint
npx tsc --noEmit # type-check
npm run build # production build- Single-page shell, no client routing —
app/page.tsxrendersLoginViewwhen unauthenticated, otherwise a sidebar shell that switches views gated by per-user permissions. - One API boundary —
lib/api.tsis the only module that talks to the backend. It maps backend payloads (PascalCase SQL rows, snake_case pydantic fields) into the camelCase domain types inlib/seed.ts; raw backend field names never reach components. - Global state —
context/AppStateContext.tsxowns the session (user, permissions, company pair, warehouses, counted items, queued edits), the theme, and the full translation dictionary. - Security — parameterized SQL throughout (no ORM), bcrypt password hashing, Bearer JWT with 8-hour lifetime, login rate limiting, server-side password policy, and explicit CORS origins.
| Location | Contents |
|---|---|
docs/ |
Arabic developer guide: architecture, screen specs, workflows, backend integration & API contract |
parallel_stocktake/README.md |
Backend deep-dive (Arabic): features, configuration, schema, troubleshooting |
AGENTS.md |
Frontend conventions and cross-system rules for contributors |
parallel_stocktake/AGENTS.md |
Backend conventions — read before touching backend code |
No license has been specified yet. All rights reserved by the repository owner.