# Parts Drawer Labels Admin-only labelling system for sorting drawers and bags. Browse a part taxonomy, define a label per drawer, and print them onto sticker sheets. Lives at **`/admin/labels`** — in the admin menu as *Parts Labels*. --- ## Deploying The feature is already wired into `app/__init__.py`, `schema_upgrade.py` and `base.html`, so a normal pull is enough: ``` git pull ``` Restart LIM. The tables are created automatically at boot by `app/services/schema_upgrade.py`, and the taxonomy seeds itself the first time an admin opens the page. If you'd rather make the database change deliberately before restarting: ``` python migrate_add_part_labels.py ``` Optional extras: | What | Why | How | |------|-----|-----| | Rebrickable API key | Part lookup: numbers, names, artwork | `REBRICKABLE_API_KEY=...` in `.env`, or paste it into *Labels → Settings* | | ReportLab | PDF export button | `pip install reportlab` | Neither is required. Without them you type labels in by hand, upload your own images, and print from the browser. --- ## Why not Brickset? Brickset's API v3 covers sets, minifigs and instructions. It has **no parts endpoint**, so it can't supply part numbers, names or part images. [Rebrickable](https://rebrickable.com/api/) can, and a key is free. Brickset stays where it is, doing sets. ## Why not Brick Architect's labels? Tom Alphin's label PDFs and his category numbering are his own copyrighted work. This feature doesn't scrape, copy or redistribute them. What ships is a starter taxonomy built from standard LEGO/BrickLink part terminology, arranged in the same *style* of hierarchy, and completely editable — rename, renumber, recolour and restructure it from *Labels → Categories* so it matches how your drawers actually run. If you want his exact labels, download them from his site and use them; this is for generating your own. --- ## Day-to-day **Adding labels** - *New Label* — name, dimensions, part number, alternates, category, drawer, colour, image. - Or, with a Rebrickable key, search on the labels page and hit *Add label* on a result. It pulls the name, number and image, caches the image locally so printing works offline, then drops you on the edit form to set the drawer. **The `name` + `dimensions` split matters.** Name is the big bold line ("Brick", "Plate, Modified with Clip"); dimensions is the geometry ("2 x 4"). They're printed together but stored apart so you can turn dimensions off for mixed drawers. **Alternate part numbers** are for old moulds that live in the same drawer — `3001a, 3001b`. Comma separated, searchable, optionally printed. **Printing** 1. Tick labels (or *Print whole category*). 2. Pick a sheet, set the options, hit *Update preview*. 3. Print from the browser: **margins None, scale 100%** — not "Fit to page", which is what ruins most label sheets. Options worth knowing: - **Skip positions** — start partway down a part-used sheet instead of wasting it. - **Copies each** — same label on several drawers. - **Offset X/Y** — per-printer alignment nudge in millimetres. Set your usual value once in *Settings*. - **Outline each label** — hairlines for cutting, and for test-printing on plain paper before you commit a sheet of Averys. - **Show on each label** — image, name, dimensions, part number, alternates, category, category code, drawer, colour, category colour stripe. **Sheet presets**: Avery L7651 (65/sheet, good for bags), L7160 (21/sheet, the all-rounder), L7163 (14/sheet, wide), L7159 (24/sheet), L7169 (8/sheet, large), Avery 5160 (US Letter), plus two plain-A4 grids for cut-your-own sticker paper or paper-and-tape. --- ## Where things live ``` app/models/part_label.py PartCategory (tree) + PartLabel app/services/part_catalog.py taxonomy seeding, Rebrickable client app/services/label_render.py sheet geometry, layout, optional PDF app/routes/labels.py the blueprint (all admin_required) app/data/part_taxonomy.json the starter taxonomy app/templates/admin/labels/ index, form, categories, settings, print /parts/ cached and uploaded part images ``` Labels are **not** an inventory. There's no quantity field on purpose — the drawer tells you how many you have. --- Created by: Jess Rogerson (yelling commands at Claude.AI)