This commit is contained in:
parent
cccf02b8dc
commit
a45bd56ad0
|
|
@ -38,6 +38,7 @@ class ReportCreate(BaseModel):
|
|||
market_type: str # us, twse, tpex
|
||||
analysis_date: str
|
||||
result: dict
|
||||
language: Optional[str] = None
|
||||
|
||||
|
||||
class ReportResponse(BaseModel):
|
||||
|
|
@ -47,6 +48,7 @@ class ReportResponse(BaseModel):
|
|||
market_type: str
|
||||
analysis_date: str
|
||||
result: dict
|
||||
language: Optional[str] = None
|
||||
created_at: str
|
||||
|
||||
|
||||
|
|
@ -166,6 +168,7 @@ async def get_reports(
|
|||
market_type=r.market_type,
|
||||
analysis_date=r.analysis_date,
|
||||
result=r.result,
|
||||
language=r.language,
|
||||
created_at=r.created_at.isoformat() + "Z"
|
||||
)
|
||||
for r in reports
|
||||
|
|
@ -184,7 +187,8 @@ async def create_report(
|
|||
ticker=report_data.ticker,
|
||||
market_type=report_data.market_type,
|
||||
analysis_date=report_data.analysis_date,
|
||||
result=report_data.result
|
||||
result=report_data.result,
|
||||
language=report_data.language
|
||||
)
|
||||
db.add(report)
|
||||
await db.commit()
|
||||
|
|
@ -223,6 +227,7 @@ async def get_report(
|
|||
market_type=report.market_type,
|
||||
analysis_date=report.analysis_date,
|
||||
result=report.result,
|
||||
language=report.language,
|
||||
created_at=report.created_at.isoformat() + "Z"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,16 @@ async def init_db():
|
|||
async with engine.begin() as conn:
|
||||
# Create all tables
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
# Manual migrations for existing databases
|
||||
try:
|
||||
# Add language column if it doesn't exist
|
||||
await conn.execute(text("ALTER TABLE reports ADD COLUMN IF NOT EXISTS language VARCHAR(10);"))
|
||||
# Add indexes to optimize queries
|
||||
await conn.execute(text("CREATE INDEX IF NOT EXISTS ix_reports_user_id ON reports (user_id);"))
|
||||
await conn.execute(text("CREATE INDEX IF NOT EXISTS ix_reports_created_at ON reports (created_at);"))
|
||||
except Exception as e:
|
||||
print(f"Skipping manual migration (might be SQLite or syntax not supported): {e}")
|
||||
|
||||
print("Database tables initialized successfully")
|
||||
|
||||
|
|
|
|||
|
|
@ -85,17 +85,20 @@ class Report(Base):
|
|||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
UUID(as_uuid=True),
|
||||
ForeignKey("users.id", ondelete="CASCADE"),
|
||||
nullable=False
|
||||
nullable=False,
|
||||
index=True
|
||||
)
|
||||
ticker: Mapped[str] = mapped_column(String(20), nullable=False)
|
||||
market_type: Mapped[str] = mapped_column(String(10), nullable=False) # us, twse, tpex
|
||||
analysis_date: Mapped[str] = mapped_column(String(10), nullable=False) # YYYY-MM-DD
|
||||
# Store full result as JSONB
|
||||
result: Mapped[dict] = mapped_column(JSON, nullable=False)
|
||||
language: Mapped[Optional[str]] = mapped_column(String(10), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime,
|
||||
default=datetime.utcnow,
|
||||
nullable=False
|
||||
nullable=False,
|
||||
index=True
|
||||
)
|
||||
|
||||
# Relationship
|
||||
|
|
|
|||
|
|
@ -574,43 +574,18 @@ export default function HistoryPage() {
|
|||
new Date(b.saved_at).getTime() - new Date(a.saved_at).getTime(),
|
||||
);
|
||||
|
||||
// Filter by current language
|
||||
const languageFiltered = merged.filter((report) => {
|
||||
// Use stored language if available
|
||||
if (report.language) {
|
||||
return report.language === locale;
|
||||
}
|
||||
// Fallback: detect from content for old reports without language field
|
||||
return detectReportLanguage(report.result?.reports) === locale;
|
||||
});
|
||||
|
||||
setReports(languageFiltered);
|
||||
setReports(merged);
|
||||
setIsCloudData(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If no cloud data or not authenticated, use local only
|
||||
// Filter by current language
|
||||
const languageFiltered = localData.filter((report) => {
|
||||
if (report.language) {
|
||||
return report.language === locale;
|
||||
}
|
||||
return detectReportLanguage(report.result?.reports) === locale;
|
||||
});
|
||||
setReports(languageFiltered);
|
||||
setReports(localData);
|
||||
setIsCloudData(false);
|
||||
} catch (error) {
|
||||
console.error("Failed to load reports:", error);
|
||||
// Fall back to local on error
|
||||
const data = await getReportsByMarketType(activeTab);
|
||||
const languageFiltered = data.filter((report) => {
|
||||
if (report.language) {
|
||||
return report.language === locale;
|
||||
}
|
||||
return detectReportLanguage(report.result?.reports) === locale;
|
||||
});
|
||||
setReports(languageFiltered);
|
||||
setReports(data as SavedReport[]);
|
||||
setIsCloudData(false);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
|
@ -621,12 +596,7 @@ export default function HistoryPage() {
|
|||
try {
|
||||
// Helper to filter reports by language
|
||||
const filterByLanguage = (reports: SavedReport[]) => {
|
||||
return reports.filter(report => {
|
||||
if (report.language) {
|
||||
return report.language === locale;
|
||||
}
|
||||
return detectReportLanguage(report.result?.reports) === locale;
|
||||
});
|
||||
return reports;
|
||||
};
|
||||
|
||||
if (isAuthenticated && isCloudSyncEnabled()) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue