Files
PartsInventorySystem/app/seed.py
T
thejayman77 ffe508b7f3 Parts inventory: catalog, search, and stock tracking
FastAPI + SQLite behind a single-page frontend, deployed as a container on
mainserver behind Caddy.

One flexible parts table plus key/value specs so components, filament,
fasteners and tooling share a schema. Categories and locations are nestable
trees whose filters and sidebar counts both roll up through descendants.
Category spec templates pre-fill the properties worth recording for each kind
of part, which is what makes manual entry tolerable. Every quantity change is
logged. Search is FTS5 with prefix matching across names, MPNs, spec values,
tags, category and location.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 09:19:58 -04:00

97 lines
4.9 KiB
Python

"""Starter categories and their spec templates.
Seeded once, on an empty database. A category's template is only a suggestion —
the add form pre-fills those keys, and you can delete any of them or add your
own. Nothing here constrains what a part may hold.
"""
import json
# (name, unit, [spec keys...], [children...])
TREE = [
("Electronics", "pcs", [], [
("Resistors", "pcs", ["Resistance", "Tolerance", "Power", "Package", "Type"]),
("Capacitors", "pcs", ["Capacitance", "Voltage", "Dielectric", "Tolerance", "Package"]),
("Inductors", "pcs", ["Inductance", "Current", "Package"]),
("Diodes", "pcs", ["Type", "Forward Voltage", "Current", "Package"]),
("LEDs", "pcs", ["Colour", "Package", "Forward Voltage", "Current", "Wavelength"]),
("Transistors", "pcs", ["Type", "Voltage", "Current", "Package"]),
("ICs", "pcs", ["Function", "Package", "Pins", "Voltage"]),
("Voltage Regulators", "pcs", ["Output Voltage", "Current", "Type", "Package"]),
("Crystals & Oscillators", "pcs", ["Frequency", "Load Capacitance", "Package"]),
("Connectors", "pcs", ["Type", "Pitch", "Positions", "Gender", "Mount"]),
("Headers & Jumpers", "pcs", ["Pitch", "Positions", "Rows", "Orientation"]),
("Switches & Buttons", "pcs", ["Type", "Poles", "Rating", "Mount"]),
("Relays", "pcs", ["Coil Voltage", "Contact Rating", "Type"]),
("Sensors", "pcs", ["Measures", "Interface", "Voltage", "Range"]),
("Modules & Breakouts", "pcs", ["Function", "Interface", "Voltage"]),
("Dev Boards", "pcs", ["MCU", "Voltage", "Flash", "RAM", "Connectivity"]),
("Displays", "pcs", ["Type", "Size", "Resolution", "Interface", "Voltage"]),
("Motors & Actuators", "pcs", ["Type", "Voltage", "Torque", "Shaft"]),
("Wire & Cable", "m", ["Gauge", "Conductors", "Insulation", "Colour"]),
("PCBs & Protoboard", "pcs", ["Size", "Layers", "Type"]),
("Batteries & Power", "pcs", ["Chemistry", "Voltage", "Capacity", "Form Factor"]),
]),
("3D Printing", "pcs", [], [
("Filament", "g", ["Material", "Colour", "Diameter", "Brand", "Spool Weight", "Print Temp", "Bed Temp"]),
("Resin", "ml", ["Type", "Colour", "Brand", "Cure Time"]),
("Nozzles", "pcs", ["Diameter", "Material", "Thread", "Fits"]),
("Printer Spares", "pcs", ["Fits", "Function"]),
("Build Surfaces", "pcs", ["Size", "Type", "Fits"]),
]),
("Mechanical", "pcs", [], [
("Fasteners", "pcs", ["Thread", "Length", "Head", "Drive", "Material", "Finish"]),
("Nuts & Washers", "pcs", ["Thread", "Type", "Material"]),
("Standoffs & Spacers", "pcs", ["Thread", "Length", "Material", "Type"]),
("Bearings", "pcs", ["Bore", "Outer Diameter", "Width", "Type"]),
("Belts & Pulleys", "pcs", ["Profile", "Teeth", "Width", "Bore"]),
("Linear Motion", "pcs", ["Diameter", "Length", "Type"]),
("Springs & Magnets", "pcs", ["Size", "Type", "Strength"]),
("Extrusion & Stock", "mm", ["Profile", "Material", "Length"]),
]),
("Materials", "pcs", [], [
("Sheet & Plate", "pcs", ["Material", "Thickness", "Size"]),
("Adhesives & Tape", "pcs", ["Type", "Width", "Use"]),
("Finishing", "pcs", ["Type", "Colour", "Volume"]),
]),
("Tools", "pcs", [], [
("Hand Tools", "pcs", ["Type", "Size", "Brand"]),
("Power Tools", "pcs", ["Type", "Voltage", "Brand"]),
("Bits & Blades", "pcs", ["Type", "Size", "Fits"]),
("Measurement", "pcs", ["Type", "Range", "Resolution", "Brand"]),
("Soldering", "pcs", ["Type", "Diameter", "Alloy", "Flux"]),
]),
("Consumables", "pcs", [], [
("Cleaning", "pcs", ["Type", "Volume"]),
("Safety & PPE", "pcs", ["Type", "Size"]),
]),
("Uncategorised", "pcs", [], []),
]
LOCATIONS = ["Workshop", "Storage"]
def seed(conn):
if conn.execute("SELECT 1 FROM categories LIMIT 1").fetchone():
return
def add(name, unit, specs, parent_id, order):
template = json.dumps([{"key": k} for k in specs])
cur = conn.execute(
"INSERT INTO categories(name, parent_id, unit, spec_template, sort_order) VALUES (?,?,?,?,?)",
(name, parent_id, unit, template, order),
)
return cur.lastrowid
for i, (name, unit, specs, children) in enumerate(TREE):
parent = add(name, unit, specs, None, i)
for j, (cname, cunit, cspecs) in enumerate(children):
add(cname, cunit, cspecs, parent, j)
for i, name in enumerate(LOCATIONS):
conn.execute(
"INSERT INTO locations(name, parent_id, sort_order) VALUES (?, NULL, ?)",
(name, i),
)
conn.commit()