PRAGMA foreign_keys = ON; -- Unified gear item table for weapons, armor, helmets, backpacks, rigs, and mods/attachments CREATE TABLE IF NOT EXISTS gear_items ( id TEXT PRIMARY KEY, api_id TEXT UNIQUE NOT NULL, name TEXT NOT NULL, short_name TEXT, category TEXT NOT NULL, -- 'gun' | 'armor' | 'helmet' | 'backpack' | 'rig' | 'mod' weight_kg REAL, grid_image_url TEXT, wiki_url TEXT, -- Weapon-specific fields caliber TEXT, fire_rate INTEGER, ergonomics INTEGER, recoil_vertical INTEGER, default_weight REAL, -- weight of gun with default preset mods attached -- Armor / Helmet / Rig shared fields armor_class INTEGER, -- 1-6, NULL if not applicable durability REAL, material TEXT, zones TEXT, -- comma-separated protection zone names head_zones TEXT, -- comma-separated head zone names (helmets only) deafening TEXT, -- None | Low | Medium | High | Complete (helmets) -- Backpack / Rig capacity capacity INTEGER, -- total grid cell count -- Mod/attachment classification mod_type TEXT, -- 'suppressor' | 'scope' | 'flashlight' | 'foregrip' | 'stock' | etc. imported_at TEXT DEFAULT CURRENT_TIMESTAMP, updated_at TEXT DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_gear_category ON gear_items(category); CREATE INDEX IF NOT EXISTS idx_gear_armor_class ON gear_items(armor_class); CREATE INDEX IF NOT EXISTS idx_gear_capacity ON gear_items(capacity); CREATE INDEX IF NOT EXISTS idx_gear_weight ON gear_items(weight_kg); CREATE INDEX IF NOT EXISTS idx_gear_caliber ON gear_items(caliber); -- Weapon mod slots: records which named slots exist on each gun CREATE TABLE IF NOT EXISTS gun_slots ( gun_id TEXT NOT NULL REFERENCES gear_items(id) ON DELETE CASCADE, slot_id TEXT NOT NULL, -- tarkov internal slot ID slot_name TEXT NOT NULL, -- human-readable name (e.g. "Muzzle") slot_nameid TEXT, -- normalized nameId (e.g. "mod_muzzle") required INTEGER DEFAULT 0, -- 1 if the slot must be filled PRIMARY KEY (gun_id, slot_id) ); CREATE INDEX IF NOT EXISTS idx_gun_slots_nameid ON gun_slots(slot_nameid); -- Which items are compatible with each gun slot (from API filters.allowedItems) CREATE TABLE IF NOT EXISTS gun_slot_items ( gun_id TEXT NOT NULL, slot_id TEXT NOT NULL, item_id TEXT NOT NULL REFERENCES gear_items(id) ON DELETE CASCADE, PRIMARY KEY (gun_id, slot_id, item_id), FOREIGN KEY (gun_id, slot_id) REFERENCES gun_slots(gun_id, slot_id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_gun_slot_items_item ON gun_slot_items(item_id); -- Open plate slots on armor/rig carriers (ItemArmorSlotOpen from tarkov API) -- Weight of a carrier does NOT include plates in these slots CREATE TABLE IF NOT EXISTS armor_open_slots ( carrier_id TEXT NOT NULL REFERENCES gear_items(id) ON DELETE CASCADE, slot_nameid TEXT NOT NULL, -- e.g. "front_plate", "back_plate", "left_side_plate" zones TEXT, -- comma-separated zone names e.g. "FR. PLATE,BCK. PLATE" PRIMARY KEY (carrier_id, slot_nameid) ); -- Which plates are compatible with each open slot on a carrier CREATE TABLE IF NOT EXISTS armor_slot_plates ( carrier_id TEXT NOT NULL, slot_nameid TEXT NOT NULL, plate_id TEXT NOT NULL REFERENCES gear_items(id) ON DELETE CASCADE, PRIMARY KEY (carrier_id, slot_nameid, plate_id), FOREIGN KEY (carrier_id, slot_nameid) REFERENCES armor_open_slots(carrier_id, slot_nameid) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_armor_slot_plates_plate ON armor_slot_plates(plate_id); -- Saved loadout builds CREATE TABLE IF NOT EXISTS saved_builds ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL DEFAULT 'My Build', gun_id TEXT REFERENCES gear_items(id), armor_id TEXT REFERENCES gear_items(id), helmet_id TEXT REFERENCES gear_items(id), rig_id TEXT REFERENCES gear_items(id), backpack_id TEXT REFERENCES gear_items(id), notes TEXT, created_at TEXT DEFAULT CURRENT_TIMESTAMP );