labfy-investigation/database/schema_v1.sql

1229 lines
24 KiB
SQL

/******************************************************************************
* Labfy Investigation
*
* Schéma SQLite officiel V1
******************************************************************************/
CREATE TABLE metadata
(
key TEXT PRIMARY KEY,
value TEXT NOT NULL
);
CREATE TABLE investigation
(
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
root_path TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE categories
(
id TEXT PRIMARY KEY,
nom TEXT NOT NULL COLLATE NOCASE,
description TEXT,
icone TEXT,
couleur TEXT,
system INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
UNIQUE (nom),
CHECK (
length(trim(nom)) > 0
),
CHECK (
description IS NULL
OR length(trim(description)) > 0
),
CHECK (
icone IS NULL
OR length(trim(icone)) > 0
),
CHECK (
couleur IS NULL
OR (
length(couleur) = 7
AND substr(couleur, 1, 1) = '#'
)
),
CHECK (
system IN (0, 1)
),
CHECK (
status IN (
'active',
'archived',
'deleted'
)
)
);
CREATE INDEX idx_categories_status
ON categories(status);
CREATE TABLE tags
(
id TEXT PRIMARY KEY,
nom TEXT NOT NULL COLLATE NOCASE,
description TEXT,
couleur TEXT,
system INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
UNIQUE (nom),
CHECK (
length(trim(nom)) > 0
),
CHECK (
description IS NULL
OR length(trim(description)) > 0
),
CHECK (
couleur IS NULL
OR (
length(couleur) = 7
AND substr(couleur, 1, 1) = '#'
)
),
CHECK (
system IN (0, 1)
),
CHECK (
status IN (
'active',
'archived',
'deleted'
)
)
);
CREATE INDEX idx_tags_status
ON tags(status);
CREATE TABLE types_preuve
(
id INTEGER PRIMARY KEY,
code TEXT NOT NULL UNIQUE,
label TEXT NOT NULL,
description TEXT
);
INSERT INTO types_preuve
(id, code, label)
VALUES
(1, 'screenshot', 'Capture d''écran'),
(2, 'photo', 'Photographie'),
(3, 'video', 'Vidéo'),
(4, 'document', 'Document'),
(5, 'email', 'Courrier électronique'),
(6, 'archive', 'Archive'),
(7, 'audio', 'Audio'),
(8, 'text', 'Texte'),
(9, 'other', 'Autre');
CREATE TABLE types_entite
(
id INTEGER PRIMARY KEY,
code TEXT NOT NULL UNIQUE,
label TEXT NOT NULL,
description TEXT
);
CREATE TABLE tag_preuves
(
tag_id TEXT NOT NULL,
preuve_id TEXT NOT NULL,
PRIMARY KEY (tag_id, preuve_id),
FOREIGN KEY (tag_id)
REFERENCES tags(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (preuve_id)
REFERENCES preuves(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_tag_preuves_preuve_id
ON tag_preuves(preuve_id);
CREATE TABLE tag_recherches
(
tag_id TEXT NOT NULL,
recherche_id TEXT NOT NULL,
PRIMARY KEY (tag_id, recherche_id),
FOREIGN KEY (tag_id)
REFERENCES tags(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (recherche_id)
REFERENCES recherches(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_tag_recherches_recherche_id
ON tag_recherches(recherche_id);
CREATE TABLE tag_entites
(
tag_id TEXT NOT NULL,
entite_id TEXT NOT NULL,
PRIMARY KEY (tag_id, entite_id),
FOREIGN KEY (tag_id)
REFERENCES tags(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (entite_id)
REFERENCES entites(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_tag_entites_entite_id
ON tag_entites(entite_id);
CREATE TABLE tag_relations
(
tag_id TEXT NOT NULL,
relation_id TEXT NOT NULL,
PRIMARY KEY (tag_id, relation_id),
FOREIGN KEY (tag_id)
REFERENCES tags(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (relation_id)
REFERENCES relations(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_tag_relations_relation_id
ON tag_relations(relation_id);
CREATE TABLE tag_hypotheses
(
tag_id TEXT NOT NULL,
hypothese_id TEXT NOT NULL,
PRIMARY KEY (tag_id, hypothese_id),
FOREIGN KEY (tag_id)
REFERENCES tags(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (hypothese_id)
REFERENCES hypotheses(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_tag_hypotheses_hypothese_id
ON tag_hypotheses(hypothese_id);
CREATE TABLE tag_chronologie
(
tag_id TEXT NOT NULL,
chronologie_id TEXT NOT NULL,
PRIMARY KEY (tag_id, chronologie_id),
FOREIGN KEY (tag_id)
REFERENCES tags(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (chronologie_id)
REFERENCES chronologie(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_tag_chronologie_chronologie_id
ON tag_chronologie(chronologie_id);
INSERT INTO types_entite
(id, code, label)
VALUES
(1, 'email_address', 'Adresse email'),
(2, 'bank_account', 'Compte bancaire'),
(3, 'facebook_account', 'Compte Facebook'),
(4, 'instagram_account', 'Compte Instagram'),
(5, 'identity_document', 'Document d''identité'),
(6, 'iban', 'IBAN'),
(7, 'person', 'Personne'),
(8, 'pseudonym', 'Pseudonyme'),
(9, 'phone_number', 'Numéro de téléphone'),
(10, 'website', 'Site web'),
(11, 'domain_name', 'Nom de domaine'),
(12, 'ip_address', 'Adresse IP'),
(13, 'organization', 'Organisation'),
(14, 'other', 'Autre');
CREATE TABLE types_source
(
id INTEGER PRIMARY KEY,
code TEXT NOT NULL UNIQUE,
label TEXT NOT NULL,
description TEXT
);
INSERT INTO types_source
(id, code, label)
VALUES
(1, 'website', 'Site web'),
(2, 'social_network', 'Réseau social'),
(3, 'email', 'Courrier électronique'),
(4, 'document', 'Document'),
(5, 'testimony', 'Témoignage'),
(6, 'phone_export', 'Export de téléphone'),
(7, 'disk_export', 'Export de disque'),
(8, 'osint_tool', 'Outil OSINT'),
(9, 'manual_entry', 'Saisie manuelle'),
(10, 'other', 'Autre');
CREATE TABLE sources
(
id TEXT PRIMARY KEY,
type_id INTEGER NOT NULL,
nom TEXT NOT NULL,
reference TEXT,
description TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (type_id)
REFERENCES types_source(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (length(trim(nom)) > 0),
CHECK (
reference IS NULL
OR length(trim(reference)) > 0
)
);
CREATE INDEX idx_sources_type_id
ON sources(type_id);
CREATE INDEX idx_sources_reference
ON sources(reference);
CREATE TABLE preuves
(
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
relative_path TEXT NOT NULL UNIQUE,
type_id INTEGER NOT NULL,
size_bytes INTEGER,
sha256 TEXT,
mime_type TEXT,
description TEXT,
commentaire TEXT,
categorie_id TEXT,
file_created_at TEXT,
imported_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
locked INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (type_id)
REFERENCES types_preuve(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (categorie_id)
REFERENCES categories(id)
ON UPDATE CASCADE
ON DELETE SET NULL
CHECK (length(trim(name)) > 0),
CHECK (length(trim(relative_path)) > 0),
CHECK (
size_bytes IS NULL
OR size_bytes >= 0
),
CHECK (
sha256 IS NULL
OR (
length(sha256) = 64
AND sha256 = lower(sha256)
)
),
CHECK (
status IN (
'active',
'archived',
'deleted'
)
),
CHECK (
locked IN (0, 1)
)
);
CREATE INDEX idx_preuves_type_id
ON preuves(type_id);
CREATE INDEX idx_preuves_status
ON preuves(status);
CREATE INDEX idx_preuves_sha256
ON preuves(sha256);
CREATE INDEX idx_preuves_categorie_id
ON preuves(categorie_id);
CREATE TABLE recherches
(
id TEXT PRIMARY KEY,
source_id TEXT,
type_outil_id INTEGER NOT NULL,
outil_nom TEXT NOT NULL,
requete TEXT,
resultat TEXT,
observations TEXT,
categorie_id TEXT,
started_at TEXT NOT NULL,
completed_at TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'planned',
FOREIGN KEY (source_id)
REFERENCES sources(id)
ON UPDATE CASCADE
ON DELETE SET NULL,
FOREIGN KEY (type_outil_id)
REFERENCES types_outil(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (categorie_id)
REFERENCES categories(id)
ON UPDATE CASCADE
ON DELETE SET NULL,
CHECK (length(trim(outil_nom)) > 0),
CHECK (
requete IS NULL
OR length(trim(requete)) > 0
),
CHECK (
completed_at IS NULL
OR completed_at >= started_at
),
CHECK (
status IN (
'planned',
'running',
'completed',
'failed',
'cancelled',
'archived'
)
)
);
CREATE INDEX idx_recherches_source_id
ON recherches(source_id);
CREATE INDEX idx_recherches_type_outil_id
ON recherches(type_outil_id);
CREATE INDEX idx_recherches_status
ON recherches(status);
CREATE INDEX idx_recherches_started_at
ON recherches(started_at);
CREATE INDEX idx_recherches_categorie_id
ON recherches(categorie_id);
CREATE TABLE recherche_preuves
(
recherche_id TEXT NOT NULL,
preuve_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (
recherche_id,
preuve_id,
role
),
FOREIGN KEY (recherche_id)
REFERENCES recherches(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (preuve_id)
REFERENCES preuves(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (
role IN (
'input',
'output'
)
)
);
CREATE INDEX idx_recherche_preuves_preuve_id
ON recherche_preuves(preuve_id);
CREATE TABLE entites
(
id TEXT PRIMARY KEY,
type_id INTEGER NOT NULL,
valeur TEXT NOT NULL,
label TEXT,
description TEXT,
confiance INTEGER NOT NULL DEFAULT 50,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
UNIQUE (type_id, valeur),
FOREIGN KEY (type_id)
REFERENCES types_entite(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (length(trim(valeur)) > 0),
CHECK (
label IS NULL
OR length(trim(label)) > 0
),
CHECK (
confiance BETWEEN 0 AND 100
),
CHECK (
status IN (
'active',
'archived',
'deleted'
)
)
);
CREATE INDEX idx_entites_type_id
ON entites(type_id);
CREATE INDEX idx_entites_valeur
ON entites(valeur);
CREATE INDEX idx_entites_status
ON entites(status);
CREATE INDEX idx_entites_confiance
ON entites(confiance);
CREATE TABLE types_outil
(
id INTEGER PRIMARY KEY,
code TEXT NOT NULL UNIQUE,
label TEXT NOT NULL,
description TEXT
);
CREATE TABLE recherche_entites
(
recherche_id TEXT NOT NULL,
entite_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (
recherche_id,
entite_id,
role
),
FOREIGN KEY (recherche_id)
REFERENCES recherches(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (entite_id)
REFERENCES entites(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (
role IN (
'discovered',
'enriched',
'validated',
'contradicted'
)
)
);
CREATE INDEX idx_recherche_entites_entite_id
ON recherche_entites(entite_id);
CREATE TABLE preuve_entites
(
preuve_id TEXT NOT NULL,
entite_id TEXT NOT NULL,
PRIMARY KEY (
preuve_id,
entite_id
),
FOREIGN KEY (preuve_id)
REFERENCES preuves(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (entite_id)
REFERENCES entites(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_preuve_entites_entite_id
ON preuve_entites(entite_id);
CREATE TABLE relations
(
id TEXT PRIMARY KEY,
entite_source_id TEXT NOT NULL,
entite_cible_id TEXT NOT NULL,
type_relation TEXT NOT NULL,
label TEXT,
justification TEXT,
confiance INTEGER NOT NULL DEFAULT 50,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
UNIQUE (
entite_source_id,
entite_cible_id,
type_relation
),
FOREIGN KEY (entite_source_id)
REFERENCES entites(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (entite_cible_id)
REFERENCES entites(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (
entite_source_id <> entite_cible_id
),
CHECK (
length(trim(type_relation)) > 0
),
CHECK (
label IS NULL
OR length(trim(label)) > 0
),
CHECK (
confiance BETWEEN 0 AND 100
),
CHECK (
status IN (
'active',
'archived',
'deleted',
'disputed'
)
)
);
CREATE INDEX idx_relations_entite_source_id
ON relations(entite_source_id);
CREATE INDEX idx_relations_entite_cible_id
ON relations(entite_cible_id);
CREATE INDEX idx_relations_type_relation
ON relations(type_relation);
CREATE INDEX idx_relations_status
ON relations(status);
CREATE INDEX idx_relations_confiance
ON relations(confiance);
CREATE TABLE relation_preuves
(
relation_id TEXT NOT NULL,
preuve_id TEXT NOT NULL,
PRIMARY KEY (
relation_id,
preuve_id
),
FOREIGN KEY (relation_id)
REFERENCES relations(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (preuve_id)
REFERENCES preuves(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_relation_preuves_preuve_id
ON relation_preuves(preuve_id);
CREATE TABLE recherche_relations
(
recherche_id TEXT NOT NULL,
relation_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (
recherche_id,
relation_id,
role
),
FOREIGN KEY (recherche_id)
REFERENCES recherches(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (relation_id)
REFERENCES relations(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (
role IN (
'discovered',
'confirmed',
'contradicted'
)
)
);
CREATE INDEX idx_recherche_relations_relation_id
ON recherche_relations(relation_id);
CREATE TABLE chronologie
(
id TEXT PRIMARY KEY,
event_time TEXT NOT NULL,
titre TEXT NOT NULL,
description TEXT,
origine TEXT NOT NULL DEFAULT 'manual',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'active',
CHECK (
length(trim(titre)) > 0
),
CHECK (
description IS NULL
OR length(trim(description)) > 0
),
CHECK (
origine IN (
'manual',
'automatic',
'imported'
)
),
CHECK (
status IN (
'active',
'archived',
'deleted'
)
)
);
CREATE INDEX idx_chronologie_event_time
ON chronologie(event_time);
CREATE INDEX idx_chronologie_origine
ON chronologie(origine);
CREATE INDEX idx_chronologie_status
ON chronologie(status);
CREATE TABLE recherche_chronologie
(
recherche_id TEXT NOT NULL,
chronologie_id TEXT NOT NULL,
PRIMARY KEY (
recherche_id,
chronologie_id
),
FOREIGN KEY (recherche_id)
REFERENCES recherches(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (chronologie_id)
REFERENCES chronologie(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE TABLE preuve_chronologie
(
preuve_id TEXT NOT NULL,
chronologie_id TEXT NOT NULL,
PRIMARY KEY (
preuve_id,
chronologie_id
),
FOREIGN KEY (preuve_id)
REFERENCES preuves(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (chronologie_id)
REFERENCES chronologie(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE TABLE entite_chronologie
(
entite_id TEXT NOT NULL,
chronologie_id TEXT NOT NULL,
PRIMARY KEY (
entite_id,
chronologie_id
),
FOREIGN KEY (entite_id)
REFERENCES entites(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (chronologie_id)
REFERENCES chronologie(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE TABLE relation_chronologie
(
relation_id TEXT NOT NULL,
chronologie_id TEXT NOT NULL,
PRIMARY KEY (
relation_id,
chronologie_id
),
FOREIGN KEY (relation_id)
REFERENCES relations(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
FOREIGN KEY (chronologie_id)
REFERENCES chronologie(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE INDEX idx_recherche_chronologie_chronologie_id
ON recherche_chronologie(chronologie_id);
CREATE INDEX idx_preuve_chronologie_chronologie_id
ON preuve_chronologie(chronologie_id);
CREATE INDEX idx_entite_chronologie_chronologie_id
ON entite_chronologie(chronologie_id);
CREATE INDEX idx_relation_chronologie_chronologie_id
ON relation_chronologie(chronologie_id);
CREATE TABLE journal
(
id TEXT PRIMARY KEY,
event_time TEXT NOT NULL,
action TEXT NOT NULL,
objet_type TEXT,
objet_id TEXT,
resultat TEXT NOT NULL,
details TEXT,
acteur TEXT,
created_at TEXT NOT NULL,
CHECK (
length(trim(action)) > 0
),
CHECK (
objet_type IS NULL
OR length(trim(objet_type)) > 0
),
CHECK (
objet_id IS NULL
OR length(trim(objet_id)) > 0
),
CHECK (
(
objet_type IS NULL
AND objet_id IS NULL
)
OR
(
objet_type IS NOT NULL
AND objet_id IS NOT NULL
)
),
CHECK (
resultat IN (
'success',
'failure',
'partial',
'cancelled'
)
),
CHECK (
details IS NULL
OR length(trim(details)) > 0
),
CHECK (
acteur IS NULL
OR length(trim(acteur)) > 0
)
);
CREATE INDEX idx_journal_event_time
ON journal(event_time);
CREATE INDEX idx_journal_action
ON journal(action);
CREATE INDEX idx_journal_objet
ON journal(objet_type, objet_id);
CREATE INDEX idx_journal_resultat
ON journal(resultat);
CREATE TABLE hypotheses
(
id TEXT PRIMARY KEY,
titre TEXT NOT NULL,
description TEXT NOT NULL,
categorie_id TEXT,
confiance INTEGER NOT NULL DEFAULT 50,
evaluation TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'proposed',
FOREIGN KEY (categorie_id)
REFERENCES categories(id)
ON UPDATE CASCADE
ON DELETE SET NULL
CHECK (
length(trim(titre)) > 0
),
CHECK (
length(trim(description)) > 0
),
CHECK (
confiance BETWEEN 0 AND 100
),
CHECK (
evaluation IS NULL
OR length(trim(evaluation)) > 0
),
CHECK (
status IN (
'proposed',
'under_review',
'supported',
'contradicted',
'confirmed',
'rejected',
'archived'
)
)
);
CREATE INDEX idx_hypotheses_status
ON hypotheses(status);
CREATE INDEX idx_hypotheses_confiance
ON hypotheses(confiance);
CREATE INDEX idx_hypotheses_updated_at
ON hypotheses(updated_at);
CREATE INDEX idx_hypotheses_categorie_id
ON hypotheses(categorie_id);
CREATE TABLE hypothese_preuves
(
hypothese_id TEXT NOT NULL,
preuve_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (
hypothese_id,
preuve_id,
role
),
FOREIGN KEY (hypothese_id)
REFERENCES hypotheses(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (preuve_id)
REFERENCES preuves(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (
role IN (
'supports',
'contradicts',
'confirms'
)
)
);
CREATE INDEX idx_hypothese_preuves_preuve_id
ON hypothese_preuves(preuve_id);
CREATE TABLE hypothese_entites
(
hypothese_id TEXT NOT NULL,
entite_id TEXT NOT NULL,
PRIMARY KEY (
hypothese_id,
entite_id
),
FOREIGN KEY (hypothese_id)
REFERENCES hypotheses(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (entite_id)
REFERENCES entites(id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE INDEX idx_hypothese_entites_entite_id
ON hypothese_entites(entite_id);
CREATE TABLE hypothese_relations
(
hypothese_id TEXT NOT NULL,
relation_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (
hypothese_id,
relation_id,
role
),
FOREIGN KEY (hypothese_id)
REFERENCES hypotheses(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (relation_id)
REFERENCES relations(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (
role IN (
'supports',
'contradicts'
)
)
);
CREATE INDEX idx_hypothese_relations_relation_id
ON hypothese_relations(relation_id);
CREATE TABLE recherche_hypotheses
(
recherche_id TEXT NOT NULL,
hypothese_id TEXT NOT NULL,
role TEXT NOT NULL,
PRIMARY KEY (
recherche_id,
hypothese_id,
role
),
FOREIGN KEY (recherche_id)
REFERENCES recherches(id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (hypothese_id)
REFERENCES hypotheses(id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CHECK (
role IN (
'created',
'enriched',
'confirmed',
'contradicted'
)
)
);
CREATE INDEX idx_recherche_hypotheses_hypothese_id
ON recherche_hypotheses(hypothese_id);
INSERT INTO types_outil
(id, code, label)
VALUES
(1, 'web_browser', 'Navigateur web'),
(2, 'search_engine', 'Moteur de recherche'),
(3, 'dns_tool', 'Outil DNS'),
(4, 'whois_tool', 'Outil WHOIS'),
(5, 'social_network', 'Réseau social'),
(6, 'email_tool', 'Outil email'),
(7, 'metadata_tool', 'Outil de métadonnées'),
(8, 'hash_tool', 'Outil de calcul de hash'),
(9, 'ocr_tool', 'Outil OCR'),
(10, 'custom_script', 'Script personnalisé'),
(11, 'manual_process', 'Procédure manuelle'),
(12, 'other', 'Autre');