-- ============================================= -- BANCO DE DADOS: snglpi -- DESCRIÇÃO: Sistema de integração entre ServiceNow e GLPI -- OBS: Chamados sempre são abertos pelo ServiceNow -- ============================================= CREATE DATABASE snglpi WITH OWNER = desenvolvimento ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8' LOCALE_PROVIDER = 'libc' TABLESPACE = pg_default CONNECTION LIMIT = -1 IS_TEMPLATE = False; -- ============================================= -- TABELA: tickets_sn -- DESCRIÇÃO: Armazena tickets importados do ServiceNow -- ============================================= CREATE TABLE tickets_sn ( id SERIAL PRIMARY KEY, -- ID único do registro no banco snglpi ticket_number VARCHAR(32) NOT NULL UNIQUE, -- Número do ticket no ServiceNow (ex: INC0140378) sys_id VARCHAR(64) NOT NULL UNIQUE, -- Identificador único do ticket no ServiceNow short_description TEXT, -- Descrição resumida do ticket tipo VARCHAR(10), -- Tipo do ticket: 'incidente' ou 'requisicao' status VARCHAR(55), -- Status atual do ticket no ServiceNow description TEXT, -- Descrição completa do ticket caller_id VARCHAR(255), -- Nome do solicitante do ticket caller_email VARCHAR(255), -- Email do solicitante location_id VARCHAR(64), -- ID da localização no ServiceNow location_name VARCHAR(255), -- Nome da localização no ServiceNow ramal VARCHAR(100), -- Ramal do solicitante telefone VARCHAR(100), -- Telefone do solicitante opened_at TIMESTAMP, -- Data e hora de abertura no ServiceNow created_at TIMESTAMP DEFAULT NOW(), -- Data e hora de criação do registro updated_at TIMESTAMP DEFAULT NOW() -- Data e hora da última atualização do registro ); -- Índices para melhor performance nas consultas frequentes CREATE INDEX idx_tickets_sn_status ON tickets_sn(status); CREATE INDEX idx_tickets_sn_tipo ON tickets_sn(tipo); CREATE INDEX idx_tickets_sn_opened_at ON tickets_sn(opened_at); CREATE INDEX idx_tickets_sn_location_id ON tickets_sn(location_id); CREATE INDEX idx_tickets_sn_location_name ON tickets_sn(location_name); -- ============================================= -- TABELA: ticket_sync -- DESCRIÇÃO: Controla o status de sincronização entre ServiceNow e GLPI -- OBS: Chamados sempre são criados no ServiceNow primeiro -- ============================================= CREATE TABLE ticket_sync ( id SERIAL PRIMARY KEY, -- ID único do registro de sincronização sn_ticket_id INTEGER NOT NULL, -- Referência ao ticket na tabela tickets_sn glpi_ticket_id INTEGER, -- ID do ticket correspondente no GLPI last_sn_sync TIMESTAMP, -- Data e hora da última sincronização com ServiceNow last_glpi_sync TIMESTAMP, -- Data e hora da última sincronização com GLPI sn_sync_status VARCHAR(20) DEFAULT 'pending',-- Status da sincronização com ServiceNow: 'pending', 'completed', 'error' glpi_sync_status VARCHAR(20) DEFAULT 'pending', -- Status da sincronização com GLPI: 'pending', 'completed', 'error' created_at TIMESTAMP DEFAULT NOW(), -- Data e hora de criação do registro updated_at TIMESTAMP DEFAULT NOW(), -- Data e hora da última atualização do registro source_last VARCHAR (4), -- Chaves estrangeiras CONSTRAINT fk_ticket_sync_sn_ticket FOREIGN KEY (sn_ticket_id) REFERENCES tickets_sn(id) ON DELETE CASCADE ); -- Índices para melhor performance nas consultas frequentes CREATE INDEX idx_ticket_sync_sn_ticket ON ticket_sync(sn_ticket_id); CREATE INDEX idx_ticket_sync_glpi_ticket ON ticket_sync(glpi_ticket_id); CREATE INDEX idx_ticket_sync_status ON ticket_sync(sn_sync_status, glpi_sync_status); -- ============================================= -- TABELA: ticket_updates -- DESCRIÇÃO: Armazena as atualizações e tarefas relacionadas aos tickets -- OBS: Atualizações podem vir de ambos os sistemas (ServiceNow e GLPI) -- ============================================= CREATE TABLE ticket_updates ( id SERIAL PRIMARY KEY, -- ID único da atualização ticket_sync_id INTEGER NOT NULL, -- Referência ao registro de sincronização update_type VARCHAR(20) NOT NULL, -- Tipo de atualização: 'task', 'note', 'status_change' source_system VARCHAR(10) NOT NULL, -- Sistema de origem: 'sn' (ServiceNow) ou 'glpi' content TEXT, -- Conteúdo da atualização/tarefa author VARCHAR(255), -- Autor da atualização created_at TIMESTAMP, -- Data e hora de criação no sistema de origem updated_at TIMESTAMP DEFAULT NOW(), -- Data e hora da última atualização do registro source_id VARCHAR(64), -- ID da atualização no sistema de origem (ex: sys_id no ServiceNow ou comment.id no GLPI) destiny_id VARCHAR(64), -- ID da atualização no sistema de destino (ex: comment.id no GLPI ou sys_id no ServiceNow) -- Chaves estrangeiras CONSTRAINT fk_ticket_updates_sync FOREIGN KEY (ticket_sync_id) REFERENCES ticket_sync(id) ON DELETE CASCADE ); -- Índices para melhor performance nas consultas frequentes CREATE INDEX idx_ticket_updates_sync ON ticket_updates(ticket_sync_id); CREATE INDEX idx_ticket_updates_source ON ticket_updates(source_system); CREATE INDEX idx_ticket_updates_type ON ticket_updates(update_type); CREATE INDEX idx_ticket_updates_source_id ON ticket_updates(source_id); -- ============================================= -- TABELA: location_mapping -- DESCRIÇÃO: Mapeamento entre localizações do ServiceNow e entidades do GLPI -- ============================================= CREATE TABLE location_mapping ( id SERIAL PRIMARY KEY, -- ID único do mapeamento sn_location_id VARCHAR(255), -- ID da localização no ServiceNow sn_location_name VARCHAR(255) NOT NULL, -- Nome da localização no ServiceNow glpi_entity_id INTEGER NOT NULL, -- ID da entidade correspondente no GLPI glpi_entity_name VARCHAR(255) NOT NULL, -- Nome da entidade no GLPI created_at TIMESTAMP DEFAULT NOW(), -- Data e hora de criação do registro updated_at TIMESTAMP DEFAULT NOW() -- Data e hora da última atualização do registro ); -- Índices para melhor performance nas consultas frequentes CREATE INDEX idx_location_mapping_sn_id ON location_mapping(sn_location_id); CREATE INDEX idx_location_mapping_sn_name ON location_mapping(sn_location_name); CREATE INDEX idx_location_mapping_glpi_id ON location_mapping(glpi_entity_id); CREATE INDEX idx_location_mapping_glpi_name ON location_mapping(glpi_entity_name); -- ============================================= -- TRIGGERS para atualizar automaticamente updated_at -- ============================================= -- Função para atualizar o campo updated_at CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Trigger para tickets_sn CREATE TRIGGER trigger_tickets_sn_updated_at BEFORE UPDATE ON tickets_sn FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- Trigger para ticket_sync CREATE TRIGGER trigger_ticket_sync_updated_at BEFORE UPDATE ON ticket_sync FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- Trigger para ticket_updates CREATE TRIGGER trigger_ticket_updates_updated_at BEFORE UPDATE ON ticket_updates FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- Trigger para location_mapping CREATE TRIGGER trigger_location_mapping_updated_at BEFORE UPDATE ON location_mapping FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); -- ============================================= -- VIEWS para consultas úteis -- ============================================= -- View para tickets pendentes de sincronização com GLPI CREATE VIEW view_tickets_pending_glpi AS SELECT ts.ticket_number, ts.short_description, ts.status, ts.tipo, ts.opened_at, tsync.created_at as sync_created FROM tickets_sn ts JOIN ticket_sync tsync ON ts.id = tsync.sn_ticket_id WHERE tsync.glpi_sync_status = 'pending'; -- View para tickets pendentes de sincronização com ServiceNow CREATE VIEW view_tickets_pending_sn AS SELECT ts.ticket_number, ts.short_description, ts.status, ts.tipo, ts.opened_at, tsync.created_at as sync_created FROM tickets_sn ts JOIN ticket_sync tsync ON ts.id = tsync.sn_ticket_id WHERE tsync.sn_sync_status = 'pending'; -- View para mapeamento de localizações completo CREATE VIEW view_location_mapping_complete AS SELECT sn_location_id, sn_location_name, glpi_entity_id, glpi_entity_name, created_at, updated_at FROM location_mapping ORDER BY sn_location_name; -- ============================================= -- COMENTÁRIOS NAS TABELAS E COLUNAS -- ============================================= COMMENT ON TABLE tickets_sn IS 'Armazena tickets importados do ServiceNow'; COMMENT ON COLUMN tickets_sn.id IS 'ID único do registro no banco snglpi'; COMMENT ON COLUMN tickets_sn.ticket_number IS 'Número do ticket no ServiceNow (ex: INC0140378)'; COMMENT ON COLUMN tickets_sn.sys_id IS 'Identificador único do ticket no ServiceNow'; COMMENT ON COLUMN tickets_sn.short_description IS 'Descrição resumida do ticket'; COMMENT ON COLUMN tickets_sn.tipo IS 'Tipo do ticket: incidente ou requisicao'; COMMENT ON COLUMN tickets_sn.status IS 'Status atual do ticket no ServiceNow'; COMMENT ON COLUMN tickets_sn.description IS 'Descrição completa do ticket'; COMMENT ON COLUMN tickets_sn.caller_id IS 'Nome do solicitante do ticket'; COMMENT ON COLUMN tickets_sn.caller_email IS 'Email do solicitante'; COMMENT ON COLUMN tickets_sn.location_id IS 'ID da localização no ServiceNow'; COMMENT ON COLUMN tickets_sn.location_name IS 'Nome da localização no ServiceNow'; COMMENT ON COLUMN tickets_sn.ramal IS 'Ramal do solicitante'; COMMENT ON COLUMN tickets_sn.telefone IS 'Telefone do solicitante'; COMMENT ON COLUMN tickets_sn.opened_at IS 'Data e hora de abertura no ServiceNow'; COMMENT ON COLUMN tickets_sn.created_at IS 'Data e hora de criação do registro'; COMMENT ON COLUMN tickets_sn.updated_at IS 'Data e hora da última atualização do registro'; COMMENT ON TABLE ticket_sync IS 'Controla o status de sincronização entre ServiceNow e GLPI'; COMMENT ON COLUMN ticket_sync.id IS 'ID único do registro de sincronização'; COMMENT ON COLUMN ticket_sync.sn_ticket_id IS 'Referência ao ticket na tabela tickets_sn'; COMMENT ON COLUMN ticket_sync.glpi_ticket_id IS 'ID do ticket correspondente no GLPI'; COMMENT ON COLUMN ticket_sync.last_sn_sync IS 'Data e hora da última sincronização com ServiceNow'; COMMENT ON COLUMN ticket_sync.last_glpi_sync IS 'Data e hora da última sincronização com GLPI'; COMMENT ON COLUMN ticket_sync.sn_sync_status IS 'Status da sincronização com ServiceNow: pending, completed, error'; COMMENT ON COLUMN ticket_sync.glpi_sync_status IS 'Status da sincronização com GLPI: pending, completed, error'; COMMENT ON COLUMN ticket_sync.created_at IS 'Data e hora de criação do registro'; COMMENT ON COLUMN ticket_sync.updated_at IS 'Data e hora da última atualização do registro'; COMMENT ON TABLE ticket_updates IS 'Armazena as atualizações e tarefas relacionadas aos tickets'; COMMENT ON COLUMN ticket_updates.id IS 'ID único da atualização'; COMMENT ON COLUMN ticket_updates.ticket_sync_id IS 'Referência ao registro de sincronização'; COMMENT ON COLUMN ticket_updates.update_type IS 'Tipo de atualização: task, note, status_change'; COMMENT ON COLUMN ticket_updates.source_system IS 'Sistema de origem: sn (ServiceNow) ou glpi'; COMMENT ON COLUMN ticket_updates.content IS 'Conteúdo da atualização/tarefa'; COMMENT ON COLUMN ticket_updates.author IS 'Autor da atualização'; COMMENT ON COLUMN ticket_updates.created_at_source IS 'Data e hora de criação no sistema de origem'; COMMENT ON COLUMN ticket_updates.sync_status IS 'Status da sincronização: pending, completed, error'; COMMENT ON COLUMN ticket_updates.sync_date IS 'Data e hora da sincronização'; COMMENT ON COLUMN ticket_updates.created_at IS 'Data e hora de criação do registro'; COMMENT ON COLUMN ticket_updates.updated_at IS 'Data e hora da última atualização do registro'; COMMENT ON TABLE location_mapping IS 'Mapeamento entre localizações do ServiceNow e entidades do GLPI'; COMMENT ON COLUMN location_mapping.id IS 'ID único do mapeamento'; COMMENT ON COLUMN location_mapping.sn_location_id IS 'ID da localização no ServiceNow'; COMMENT ON COLUMN location_mapping.sn_location_name IS 'Nome da localização no ServiceNow'; COMMENT ON COLUMN location_mapping.glpi_entity_id IS 'ID da entidade correspondente no GLPI'; COMMENT ON COLUMN location_mapping.glpi_entity_name IS 'Nome da entidade no GLPI'; COMMENT ON COLUMN location_mapping.created_at IS 'Data e hora de criação do registro'; COMMENT ON COLUMN location_mapping.updated_at IS 'Data e hora da última atualização do registro'; -- ============================================= -- TABELA: sync_control -- DESCRIÇÃO: Armazena metadados do processo de sincronização, como marcas d'água. -- ============================================= CREATE TABLE sync_control ( id SERIAL PRIMARY KEY, system_name VARCHAR(50) NOT NULL UNIQUE, last_watermark TIMESTAMP WITH TIME ZONE, last_run_status VARCHAR(20), last_run_at TIMESTAMP WITH TIME ZONE ); -- Registro inicial para a marca d'água do ServiceNow. -- Começa em uma data muito antiga para garantir que a primeira execução pegue tudo. INSERT INTO sync_control (system_name, last_watermark) VALUES ('servicenow', '1970-01-01 00:00:00+00'); COMMENT ON TABLE sync_control IS 'Controla o estado do processo de sincronização, como a última data de busca (watermark).'; COMMENT ON COLUMN sync_control.system_name IS 'Nome do sistema para o qual a marca d''água se aplica (ex: servicenow)'; COMMENT ON COLUMN sync_control.last_watermark IS 'O timestamp (sys_updated_on) do último registro processado com sucesso.'; COMMENT ON COLUMN sync_control.last_run_status IS 'Status da última execução (ex: success, failed).'; COMMENT ON COLUMN sync_control.last_run_at IS 'Timestamp da última vez que o job rodou.'; -- Registro inicial para a marca d'água do GLPI. INSERT INTO sync_control (system_name, last_watermark) VALUES ('glpi', '1970-01-01 00:00:00+00');