- Implement test script for new SAG module endpoints BE-003 (Tag State Management) and BE-004 (Bulk Operations). - Create test cases for creating, updating, and bulk operations on cases and tags. - Add a test for module deactivation to ensure data integrity is maintained. - Include setup and teardown for tests to clear database state before and after each test.
135 lines
5.8 KiB
SQL
135 lines
5.8 KiB
SQL
-- Hardware Asset Management Module
|
|
-- Created: 2026-01-30
|
|
-- Description: Complete hardware tracking with ownership, location, and attachment history
|
|
|
|
-- ============================================================================
|
|
-- Table 1: hardware_assets
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS hardware_assets (
|
|
id SERIAL PRIMARY KEY,
|
|
asset_type VARCHAR(50) NOT NULL CHECK (asset_type IN ('pc', 'laptop', 'printer', 'skærm', 'telefon', 'server', 'netværk', 'andet')),
|
|
brand VARCHAR(100),
|
|
model VARCHAR(100),
|
|
serial_number VARCHAR(100),
|
|
customer_asset_id VARCHAR(50), -- Customer's inventory number
|
|
internal_asset_id VARCHAR(50), -- BMC internal ID
|
|
notes TEXT,
|
|
|
|
-- Current state (for quick queries)
|
|
current_owner_type VARCHAR(50) CHECK (current_owner_type IN ('customer', 'bmc', 'third_party')),
|
|
current_owner_customer_id INT, -- if owner_type = customer
|
|
current_location_id INT,
|
|
|
|
-- Status
|
|
status VARCHAR(50) DEFAULT 'active' CHECK (status IN ('active', 'faulty_reported', 'in_repair', 'replaced', 'retired', 'unsupported')),
|
|
status_reason TEXT,
|
|
warranty_until DATE,
|
|
end_of_life DATE,
|
|
|
|
-- Follow-up
|
|
follow_up_date DATE,
|
|
follow_up_owner_user_id INT,
|
|
|
|
-- Standard fields
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
deleted_at TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hardware_serial ON hardware_assets(serial_number);
|
|
CREATE INDEX IF NOT EXISTS idx_hardware_customer ON hardware_assets(current_owner_customer_id);
|
|
CREATE INDEX IF NOT EXISTS idx_hardware_status ON hardware_assets(status) WHERE deleted_at IS NULL;
|
|
|
|
-- ============================================================================
|
|
-- Table 2: hardware_ownership_history
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS hardware_ownership_history (
|
|
id SERIAL PRIMARY KEY,
|
|
hardware_id INT NOT NULL REFERENCES hardware_assets(id),
|
|
owner_type VARCHAR(50) NOT NULL CHECK (owner_type IN ('customer', 'bmc', 'third_party')),
|
|
owner_customer_id INT, -- if owner_type = customer
|
|
start_date DATE NOT NULL,
|
|
end_date DATE, -- NULL = active ownership
|
|
notes TEXT,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
deleted_at TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_ownership_hardware ON hardware_ownership_history(hardware_id);
|
|
CREATE INDEX IF NOT EXISTS idx_ownership_active ON hardware_ownership_history(hardware_id, end_date) WHERE end_date IS NULL AND deleted_at IS NULL;
|
|
|
|
-- ============================================================================
|
|
-- Table 3: hardware_location_history
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS hardware_location_history (
|
|
id SERIAL PRIMARY KEY,
|
|
hardware_id INT NOT NULL REFERENCES hardware_assets(id),
|
|
location_id INT, -- Reference to locations table (if exists)
|
|
location_name VARCHAR(200), -- Free text if no location_id
|
|
start_date DATE NOT NULL,
|
|
end_date DATE, -- NULL = current location
|
|
notes TEXT,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
deleted_at TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_location_hardware ON hardware_location_history(hardware_id);
|
|
CREATE INDEX IF NOT EXISTS idx_location_active ON hardware_location_history(hardware_id, end_date) WHERE end_date IS NULL AND deleted_at IS NULL;
|
|
|
|
-- ============================================================================
|
|
-- Table 4: hardware_attachments
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS hardware_attachments (
|
|
id SERIAL PRIMARY KEY,
|
|
hardware_id INT NOT NULL REFERENCES hardware_assets(id),
|
|
file_type VARCHAR(50), -- 'image', 'receipt', 'contract', 'manual', 'other'
|
|
file_name VARCHAR(255) NOT NULL,
|
|
storage_ref TEXT NOT NULL, -- Path or cloud storage reference
|
|
file_size_bytes BIGINT,
|
|
mime_type VARCHAR(100),
|
|
description TEXT,
|
|
uploaded_by_user_id INT,
|
|
uploaded_at TIMESTAMP DEFAULT NOW(),
|
|
deleted_at TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_attachments_hardware ON hardware_attachments(hardware_id);
|
|
|
|
-- ============================================================================
|
|
-- Table 5: hardware_case_relations
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS hardware_case_relations (
|
|
id SERIAL PRIMARY KEY,
|
|
hardware_id INT NOT NULL REFERENCES hardware_assets(id),
|
|
case_id INT NOT NULL, -- References sag_sager(id)
|
|
relation_type VARCHAR(50) DEFAULT 'related', -- 'repair', 'installation', 'support', 'related'
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
deleted_at TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hardware_cases ON hardware_case_relations(hardware_id);
|
|
CREATE INDEX IF NOT EXISTS idx_case_hardware ON hardware_case_relations(case_id);
|
|
|
|
-- ============================================================================
|
|
-- Table 6: hardware_tags
|
|
-- ============================================================================
|
|
CREATE TABLE IF NOT EXISTS hardware_tags (
|
|
id SERIAL PRIMARY KEY,
|
|
hardware_id INT NOT NULL REFERENCES hardware_assets(id),
|
|
tag_name VARCHAR(100) NOT NULL,
|
|
tag_type VARCHAR(50) DEFAULT 'manual' CHECK (tag_type IN ('manual', 'system', 'ai_generated')),
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
deleted_at TIMESTAMP
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hardware_tags ON hardware_tags(hardware_id);
|
|
CREATE INDEX IF NOT EXISTS idx_tag_name ON hardware_tags(tag_name) WHERE deleted_at IS NULL;
|
|
|
|
-- ============================================================================
|
|
-- Success message
|
|
-- ============================================================================
|
|
DO $$
|
|
BEGIN
|
|
RAISE NOTICE '✅ Hardware module tables created successfully';
|
|
END $$;
|