Bromeo777 commited on
Commit
5167d8e
·
verified ·
1 Parent(s): 13c8874

Add app\models\writesage.py

Browse files
Files changed (1) hide show
  1. app//models//writesage.py +133 -0
app//models//writesage.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/models/writesage.py
2
+ # Final Version: Fixed SQLAlchemy column type error
3
+ # Timestamp: 2026-03-13
4
+
5
+ from datetime import datetime
6
+ from typing import Optional, List, Dict, Any
7
+ import enum
8
+
9
+ from sqlalchemy import (
10
+ String,
11
+ Integer,
12
+ DateTime,
13
+ ForeignKey,
14
+ Text,
15
+ JSON,
16
+ Enum,
17
+ Boolean,
18
+ Float, # FIX: Imported Float for proper column type
19
+ )
20
+ from sqlalchemy.orm import Mapped, mapped_column, relationship
21
+ from sqlalchemy.sql import func
22
+
23
+ from app.models.base import Base
24
+
25
+
26
+ class ManuscriptStatus(str, enum.Enum):
27
+ """Lifecycle of a scholarly manuscript."""
28
+ DRAFT = "draft"
29
+ GENERATING = "generating"
30
+ REVIEW_REQUIRED = "review_required"
31
+ COMPLETED = "completed"
32
+
33
+
34
+ class Manuscript(Base):
35
+ """
36
+ Core document being authored within the WriteSage workspace.
37
+ Links to the researcher's Saved Library and extraction context.
38
+ """
39
+ __tablename__ = "writesage_manuscripts"
40
+
41
+ id: Mapped[str] = mapped_column(String(64), primary_key=True)
42
+ user_id: Mapped[int] = mapped_column(
43
+ Integer,
44
+ ForeignKey("users.id", ondelete="CASCADE"),
45
+ nullable=False
46
+ )
47
+ title: Mapped[str] = mapped_column(String(255), nullable=False)
48
+ target_journal: Mapped[Optional[str]] = mapped_column(String(100))
49
+ status: Mapped[ManuscriptStatus] = mapped_column(
50
+ Enum(ManuscriptStatus),
51
+ default=ManuscriptStatus.DRAFT
52
+ )
53
+
54
+ # Metadata context: PICO, effect sizes, and seeds used for grounding
55
+ context_papers: Mapped[str] = mapped_column(Text, default="[]") # JSON list of DOIs
56
+ pico_context_id: Mapped[Optional[str]] = mapped_column(String(64))
57
+
58
+ created_at: Mapped[datetime] = mapped_column(
59
+ DateTime(timezone=True),
60
+ server_default=func.now()
61
+ )
62
+ updated_at: Mapped[datetime] = mapped_column(
63
+ DateTime(timezone=True),
64
+ server_default=func.now(),
65
+ onupdate=func.now()
66
+ )
67
+
68
+ # Relationships
69
+ user = relationship("User", back_populates="manuscripts")
70
+ sections = relationship(
71
+ "ManuscriptSection",
72
+ back_populates="manuscript",
73
+ cascade="all, delete-orphan"
74
+ )
75
+
76
+
77
+ class ManuscriptSection(Base):
78
+ """
79
+ Individual components of the manuscript (IMRaD+ structure).
80
+ Supports dynamic architecture suggestion via StructGen.
81
+ """
82
+ __tablename__ = "writesage_sections"
83
+
84
+ id: Mapped[int] = mapped_column(
85
+ Integer,
86
+ primary_key=True,
87
+ autoincrement=True
88
+ )
89
+ manuscript_id: Mapped[str] = mapped_column(
90
+ ForeignKey("writesage_manuscripts.id", ondelete="CASCADE"),
91
+ nullable=False
92
+ )
93
+ name: Mapped[str] = mapped_column(String(100)) # e.g., "Methods", "Results"
94
+ order_index: Mapped[int] = mapped_column(Integer, nullable=False)
95
+ content: Mapped[Optional[str]] = mapped_column(Text)
96
+ is_ai_generated: Mapped[bool] = mapped_column(Boolean, default=True)
97
+
98
+ # Audit trail for Veritas Shield integrity tracking
99
+ # FIX: Changed from func.float() to Float for proper SQLAlchemy column type
100
+ originality_score: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
101
+
102
+ # Relationships
103
+ manuscript = relationship("Manuscript", back_populates="sections")
104
+
105
+
106
+ class JournalProfile(Base):
107
+ """
108
+ Cached journal intelligence for format adaptation.
109
+ Resolves structure, citation style, and word limits.
110
+ """
111
+ __tablename__ = "writesage_journal_profiles"
112
+
113
+ id: Mapped[int] = mapped_column(
114
+ Integer,
115
+ primary_key=True,
116
+ autoincrement=True
117
+ )
118
+ journal_name: Mapped[str] = mapped_column(
119
+ String(255),
120
+ index=True,
121
+ unique=True
122
+ )
123
+ issn: Mapped[Optional[str]] = mapped_column(String(20), index=True)
124
+
125
+ # Structural intelligence
126
+ required_sections: Mapped[str] = mapped_column(Text) # JSON list
127
+ word_limit: Mapped[Optional[int]] = mapped_column(Integer)
128
+ citation_style: Mapped[str] = mapped_column(String(100)) # e.g., "Vancouver", "APA"
129
+
130
+ last_updated: Mapped[datetime] = mapped_column(
131
+ DateTime(timezone=True),
132
+ server_default=func.now()
133
+ )