Initial scaffold for AvtoAmbor parts inventory
SvelteKit 2 + Svelte 4 + adapter-node, SQLite via better-sqlite3 (WAL, foreign keys on). Bilingual EN/Тоҷикӣ throughout, locale persisted in localStorage. Pages: dashboard (totals, low stock, recent movements), parts list with search and sort, part create/edit, record movement (in/out/adjust with smart unit-price and adjust-quantity prefill), suppliers list with inline add. Schema: categories, suppliers, parts (with _en/_tg name+description columns, dirams for money), stock_movements with check on movement_type. On-hand updates are done in JS inside a transaction with the movement insert. Dockerized dev: docker compose, named project, bind-mounted data/ for DB persistence. Seed contains 6 categories, 4 suppliers, 31 realistic parts (Lada / Nexia / Opel / Toyota bias). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
56
src/lib/server/schema.sql
Normal file
56
src/lib/server/schema.sql
Normal file
@ -0,0 +1,56 @@
|
||||
-- AvtoAmbor schema. Money is stored as INTEGER dirams (1 TJS = 100 dirams).
|
||||
-- Translated fields use _en / _tg suffixes.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS categories (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name_en TEXT NOT NULL,
|
||||
name_tg TEXT NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS suppliers (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
phone TEXT,
|
||||
address TEXT,
|
||||
notes TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS parts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sku TEXT NOT NULL UNIQUE,
|
||||
name_en TEXT NOT NULL,
|
||||
name_tg TEXT NOT NULL,
|
||||
description_en TEXT,
|
||||
description_tg TEXT,
|
||||
category_id INTEGER REFERENCES categories(id) ON DELETE SET NULL,
|
||||
unit TEXT NOT NULL DEFAULT 'pcs',
|
||||
cost_price INTEGER NOT NULL DEFAULT 0, -- dirams
|
||||
sale_price INTEGER NOT NULL DEFAULT 0, -- dirams
|
||||
quantity_on_hand INTEGER NOT NULL DEFAULT 0,
|
||||
reorder_level INTEGER NOT NULL DEFAULT 0,
|
||||
location TEXT,
|
||||
barcode TEXT,
|
||||
active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS stock_movements (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
part_id INTEGER NOT NULL REFERENCES parts(id) ON DELETE CASCADE,
|
||||
movement_type TEXT NOT NULL CHECK(movement_type IN ('in','out','adjust')),
|
||||
quantity INTEGER NOT NULL, -- positive for in/adjust-up, negative for out/adjust-down
|
||||
unit_price INTEGER, -- dirams; nullable for adjustments
|
||||
supplier_id INTEGER REFERENCES suppliers(id) ON DELETE SET NULL,
|
||||
reference TEXT,
|
||||
notes TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_parts_sku ON parts(sku);
|
||||
CREATE INDEX IF NOT EXISTS idx_parts_barcode ON parts(barcode);
|
||||
CREATE INDEX IF NOT EXISTS idx_parts_category ON parts(category_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_movements_part ON stock_movements(part_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_movements_created ON stock_movements(created_at);
|
||||
Reference in New Issue
Block a user