new file: .dockerignore
new file: .env.example new file: Dockerfile new file: app.py new file: blueprints/__init__.py new file: blueprints/auth.py new file: blueprints/chat.py new file: blueprints/context.py new file: blueprints/documents.py new file: blueprints/main.py new file: config.py new file: docker-compose.yml new file: models/__init__.py new file: models/chat_session.py new file: models/document.py new file: models/user.py new file: requirements.txt new file: services/__init__.py new file: services/document_parser.py new file: services/llm_service.py new file: services/rag_service.py new file: services/url_scraper.py new file: static/css/style.css new file: static/js/chat.js new file: static/js/inline_chat.js new file: static/js/main.js new file: templates/base.html new file: templates/document_view.html new file: templates/index.html new file: templates/login.html new file: templates/register.html
This commit is contained in:
9
models/__init__.py
Normal file
9
models/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
from .user import User
|
||||
from .document import Document, UrlContext
|
||||
from .chat_session import ChatSession, ChatMessage
|
||||
|
||||
__all__ = ["db", "User", "Document", "UrlContext", "ChatSession", "ChatMessage"]
|
||||
45
models/chat_session.py
Normal file
45
models/chat_session.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from datetime import datetime
|
||||
import json
|
||||
from . import db
|
||||
|
||||
|
||||
class ChatSession(db.Model):
|
||||
__tablename__ = "chat_sessions"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
|
||||
title = db.Column(db.String(255), default="New Chat")
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
messages = db.relationship(
|
||||
"ChatMessage", backref="session", lazy=True, cascade="all, delete-orphan",
|
||||
order_by="ChatMessage.created_at"
|
||||
)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"title": self.title,
|
||||
"created_at": self.created_at.isoformat(),
|
||||
"updated_at": self.updated_at.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
class ChatMessage(db.Model):
|
||||
__tablename__ = "chat_messages"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
session_id = db.Column(db.Integer, db.ForeignKey("chat_sessions.id"), nullable=False)
|
||||
role = db.Column(db.String(16), nullable=False) # "user" | "assistant"
|
||||
content = db.Column(db.Text, nullable=False)
|
||||
context_ids = db.Column(db.Text, nullable=True) # JSON list of doc/url ids used
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"role": self.role,
|
||||
"content": self.content,
|
||||
"created_at": self.created_at.isoformat(),
|
||||
}
|
||||
43
models/document.py
Normal file
43
models/document.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from datetime import datetime
|
||||
from . import db
|
||||
|
||||
|
||||
class Document(db.Model):
|
||||
__tablename__ = "documents"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
|
||||
filename = db.Column(db.String(255), nullable=False)
|
||||
original_name = db.Column(db.String(255), nullable=False)
|
||||
file_type = db.Column(db.String(16), nullable=False)
|
||||
indexed = db.Column(db.Boolean, default=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"original_name": self.original_name,
|
||||
"file_type": self.file_type,
|
||||
"indexed": self.indexed,
|
||||
"created_at": self.created_at.isoformat(),
|
||||
}
|
||||
|
||||
|
||||
class UrlContext(db.Model):
|
||||
__tablename__ = "url_contexts"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
|
||||
url = db.Column(db.String(2048), nullable=False)
|
||||
title = db.Column(db.String(512), nullable=True)
|
||||
indexed = db.Column(db.Boolean, default=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"url": self.url,
|
||||
"title": self.title or self.url,
|
||||
"indexed": self.indexed,
|
||||
"created_at": self.created_at.isoformat(),
|
||||
}
|
||||
21
models/user.py
Normal file
21
models/user.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_login import UserMixin
|
||||
from datetime import datetime
|
||||
from . import db
|
||||
|
||||
|
||||
class User(UserMixin, db.Model):
|
||||
__tablename__ = "users"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(64), unique=True, nullable=False)
|
||||
email = db.Column(db.String(120), unique=True, nullable=False)
|
||||
password_hash = db.Column(db.String(256), nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
documents = db.relationship("Document", backref="owner", lazy=True, cascade="all, delete-orphan")
|
||||
url_contexts = db.relationship("UrlContext", backref="owner", lazy=True, cascade="all, delete-orphan")
|
||||
chat_sessions = db.relationship("ChatSession", backref="owner", lazy=True, cascade="all, delete-orphan")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User {self.username}>"
|
||||
Reference in New Issue
Block a user