InfoVault-Mobile / models /document.py
Kishore200630's picture
Update models/document.py
2c26829 verified
Raw
History Blame Contribute Delete
6.27 kB
"""
Document model for mobile app.
No S3 keys - documents are stored locally on device.
Backend stores metadata + extracted text for AI processing.
"""
from datetime import datetime
from bson import ObjectId
from typing import List, Optional
from models import mongo
class Document:
"""Document model for mobile app - local storage focus."""
collection_name = 'documents'
@staticmethod
def create(
user_id: str,
name: str,
doc_type: str,
original_filename: str,
file_size: int,
mime_type: str,
has_expiry: bool = False,
expiry_date: datetime = None,
extracted_text: str = None,
extracted_data: dict = None
) -> dict:
"""
Create a new document metadata entry.
No S3 key - documents stored locally on mobile device.
"""
document = {
'user_id': ObjectId(user_id),
'name': name,
'type': doc_type,
'original_filename': original_filename,
'file_size': file_size,
'mime_type': mime_type,
'has_expiry': has_expiry,
'expiry_date': expiry_date,
'extracted_text': extracted_text,
'extracted_data': extracted_data or {}, # Key-value pairs extracted from document
'processing_status': 'completed' if extracted_text else 'pending',
'created_at': datetime.utcnow(),
'updated_at': datetime.utcnow(),
}
result = mongo.db.documents.insert_one(document)
document['_id'] = result.inserted_id
return document
@staticmethod
def find_by_id(document_id: str) -> dict | None:
"""Find a document by ID."""
try:
return mongo.db.documents.find_one({'_id': ObjectId(document_id)})
except Exception:
return None
@staticmethod
def find_by_user(user_id: str, limit: int = 100) -> List[dict]:
"""Find all documents for a user."""
return list(mongo.db.documents.find(
{'user_id': ObjectId(user_id)}
).sort('created_at', -1).limit(limit))
@staticmethod
def find_expiring(user_id: str = None, days: int = 7) -> List[dict]:
"""Find documents expiring within specified days."""
from datetime import timedelta
now = datetime.utcnow()
expiry_threshold = now + timedelta(days=days)
query = {
'has_expiry': True,
'expiry_date': {
'$gte': now,
'$lte': expiry_threshold
}
}
if user_id:
query['user_id'] = ObjectId(user_id)
return list(mongo.db.documents.find(query).sort('expiry_date', 1))
@staticmethod
def find_expired(user_id: str = None) -> List[dict]:
"""Find documents that have already expired."""
now = datetime.utcnow()
query = {
'has_expiry': True,
'expiry_date': {'$lt': now}
}
if user_id:
query['user_id'] = ObjectId(user_id)
return list(mongo.db.documents.find(query).sort('expiry_date', 1))
@staticmethod
def count_by_user(user_id: str) -> int:
"""Count documents for a user."""
return mongo.db.documents.count_documents({'user_id': ObjectId(user_id)})
@staticmethod
def count_with_expiry(user_id: str) -> int:
"""Count documents with expiry dates for a user."""
return mongo.db.documents.count_documents({
'user_id': ObjectId(user_id),
'has_expiry': True
})
@staticmethod
def delete(document_id: str, user_id: str) -> bool:
"""Delete a document (only if user owns it)."""
result = mongo.db.documents.delete_one({
'_id': ObjectId(document_id),
'user_id': ObjectId(user_id)
})
return result.deleted_count > 0
@staticmethod
def update(document_id: str, user_id: str, fields: dict) -> bool:
"""Update document fields."""
fields['updated_at'] = datetime.utcnow()
fields.pop('user_id', None)
result = mongo.db.documents.update_one(
{'_id': ObjectId(document_id), 'user_id': ObjectId(user_id)},
{'$set': fields}
)
return result.modified_count > 0
@staticmethod
def update_extracted_data(document_id: str, extracted_data: dict) -> bool:
"""Update extracted key-value data for a document."""
result = mongo.db.documents.update_one(
{'_id': ObjectId(document_id)},
{'$set': {
'extracted_data': extracted_data,
'processing_status': 'completed',
'updated_at': datetime.utcnow()
}}
)
return result.modified_count > 0
@staticmethod
def get_recent(user_id: str, limit: int = 5) -> List[dict]:
"""Get recent documents for a user."""
return list(mongo.db.documents.find(
{'user_id': ObjectId(user_id)}
).sort('created_at', -1).limit(limit))
@staticmethod
def to_dict(doc: dict) -> dict:
"""Convert document to dictionary for API response."""
if not doc:
return None
return {
'id': str(doc['_id']),
'name': doc.get('name'),
'type': doc.get('type'),
'originalFilename': doc.get('original_filename'),
'fileSize': doc.get('file_size'),
'mimeType': doc.get('mime_type'),
'hasExpiry': doc.get('has_expiry', False),
'expiryDate': (doc.get('expiry_date').isoformat() + 'Z') if doc.get('expiry_date') else None,
'extractedData': doc.get('extracted_data', {}),
'processingStatus': doc.get('processing_status', 'completed'),
'uploadDate': (doc.get('created_at').isoformat() + 'Z') if doc.get('created_at') else None,
'createdAt': (doc.get('created_at').isoformat() + 'Z') if doc.get('created_at') else None,
'updatedAt': (doc.get('updated_at').isoformat() + 'Z') if doc.get('updated_at') else None,
}