Backend:
- Document + MemoryEntry models with Alembic migration (GIN FTS index)
- File upload endpoint with path traversal protection (sanitized filenames)
- Background document text extraction (PyMuPDF)
- Full-text search on extracted_text via PostgreSQL tsvector/tsquery
- Memory CRUD with enum-validated categories/importance, field allow-list
- AI tools: save_memory, search_documents, get_memory (Claude function calling)
- Tool execution loop in stream_ai_response (multi-turn tool use)
- Context assembly: injects critical memory + relevant doc excerpts
- File storage abstraction (local filesystem, S3-swappable)
- Secure file deletion (DB flush before disk delete)
Frontend:
- Document upload dialog (drag-and-drop + file picker)
- Document list with status badges, search, download (via authenticated blob)
- Document viewer with extracted text preview
- Memory list grouped by category with importance color coding
- Memory editor with category/importance dropdowns
- Documents + Memory pages with full CRUD
- Enabled sidebar navigation for both sections
Review fixes applied:
- Sanitized upload filenames (path traversal prevention)
- Download via axios blob (not bare <a href>, preserves auth)
- Route ordering: /search before /{id}/reindex
- Memory update allows is_active=False + field allow-list
- MemoryEditor form resets on mode switch
- Literal enum validation on category/importance schemas
- DB flush before file deletion for data integrity
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
155 lines
4.8 KiB
JSON
155 lines
4.8 KiB
JSON
{
|
|
"auth": {
|
|
"login": "Log In",
|
|
"register": "Sign Up",
|
|
"email": "Email",
|
|
"password": "Password",
|
|
"confirmPassword": "Confirm Password",
|
|
"username": "Username",
|
|
"fullName": "Full Name",
|
|
"rememberMe": "Remember me",
|
|
"submit": "Submit",
|
|
"noAccount": "Don't have an account?",
|
|
"hasAccount": "Already have an account?",
|
|
"loginTitle": "Welcome Back",
|
|
"loginSubtitle": "Sign in to your account",
|
|
"registerTitle": "Create Account",
|
|
"registerSubtitle": "Get started with your personal AI assistant",
|
|
"errors": {
|
|
"invalidCredentials": "Invalid email or password",
|
|
"emailExists": "User with this email or username already exists",
|
|
"passwordMismatch": "Passwords do not match",
|
|
"passwordMinLength": "Password must be at least 8 characters",
|
|
"usernameFormat": "Username must be 3-50 characters (letters, numbers, _ or -)",
|
|
"required": "This field is required"
|
|
}
|
|
},
|
|
"layout": {
|
|
"dashboard": "Dashboard",
|
|
"chats": "Chats",
|
|
"documents": "Documents",
|
|
"memory": "Memory",
|
|
"notifications": "Notifications",
|
|
"profile": "Profile",
|
|
"logout": "Log Out",
|
|
"settings": "Settings",
|
|
"admin": "Admin",
|
|
"users": "Users",
|
|
"context": "Context",
|
|
"skills": "Skills",
|
|
"personal_context": "My Context"
|
|
},
|
|
"dashboard": {
|
|
"welcome": "Welcome, {{name}}",
|
|
"subtitle": "Your personal AI health assistant"
|
|
},
|
|
"chat": {
|
|
"new_chat": "New Chat",
|
|
"no_chats": "No chats yet. Create one to get started.",
|
|
"no_messages": "Start a conversation...",
|
|
"select_chat": "Select a chat to start messaging",
|
|
"type_message": "Type a message...",
|
|
"send": "Send",
|
|
"archive": "Archive",
|
|
"unarchive": "Unarchive",
|
|
"delete_confirm": "Are you sure you want to delete this chat?",
|
|
"limit_reached": "Chat limit reached",
|
|
"streaming": "AI is thinking..."
|
|
},
|
|
"admin": {
|
|
"context_editor": "Primary Context Editor",
|
|
"context_placeholder": "Enter the system prompt for the AI assistant...",
|
|
"save": "Save",
|
|
"saved": "Saved",
|
|
"unsaved_changes": "Unsaved changes",
|
|
"version": "Version",
|
|
"characters": "characters"
|
|
},
|
|
"skills": {
|
|
"my_skills": "My Skills",
|
|
"general_skills": "General Skills",
|
|
"no_skills": "No skills yet.",
|
|
"no_personal_skills": "You haven't created any personal skills yet.",
|
|
"create_personal": "Create Personal Skill",
|
|
"edit_personal": "Edit Personal Skill",
|
|
"create_general": "Create General Skill",
|
|
"edit_general": "Edit General Skill",
|
|
"name": "Name",
|
|
"name_placeholder": "e.g. Cardiologist",
|
|
"description": "Description",
|
|
"description_placeholder": "Brief description of this specialist",
|
|
"system_prompt": "System Prompt",
|
|
"prompt_placeholder": "Instructions for the AI when using this skill...",
|
|
"icon": "Icon",
|
|
"no_skill": "No specialist",
|
|
"general": "General",
|
|
"personal": "Personal"
|
|
},
|
|
"personal_context": {
|
|
"title": "Personal Context",
|
|
"subtitle": "This context is added to all your AI conversations",
|
|
"placeholder": "Add personal information that the AI should know about you..."
|
|
},
|
|
"documents": {
|
|
"upload": "Upload",
|
|
"drop_or_click": "Drop a file here or click to browse",
|
|
"doc_type": "Document Type",
|
|
"no_documents": "No documents uploaded yet.",
|
|
"download": "Download",
|
|
"reindex": "Re-extract text",
|
|
"extracted_text": "Extracted Text",
|
|
"search_placeholder": "Search documents...",
|
|
"clear_search": "Clear",
|
|
"types": {
|
|
"other": "Other",
|
|
"lab_result": "Lab Result",
|
|
"consultation": "Consultation",
|
|
"prescription": "Prescription",
|
|
"imaging": "Imaging"
|
|
},
|
|
"status": {
|
|
"pending": "Pending",
|
|
"processing": "Processing",
|
|
"completed": "Completed",
|
|
"failed": "Failed"
|
|
}
|
|
},
|
|
"memory": {
|
|
"create": "Add Memory Entry",
|
|
"edit": "Edit Memory Entry",
|
|
"no_entries": "No memory entries yet. The AI will save important health information here.",
|
|
"category": "Category",
|
|
"importance": "Importance",
|
|
"title_field": "Title",
|
|
"title_placeholder": "e.g. Diabetes Type 2",
|
|
"content_field": "Content",
|
|
"content_placeholder": "Detailed information...",
|
|
"categories": {
|
|
"condition": "Condition",
|
|
"medication": "Medication",
|
|
"allergy": "Allergy",
|
|
"vital": "Vital Sign",
|
|
"document_summary": "Document Summary",
|
|
"other": "Other"
|
|
},
|
|
"importance_levels": {
|
|
"critical": "Critical",
|
|
"high": "High",
|
|
"medium": "Medium",
|
|
"low": "Low"
|
|
}
|
|
},
|
|
"common": {
|
|
"loading": "Loading...",
|
|
"error": "An error occurred",
|
|
"notFound": "Page not found",
|
|
"goHome": "Go to Dashboard",
|
|
"save": "Save",
|
|
"cancel": "Cancel",
|
|
"delete": "Delete",
|
|
"edit": "Edit",
|
|
"create": "Create",
|
|
"search": "Search"
|
|
}
|
|
}
|