## Security Enhancements (P0) - Add input validation with max_length and numeric range constraints - Implement WebSocket token authentication via first message - Add path traversal prevention in file storage service ## Permission Enhancements (P0) - Add project member management for cross-department access - Implement is_department_manager flag for workload visibility ## Cycle Detection (P0) - Add DFS-based cycle detection for task dependencies - Add formula field circular reference detection - Display user-friendly cycle path visualization ## Concurrency & Reliability (P1) - Implement optimistic locking with version field (409 Conflict on mismatch) - Add trigger retry mechanism with exponential backoff (1s, 2s, 4s) - Implement cascade restore for soft-deleted tasks ## Rate Limiting (P1) - Add tiered rate limits: standard (60/min), sensitive (20/min), heavy (5/min) - Apply rate limits to tasks, reports, attachments, and comments ## Frontend Improvements (P1) - Add responsive sidebar with hamburger menu for mobile - Improve touch-friendly UI with proper tap target sizes - Complete i18n translations for all components ## Backend Reliability (P2) - Configure database connection pool (size=10, overflow=20) - Add Redis fallback mechanism with message queue - Add blocker check before task deletion ## API Enhancements (P3) - Add standardized response wrapper utility - Add /health/ready and /health/live endpoints - Implement project templates with status/field copying ## Tests Added - test_input_validation.py - Schema and path traversal tests - test_concurrency_reliability.py - Optimistic locking and retry tests - test_backend_reliability.py - Connection pool and Redis tests - test_api_enhancements.py - Health check and template tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
214 lines
6.3 KiB
JSON
214 lines
6.3 KiB
JSON
{
|
|
"title": "Tasks",
|
|
"createTask": "Create Task",
|
|
"editTask": "Edit Task",
|
|
"deleteTask": "Delete Task",
|
|
"taskDetails": "Task Details",
|
|
"fields": {
|
|
"title": "Title",
|
|
"titlePlaceholder": "Enter task title",
|
|
"description": "Description",
|
|
"descriptionPlaceholder": "Enter task description",
|
|
"status": "Status",
|
|
"priority": "Priority",
|
|
"assignee": "Assignee",
|
|
"dueDate": "Due Date",
|
|
"startDate": "Start Date",
|
|
"estimatedHours": "Estimated Hours",
|
|
"actualHours": "Actual Hours",
|
|
"progress": "Progress",
|
|
"tags": "Tags",
|
|
"parent": "Parent Task",
|
|
"subtasks": "Subtasks",
|
|
"attachments": "Attachments",
|
|
"comments": "Comments",
|
|
"watchers": "Watchers",
|
|
"blockers": "Blockers",
|
|
"hours": "{{count}} hours"
|
|
},
|
|
"status": {
|
|
"todo": "To Do",
|
|
"in_progress": "In Progress",
|
|
"review": "In Review",
|
|
"done": "Done",
|
|
"cancelled": "Cancelled",
|
|
"blocked": "Blocked",
|
|
"noStatus": "No Status",
|
|
"unassigned": "Unassigned",
|
|
"noDueDate": "No due date",
|
|
"notEstimated": "Not estimated"
|
|
},
|
|
"priority": {
|
|
"low": "Low",
|
|
"medium": "Medium",
|
|
"high": "High",
|
|
"urgent": "Urgent"
|
|
},
|
|
"views": {
|
|
"list": "List",
|
|
"kanban": "Kanban",
|
|
"calendar": "Calendar",
|
|
"gantt": "Gantt",
|
|
"timeline": "Timeline"
|
|
},
|
|
"filters": {
|
|
"all": "All Tasks",
|
|
"myTasks": "My Tasks",
|
|
"unassigned": "Unassigned",
|
|
"overdue": "Overdue",
|
|
"dueThisWeek": "Due This Week",
|
|
"highPriority": "High Priority",
|
|
"recentlyUpdated": "Recently Updated"
|
|
},
|
|
"sort": {
|
|
"sortBy": "Sort by",
|
|
"dueDate": "Due Date",
|
|
"priority": "Priority",
|
|
"status": "Status",
|
|
"title": "Title",
|
|
"createdAt": "Created At",
|
|
"updatedAt": "Updated At",
|
|
"ascending": "Ascending",
|
|
"descending": "Descending"
|
|
},
|
|
"actions": {
|
|
"assign": "Assign",
|
|
"reassign": "Reassign",
|
|
"changeStatus": "Change Status",
|
|
"changePriority": "Change Priority",
|
|
"addSubtask": "Add Subtask",
|
|
"addComment": "Add Comment",
|
|
"addAttachment": "Add Attachment",
|
|
"addWatcher": "Add Watcher",
|
|
"removeWatcher": "Remove Watcher",
|
|
"duplicate": "Duplicate Task",
|
|
"archive": "Archive",
|
|
"restore": "Restore",
|
|
"moveToProject": "Move to Project"
|
|
},
|
|
"subtasks": {
|
|
"title": "Subtasks",
|
|
"add": "Add Subtask",
|
|
"placeholder": "Enter subtask title",
|
|
"completed": "{{count}} / {{total}} completed",
|
|
"count": "{{count}} subtask(s)",
|
|
"empty": "No subtasks",
|
|
"adding": "Adding...",
|
|
"error": {
|
|
"load": "Failed to load subtasks",
|
|
"create": "Failed to create subtask"
|
|
}
|
|
},
|
|
"comments": {
|
|
"title": "Comments",
|
|
"add": "Post Comment",
|
|
"placeholder": "Add a comment... Use @name to mention someone",
|
|
"edited": "edited",
|
|
"delete": "Delete Comment",
|
|
"confirmDelete": "Are you sure you want to delete this comment? This action cannot be undone.",
|
|
"empty": "No comments yet",
|
|
"reply": "Reply",
|
|
"mentioned": "Mentioned",
|
|
"replyingTo": "Replying to comment",
|
|
"posting": "Posting...",
|
|
"error": {
|
|
"load": "Failed to load comments",
|
|
"post": "Failed to post comment",
|
|
"update": "Failed to update comment",
|
|
"delete": "Failed to delete comment"
|
|
}
|
|
},
|
|
"attachments": {
|
|
"title": "Attachments",
|
|
"add": "Add Attachment",
|
|
"upload": "Upload File",
|
|
"dragDrop": "Drag and drop files here or click to upload",
|
|
"maxSize": "Max file size: {{size}}MB",
|
|
"downloading": "Downloading...",
|
|
"empty": "No attachments"
|
|
},
|
|
"blockers": {
|
|
"title": "Blockers",
|
|
"add": "Add Blocker",
|
|
"blockedBy": "Blocked by",
|
|
"blocking": "Blocking",
|
|
"remove": "Remove blocker",
|
|
"empty": "No blockers",
|
|
"taskBlocked": "Task Blocked",
|
|
"markAsBlocked": "Mark as Blocked",
|
|
"activeBlocker": "Active Blocker",
|
|
"reportedBy": "Reported by",
|
|
"on": "on",
|
|
"resolutionNote": "Resolution Note",
|
|
"resolutionPlaceholder": "Describe how the blocker was resolved...",
|
|
"resolving": "Resolving...",
|
|
"resolveBlocker": "Resolve Blocker",
|
|
"blockerReason": "Blocker Reason",
|
|
"reasonPlaceholder": "Describe what is blocking this task...",
|
|
"history": "Blocker History",
|
|
"reported": "Reported",
|
|
"resolved": "Resolved",
|
|
"error": {
|
|
"load": "Failed to load blockers",
|
|
"create": "Failed to create blocker",
|
|
"resolve": "Failed to resolve blocker"
|
|
}
|
|
},
|
|
"messages": {
|
|
"created": "Task created",
|
|
"updated": "Task updated",
|
|
"deleted": "Task deleted",
|
|
"statusChanged": "Status changed to \"{{status}}\"",
|
|
"assigned": "Assigned to {{assignee}}",
|
|
"unassigned": "Unassigned",
|
|
"commentAdded": "Comment added",
|
|
"attachmentUploaded": "Attachment uploaded",
|
|
"confirmDelete": "Are you sure you want to delete this task? This action cannot be undone."
|
|
},
|
|
"kanban": {
|
|
"dropHere": "Drop tasks here"
|
|
},
|
|
"calendar": {
|
|
"allAssignees": "All Assignees",
|
|
"allPriorities": "All Priorities",
|
|
"activeOnly": "Active Only",
|
|
"completedOnly": "Completed Only",
|
|
"clearFilters": "Clear Filters",
|
|
"overdue": "Overdue",
|
|
"completed": "Completed"
|
|
},
|
|
"empty": {
|
|
"title": "No Tasks",
|
|
"description": "There are no tasks yet. Create your first task to get started!",
|
|
"filtered": "No tasks match your filters"
|
|
},
|
|
"dependencies": {
|
|
"title": "Task Dependencies",
|
|
"add": "Add Dependency",
|
|
"remove": "Remove Dependency",
|
|
"predecessor": "Predecessor",
|
|
"successor": "Successor",
|
|
"type": "Dependency Type",
|
|
"types": {
|
|
"FS": "Finish-to-Start",
|
|
"SS": "Start-to-Start",
|
|
"FF": "Finish-to-Finish",
|
|
"SF": "Start-to-Finish"
|
|
},
|
|
"circularError": {
|
|
"title": "Circular Dependency Detected",
|
|
"description": "Adding this dependency would create a circular reference, which is not allowed.",
|
|
"cyclePath": "Dependency Cycle",
|
|
"helpText": "To resolve this issue, choose a different task as a dependency, or remove one of the existing dependencies in the cycle."
|
|
},
|
|
"error": {
|
|
"addFailed": "Failed to add dependency",
|
|
"removeFailed": "Failed to remove dependency"
|
|
}
|
|
},
|
|
"conflict": {
|
|
"title": "Update Conflict",
|
|
"message": "This task has been modified by another user. Please refresh to see the latest version and try again."
|
|
}
|
|
}
|