-- Time Entries table for Autotask sync -- This migration creates the time_entries table with proper indexing and foreign keys CREATE TABLE IF NOT EXISTS time_entries ( id BIGINT PRIMARY KEY, resource_id BIGINT NOT NULL, ticket_id BIGINT, task_id BIGINT, project_id BIGINT, company_id BIGINT, entry_date TIMESTAMP NOT NULL, hours_worked DECIMAL(10,2) NOT NULL, notes TEXT, internal_notes TEXT, title VARCHAR(255), type INTEGER, start_date_time TIMESTAMP, end_date_time TIMESTAMP, billable BOOLEAN DEFAULT true, billing_rate DECIMAL(15,2), billing_rate_currency_id INTEGER, cost_rate DECIMAL(15,2), cost_rate_currency_id INTEGER, cost DECIMAL(15,2), cost_currency_id INTEGER, revenue DECIMAL(15,2), revenue_currency_id INTEGER, margin DECIMAL(15,2), margin_currency_id INTEGER, approved BOOLEAN DEFAULT false, approved_by_resource_id BIGINT, approved_date_time TIMESTAMP, non_billable BOOLEAN DEFAULT false, contract_service_id BIGINT, contract_service_bundle_id BIGINT, role_id BIGINT, department_id INTEGER, location_id BIGINT, allocation_code_id BIGINT, imp_project_schedule_id BIGINT, imp_project_schedule_task_id BIGINT, api_vendor_id INTEGER, -- Audit fields created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, synced_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_deleted BOOLEAN DEFAULT false, deleted_at TIMESTAMP, FOREIGN KEY (resource_id) REFERENCES resources(id) ON DELETE CASCADE, FOREIGN KEY (ticket_id) REFERENCES tickets(id) ON DELETE SET NULL, FOREIGN KEY (task_id) REFERENCES tasks(id) ON DELETE SET NULL, FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE SET NULL, FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE SET NULL, FOREIGN KEY (approved_by_resource_id) REFERENCES resources(id) ON DELETE SET NULL -- Note: Foreign keys for contract_services, contract_service_bundles, roles, locations, -- and allocation_codes are omitted as these tables don't exist yet. -- These can be added in a future migration when those tables are created. ); -- Indexes for performance CREATE INDEX IF NOT EXISTS idx_time_entries_resource_id ON time_entries(resource_id); CREATE INDEX IF NOT EXISTS idx_time_entries_ticket_id ON time_entries(ticket_id); CREATE INDEX IF NOT EXISTS idx_time_entries_task_id ON time_entries(task_id); CREATE INDEX IF NOT EXISTS idx_time_entries_project_id ON time_entries(project_id); CREATE INDEX IF NOT EXISTS idx_time_entries_company_id ON time_entries(company_id); CREATE INDEX IF NOT EXISTS idx_time_entries_entry_date ON time_entries(entry_date); CREATE INDEX IF NOT EXISTS idx_time_entries_start_date_time ON time_entries(start_date_time); CREATE INDEX IF NOT EXISTS idx_time_entries_end_date_time ON time_entries(end_date_time); CREATE INDEX IF NOT EXISTS idx_time_entries_is_active ON time_entries(is_deleted); CREATE INDEX IF NOT EXISTS idx_time_entries_synced_at ON time_entries(synced_at); CREATE INDEX IF NOT EXISTS idx_time_entries_created_at ON time_entries(created_at); -- Composite indexes for common queries CREATE INDEX IF NOT EXISTS idx_time_entries_resource_date ON time_entries(resource_id, entry_date); CREATE INDEX IF NOT EXISTS idx_time_entries_ticket_date ON time_entries(ticket_id, entry_date); CREATE INDEX IF NOT EXISTS idx_time_entries_project_date ON time_entries(project_id, entry_date); CREATE INDEX IF NOT EXISTS idx_time_entries_company_date ON time_entries(company_id, entry_date); -- Comments for documentation COMMENT ON TABLE time_entries IS 'Autotask time entries with analytics support'; COMMENT ON COLUMN time_entries.hours_worked IS 'Hours worked for this time entry'; COMMENT ON COLUMN time_entries.notes IS 'Public notes for the time entry'; COMMENT ON COLUMN time_entries.internal_notes IS 'Internal notes for the time entry'; COMMENT ON COLUMN time_entries.billable IS 'Whether this time entry is billable'; COMMENT ON COLUMN time_entries.approved IS 'Whether this time entry has been approved'; COMMENT ON COLUMN time_entries.non_billable IS 'Whether this time entry is marked as non-billable'; COMMENT ON COLUMN time_entries.is_deleted IS 'Soft delete flag - true if deleted in Autotask'; COMMENT ON COLUMN time_entries.synced_at IS 'Last time this record was synced from Autotask';