"""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()