
# 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.



When I select Record Movement in the Parts page, can't we prepopulate the movement since we know the part?

ANd shouldn't some of the fields be defaulted to our best guess based on what we know about the part?


