Files
ORCID2SWORD/backend/app/db/models.py
T
Mireya Cueto Garrido af1b8e9956 feat: enhance backend security and configuration
- Updated Dockerfile to improve security with a non-root user and added health checks.
- Modified docker-compose.yml to set containers as read-only, restrict ports to localhost, and implement health checks.
- Enhanced .env.example with additional environment variables for security and configuration.
- Improved FastAPI application with middleware for security headers, CORS, and body size limits.
- Refactored authentication flow in auth.py to include state validation and improved error handling.
- Added rate limiting to various endpoints to prevent abuse.
- Updated researcher and publication handling to ensure better validation and error management.
2026-05-08 11:19:52 +02:00

93 lines
3.4 KiB
Python

from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.orm import relationship
import uuid
from datetime import datetime
from app.db.session import Base
# ---------------------------------------------------------
# Modelo de investigador
# ---------------------------------------------------------
class Researcher(Base):
__tablename__ = "researchers"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
orcid_id = Column(String, unique=True, index=True, nullable=False)
name = Column(String, nullable=True)
authenticated = Column(Boolean, default=False)
last_sync_at = Column(DateTime, nullable=True)
publications = relationship("Publication", back_populates="researcher", cascade="all, delete-orphan")
# ---------------------------------------------------------
# Modelo de publicación
# ---------------------------------------------------------
class Publication(Base):
__tablename__ = "publications"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
researcher_id = Column(UUID(as_uuid=True), ForeignKey("researchers.id"), nullable=False)
researcher = relationship("Researcher", back_populates="publications")
# ORCID core
put_code = Column(Integer, index=True, nullable=False)
title = Column(String, nullable=True)
subtitle = Column(String, nullable=True)
type = Column(String, nullable=True)
# Journal / container
journal = Column(String, nullable=True)
# Dates
pub_year = Column(Integer, nullable=True)
pub_month = Column(Integer, nullable=True)
pub_day = Column(Integer, nullable=True)
# Identifiers / links
doi = Column(String, nullable=True)
url = Column(String, nullable=True)
# Description / citation
short_description = Column(String, nullable=True)
citation_type = Column(String, nullable=True)
citation_value = Column(String, nullable=True)
# Language / country
language_code = Column(String, nullable=True)
country = Column(String, nullable=True)
# Extra structured data
external_ids = Column(JSONB, nullable=True) # lista de external-id normalizados
contributors = Column(JSONB, nullable=True) # lista de autores/roles
# Tu campo existente
hash_fingerprint = Column(String, nullable=True)
last_modified = Column(DateTime, nullable=True, default=None)
# Legacy: descargado global (deprecado). Mantener por compatibilidad de DB.
downloaded = Column(Boolean, nullable=False, default=False)
# ---------------------------------------------------------
# Modelo de descarga de publicación
# ---------------------------------------------------------
class PublicationDownload(Base):
"""
Marca de descarga por usuario (researcher) sobre cualquier publicación.
Una fila por (researcher_id, publication_id).
"""
__tablename__ = "publication_downloads"
__table_args__ = (
UniqueConstraint("researcher_id", "publication_id", name="uq_publication_download"),
)
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
researcher_id = Column(UUID(as_uuid=True), ForeignKey("researchers.id"), nullable=False, index=True)
publication_id = Column(UUID(as_uuid=True), ForeignKey("publications.id"), nullable=False, index=True)
downloaded_at = Column(DateTime, nullable=False, default=datetime.utcnow)