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:
167
prompts.txt
Normal file
167
prompts.txt
Normal file
@ -0,0 +1,167 @@
|
||||
|
||||
# AvtoAmbor — Auto Parts Inventory System (v1 scaffold)
|
||||
|
||||
## Context
|
||||
Build a simple, single-user inventory system named "AvtoAmbor" for an auto parts
|
||||
store in Tajikistan. Development is on Linux inside Docker; the production target
|
||||
is a Windows machine where the owner will access it via browser on localhost.
|
||||
v1 is PARTS ONLY — no service jobs, customers, or invoicing.
|
||||
|
||||
Do not write tests, lint config, or CI in this pass. Keep the code idiomatic,
|
||||
lightly commented, and not over-engineered.
|
||||
|
||||
## Tech stack (strict)
|
||||
- Node.js 20 LTS, run via Docker
|
||||
- SQLite via `better-sqlite3`
|
||||
- SvelteKit 2.x pinned to **Svelte 4** — `"svelte": "^4.2.0"` in package.json.
|
||||
Use Svelte 4 syntax only: no runes, no `$state`/`$derived`/`$effect`.
|
||||
- `@sveltejs/adapter-node` for production (so deployment to Windows is just
|
||||
`node build/index.js`)
|
||||
- Plain CSS. No Tailwind, no component library.
|
||||
|
||||
## Repo layout
|
||||
avtoambor/
|
||||
Makefile
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
.gitignore
|
||||
README.md
|
||||
package.json
|
||||
svelte.config.js
|
||||
vite.config.js
|
||||
src/
|
||||
app.html
|
||||
hooks.server.js # opens db on startup
|
||||
lib/
|
||||
server/
|
||||
db.js # better-sqlite3, WAL mode, foreign keys on
|
||||
schema.sql
|
||||
seed.sql
|
||||
parts.js # CRUD helpers
|
||||
movements.js
|
||||
suppliers.js
|
||||
i18n/
|
||||
en.json
|
||||
tg.json
|
||||
store.js # locale store + t(key) helper
|
||||
components/
|
||||
Header.svelte # "AvtoAmbor" wordmark + EN/Тоҷ toggle
|
||||
routes/
|
||||
+layout.svelte # renders <Header/>
|
||||
+page.svelte # dashboard
|
||||
parts/
|
||||
+page.svelte # list, search, sort
|
||||
+page.server.js
|
||||
new/
|
||||
+page.svelte
|
||||
+page.server.js
|
||||
[id]/
|
||||
+page.svelte # edit + recent movements
|
||||
+page.server.js
|
||||
movements/
|
||||
new/
|
||||
+page.svelte
|
||||
+page.server.js
|
||||
suppliers/
|
||||
+page.svelte
|
||||
+page.server.js
|
||||
data/ # gitignored; holds avtoambor.db
|
||||
scripts/
|
||||
init-db.js # reads schema.sql + seed.sql, writes data/avtoambor.db
|
||||
|
||||
## Database schema (initial guess — we will iterate)
|
||||
- All translated fields use `_en` and `_tg` suffixes.
|
||||
- Money stored as INTEGER dirams (1 TJS = 100 dirams).
|
||||
- Timestamps as ISO 8601 TEXT (`datetime('now')`).
|
||||
|
||||
Tables:
|
||||
- categories(id PK, name_en, name_tg, sort_order)
|
||||
- suppliers(id PK, name, phone, address, notes, created_at)
|
||||
- parts(id PK, sku UNIQUE NOT NULL, name_en, name_tg,
|
||||
description_en, description_tg, category_id FK,
|
||||
unit TEXT, cost_price INT, sale_price INT,
|
||||
quantity_on_hand INT DEFAULT 0, reorder_level INT DEFAULT 0,
|
||||
location TEXT, barcode TEXT, active INT DEFAULT 1,
|
||||
created_at, updated_at)
|
||||
- stock_movements(id PK, part_id FK, movement_type
|
||||
CHECK(movement_type IN ('in','out','adjust')),
|
||||
quantity INT, unit_price INT,
|
||||
supplier_id FK NULL, reference TEXT, notes TEXT,
|
||||
created_at)
|
||||
|
||||
Indexes on parts.sku, parts.barcode, parts.category_id, stock_movements.part_id.
|
||||
|
||||
Update `parts.quantity_on_hand` in application code (in a transaction with
|
||||
the movement insert), not via trigger — clearer for future-me.
|
||||
|
||||
## Seed data
|
||||
- 5–6 categories: Filters, Brakes, Engine, Electrical, Fluids, Belts & Hoses
|
||||
- 3–4 suppliers with realistic names
|
||||
- 25–30 realistic auto parts with EN and Tajik (Cyrillic) names.
|
||||
Bias toward parts common for Lada, Daewoo Nexia, Opel, and Toyota,
|
||||
which are common in Tajikistan. Use realistic somoni prices.
|
||||
|
||||
## UI
|
||||
- `Header.svelte` (in `+layout.svelte`, every page):
|
||||
- Left: "AvtoAmbor" wordmark
|
||||
- Right: language toggle showing the *other* language (click EN → switches to
|
||||
Tajik). Persist choice to `localStorage` under key `avtoambor.locale`.
|
||||
- Pages for v1:
|
||||
- `/` dashboard: total SKUs, count of parts at/below reorder level,
|
||||
total inventory value at cost
|
||||
- `/parts` searchable + sortable list
|
||||
- `/parts/new` create
|
||||
- `/parts/[id]` edit, with recent movements panel
|
||||
- `/movements/new` record in/out/adjust
|
||||
- `/suppliers` list + add inline
|
||||
- Every visible string goes through the i18n helper. Missing keys fall back to
|
||||
English and log a `console.warn` once per missing key.
|
||||
GIve it a Tajik look & feel, if that's even possible for such a simple app
|
||||
|
||||
## i18n
|
||||
- `en.json` and `tg.json` with nested keys (e.g. `nav.parts`, `parts.sku`)
|
||||
- `store.js` exports a writable `locale` store and a derived `t` function:
|
||||
`$t('parts.sku')` in templates
|
||||
- Default locale is `'tg'`. On mount in the layout, read `localStorage` and
|
||||
hydrate if present.
|
||||
|
||||
## Makefile
|
||||
Targets (use `docker compose`). First target = `help`.
|
||||
- `help` — print a friendly banner + list of targets with descriptions
|
||||
- `install` — `docker compose run --rm app npm install`
|
||||
- `run` — `docker compose up` (dev server on 5173)
|
||||
- `build` — production build via adapter-node into `build/`
|
||||
- `db-init` — run `scripts/init-db.js`, skip if `data/avtoambor.db` exists
|
||||
- `db-reset` — confirm prompt, then delete and recreate the db
|
||||
- `docker-build` — build the image
|
||||
- `docker-shell` — interactive bash in the container
|
||||
- `clean` — remove `node_modules`, `build/`, but keep `data/`
|
||||
- `clean-all` — also wipe `data/`
|
||||
|
||||
Use `@` to suppress command echo where it would be noise.
|
||||
|
||||
## Dockerfile
|
||||
- `node:20-bookworm-slim`
|
||||
- Install `python3 make g++` for the `better-sqlite3` native build
|
||||
- Non-root user
|
||||
- WORKDIR `/app`
|
||||
- EXPOSE 5173 and 3000
|
||||
|
||||
## docker-compose.yml
|
||||
- One service `app`
|
||||
- Bind-mount the repo to `/app`
|
||||
- Named volume for `node_modules` so it doesn't shadow the host
|
||||
- Bind-mount `./data` so the SQLite file persists on the host
|
||||
- Map 5173:5173 and 3000:3000
|
||||
|
||||
## README.md
|
||||
Short: what it is, prerequisites (Docker), quickstart
|
||||
(`make install && make db-init && make run`), and a one-liner on production:
|
||||
`make build` then `node build/index.js` on the Windows host.
|
||||
|
||||
## Deliverables for this pass
|
||||
1. Generate every file above, working out of the box.
|
||||
2. Print the resulting file tree.
|
||||
3. Print the exact command sequence to bring it up from a fresh clone.
|
||||
4. Call out anything you guessed at that I should review before we move on.
|
||||
Reference in New Issue
Block a user