Madras1 commited on
Commit
3ecc1d1
·
verified ·
1 Parent(s): 7c8e3aa

Upload 59 files

Browse files
app/api/routes/timeline.py CHANGED
@@ -73,13 +73,15 @@ async def get_timeline(
73
  }
74
 
75
  for e in entities:
 
 
76
  events.append(TimelineEvent(
77
  id=e.id,
78
  type="entity",
79
  entity_type=e.type,
80
  name=e.name,
81
  description=e.description[:100] if e.description else None,
82
- date=e.created_at.isoformat() if e.created_at else datetime.now().isoformat(),
83
  icon=icon_map.get(e.type, "📄")
84
  ))
85
 
@@ -93,12 +95,14 @@ async def get_timeline(
93
  target = db.query(Entity).filter(Entity.id == r.target_id).first()
94
 
95
  if source and target:
 
 
96
  events.append(TimelineEvent(
97
  id=r.id,
98
  type="relationship",
99
  name=f"{source.name} → {target.name}",
100
  description=r.type,
101
- date=r.created_at.isoformat() if r.created_at else datetime.now().isoformat(),
102
  icon="🔗"
103
  ))
104
 
 
73
  }
74
 
75
  for e in entities:
76
+ # Prefer event_date over created_at
77
+ date = e.event_date if e.event_date else e.created_at
78
  events.append(TimelineEvent(
79
  id=e.id,
80
  type="entity",
81
  entity_type=e.type,
82
  name=e.name,
83
  description=e.description[:100] if e.description else None,
84
+ date=date.isoformat() if date else datetime.now().isoformat(),
85
  icon=icon_map.get(e.type, "📄")
86
  ))
87
 
 
95
  target = db.query(Entity).filter(Entity.id == r.target_id).first()
96
 
97
  if source and target:
98
+ # Prefer event_date over created_at
99
+ date = r.event_date if r.event_date else r.created_at
100
  events.append(TimelineEvent(
101
  id=r.id,
102
  type="relationship",
103
  name=f"{source.name} → {target.name}",
104
  description=r.type,
105
+ date=date.isoformat() if date else datetime.now().isoformat(),
106
  icon="🔗"
107
  ))
108
 
app/models/entity.py CHANGED
@@ -30,6 +30,9 @@ class Entity(Base):
30
  latitude = Column(Float, nullable=True)
31
  longitude = Column(Float, nullable=True)
32
 
 
 
 
33
  # Fonte do dado
34
  source = Column(String(100), nullable=True) # wikipedia, newsapi, manual, etc
35
  source_url = Column(Text, nullable=True)
@@ -65,6 +68,9 @@ class Relationship(Base):
65
  properties = Column(JSON, default=dict)
66
  confidence = Column(Float, default=1.0) # 0-1, quão certo estamos dessa conexão
67
 
 
 
 
68
  # Fonte
69
  source = Column(String(100), nullable=True)
70
 
 
30
  latitude = Column(Float, nullable=True)
31
  longitude = Column(Float, nullable=True)
32
 
33
+ # Data histórica do evento/entidade (quando aconteceu, não quando foi adicionado)
34
+ event_date = Column(DateTime, nullable=True)
35
+
36
  # Fonte do dado
37
  source = Column(String(100), nullable=True) # wikipedia, newsapi, manual, etc
38
  source_url = Column(Text, nullable=True)
 
68
  properties = Column(JSON, default=dict)
69
  confidence = Column(Float, default=1.0) # 0-1, quão certo estamos dessa conexão
70
 
71
+ # Data histórica do relacionamento (quando aconteceu)
72
+ event_date = Column(DateTime, nullable=True)
73
+
74
  # Fonte
75
  source = Column(String(100), nullable=True)
76
 
app/services/nlp/entity_extractor.py CHANGED
@@ -21,6 +21,7 @@ class ExtractedEntity:
21
  description: Optional[str] = None
22
  latitude: Optional[float] = None
23
  longitude: Optional[float] = None
 
24
 
25
 
26
  @dataclass
@@ -30,6 +31,7 @@ class ExtractedRelationship:
30
  target: str
31
  relationship_type: str
32
  context: Optional[str] = None
 
33
 
34
 
35
  @dataclass
@@ -62,6 +64,7 @@ Analise o texto fornecido e extraia TODAS as entidades, relacionamentos e evento
62
  4. Para LOCAIS: seja específico (cidade, país, endereço)
63
  5. Identifique RELACIONAMENTOS entre entidades (quem trabalha onde, quem conhece quem, etc.)
64
  6. Identifique EVENTOS mencionados (reuniões, anúncios, eleições, etc.)
 
65
 
66
  ## Formato de resposta (JSON válido):
67
  ```json
@@ -72,7 +75,8 @@ Analise o texto fornecido e extraia TODAS as entidades, relacionamentos e evento
72
  "type": "person|organization|location|event",
73
  "role": "cargo ou função (opcional)",
74
  "aliases": ["apelidos", "siglas"],
75
- "description": "breve descrição se relevante"
 
76
  }}
77
  ],
78
  "relationships": [
@@ -80,14 +84,15 @@ Analise o texto fornecido e extraia TODAS as entidades, relacionamentos e evento
80
  "source": "Nome da Entidade 1",
81
  "target": "Nome da Entidade 2",
82
  "relationship_type": "tipo de relação (trabalha em, preside, fundou, reuniu-se com, etc.)",
83
- "context": "contexto da relação"
 
84
  }}
85
  ],
86
  "events": [
87
  {{
88
  "description": "O que aconteceu",
89
  "event_type": "meeting|announcement|election|crime|etc",
90
- "date": "data se mencionada",
91
  "location": "local se mencionado",
92
  "participants": ["lista de participantes"]
93
  }}
@@ -205,7 +210,8 @@ class EntityExtractor:
205
  type=e.get("type", "unknown"),
206
  role=e.get("role"),
207
  aliases=e.get("aliases", []),
208
- description=e.get("description")
 
209
  ))
210
 
211
  # Parse relationships
@@ -215,7 +221,8 @@ class EntityExtractor:
215
  source=r.get("source", ""),
216
  target=r.get("target", ""),
217
  relationship_type=r.get("relationship_type", "related_to"),
218
- context=r.get("context")
 
219
  ))
220
 
221
  # Parse events
 
21
  description: Optional[str] = None
22
  latitude: Optional[float] = None
23
  longitude: Optional[float] = None
24
+ event_date: Optional[str] = None # Date in ISO format (YYYY-MM-DD)
25
 
26
 
27
  @dataclass
 
31
  target: str
32
  relationship_type: str
33
  context: Optional[str] = None
34
+ event_date: Optional[str] = None # Date in ISO format (YYYY-MM-DD)
35
 
36
 
37
  @dataclass
 
64
  4. Para LOCAIS: seja específico (cidade, país, endereço)
65
  5. Identifique RELACIONAMENTOS entre entidades (quem trabalha onde, quem conhece quem, etc.)
66
  6. Identifique EVENTOS mencionados (reuniões, anúncios, eleições, etc.)
67
+ 7. EXTRAIA DATAS sempre que mencionadas (formato YYYY-MM-DD ou YYYY se só o ano)
68
 
69
  ## Formato de resposta (JSON válido):
70
  ```json
 
75
  "type": "person|organization|location|event",
76
  "role": "cargo ou função (opcional)",
77
  "aliases": ["apelidos", "siglas"],
78
+ "description": "breve descrição se relevante",
79
+ "event_date": "YYYY-MM-DD ou YYYY (data relevante como nascimento, fundação, etc)"
80
  }}
81
  ],
82
  "relationships": [
 
84
  "source": "Nome da Entidade 1",
85
  "target": "Nome da Entidade 2",
86
  "relationship_type": "tipo de relação (trabalha em, preside, fundou, reuniu-se com, etc.)",
87
+ "context": "contexto da relação",
88
+ "event_date": "YYYY-MM-DD ou YYYY (quando o relacionamento aconteceu/iniciou)"
89
  }}
90
  ],
91
  "events": [
92
  {{
93
  "description": "O que aconteceu",
94
  "event_type": "meeting|announcement|election|crime|etc",
95
+ "date": "YYYY-MM-DD ou YYYY",
96
  "location": "local se mencionado",
97
  "participants": ["lista de participantes"]
98
  }}
 
210
  type=e.get("type", "unknown"),
211
  role=e.get("role"),
212
  aliases=e.get("aliases", []),
213
+ description=e.get("description"),
214
+ event_date=e.get("event_date")
215
  ))
216
 
217
  # Parse relationships
 
221
  source=r.get("source", ""),
222
  target=r.get("target", ""),
223
  relationship_type=r.get("relationship_type", "related_to"),
224
+ context=r.get("context"),
225
+ event_date=r.get("event_date")
226
  ))
227
 
228
  # Parse events