feat: implement 8 OpenSpec proposals for security, reliability, and UX improvements
## 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>
This commit is contained in:
@@ -98,6 +98,43 @@
|
||||
- **THEN** 系統篩選 due_date >= 下週一 且 < 下週日
|
||||
- **AND** 排除已完成狀態的任務
|
||||
|
||||
### Requirement: Formula Field Cycle Prevention
|
||||
The system SHALL detect and prevent circular references in custom field formulas to avoid infinite calculation loops.
|
||||
|
||||
#### Scenario: Formula self-reference rejected
|
||||
- **WHEN** user creates a formula field that references itself
|
||||
- **THEN** system rejects with 400 Bad Request
|
||||
- **THEN** error message indicates self-reference is not allowed
|
||||
|
||||
#### Scenario: Formula circular reference chain rejected
|
||||
- **WHEN** user creates formula where Field A references Field B and Field B references Field A
|
||||
- **THEN** system rejects with 400 Bad Request
|
||||
- **THEN** error message includes the reference cycle path
|
||||
|
||||
#### Scenario: Valid formula references accepted
|
||||
- **WHEN** user creates formula referencing other fields without cycles
|
||||
- **THEN** system saves the formula and calculates values correctly
|
||||
|
||||
### Requirement: Trigger Execution Retry
|
||||
The system SHALL retry failed trigger executions with exponential backoff to handle transient failures.
|
||||
|
||||
#### Scenario: Trigger succeeds after retry
|
||||
- **WHEN** trigger execution fails due to transient error
|
||||
- **THEN** system retries after 1 second delay
|
||||
- **WHEN** retry succeeds
|
||||
- **THEN** trigger is marked as successful in execution log
|
||||
|
||||
#### Scenario: Trigger exhausts retries
|
||||
- **WHEN** trigger execution fails 3 consecutive times
|
||||
- **THEN** system marks trigger execution as permanently failed
|
||||
- **THEN** system sends alert notification to system administrators
|
||||
- **THEN** execution log contains all retry attempts with error details
|
||||
|
||||
#### Scenario: Non-retryable error
|
||||
- **WHEN** trigger fails with validation or permission error (4xx)
|
||||
- **THEN** system does not retry and marks as failed immediately
|
||||
- **THEN** error is logged with appropriate categorization
|
||||
|
||||
## Data Model
|
||||
|
||||
```
|
||||
|
||||
@@ -67,3 +67,97 @@ The backend SHALL provide a single aggregated endpoint for dashboard data.
|
||||
- Project health summary
|
||||
- And: Response is optimized with single database query where possible
|
||||
|
||||
### Requirement: Responsive Layout
|
||||
The system SHALL provide a responsive user interface that adapts to different screen sizes for optimal usability.
|
||||
|
||||
#### Scenario: Mobile sidebar behavior
|
||||
- **WHEN** user accesses application on mobile device (width < 768px)
|
||||
- **THEN** sidebar is hidden by default
|
||||
- **THEN** hamburger menu button is visible in header
|
||||
- **WHEN** user taps hamburger menu
|
||||
- **THEN** sidebar slides in from left with backdrop overlay
|
||||
|
||||
#### Scenario: Table responsive behavior
|
||||
- **WHEN** user views task list on small screen
|
||||
- **THEN** table displays with horizontal scroll or switches to card layout
|
||||
- **THEN** all essential information remains accessible
|
||||
|
||||
#### Scenario: Touch-friendly interactions
|
||||
- **WHEN** user interacts with application on touch device
|
||||
- **THEN** all interactive elements have minimum 44x44 pixel tap targets
|
||||
- **THEN** sufficient spacing prevents accidental taps
|
||||
|
||||
### Requirement: Complete Internationalization
|
||||
The system SHALL support complete internationalization with no hardcoded text strings.
|
||||
|
||||
#### Scenario: Language switching
|
||||
- **WHEN** user changes language preference
|
||||
- **THEN** all UI text updates to selected language
|
||||
- **THEN** no untranslated strings remain visible
|
||||
|
||||
#### Scenario: Date and time localization
|
||||
- **WHEN** dates and times are displayed
|
||||
- **THEN** format follows user's locale preference
|
||||
- **THEN** relative times (e.g., "2 hours ago") are properly translated
|
||||
|
||||
#### Scenario: New component text
|
||||
- **WHEN** new UI components are added
|
||||
- **THEN** all text strings use i18n translation keys
|
||||
- **THEN** translations exist for all supported locales
|
||||
|
||||
### Requirement: Standardized API Response Format
|
||||
The system SHALL return all API responses in a consistent standardized format.
|
||||
|
||||
#### Scenario: Successful API response
|
||||
- **WHEN** API request succeeds
|
||||
- **THEN** response includes success=true
|
||||
- **THEN** response includes data field with result
|
||||
- **THEN** response includes timestamp field
|
||||
|
||||
#### Scenario: Error API response
|
||||
- **WHEN** API request fails
|
||||
- **THEN** response includes success=false
|
||||
- **THEN** response includes error_code field
|
||||
- **THEN** response includes message field with description
|
||||
|
||||
### Requirement: API Versioning
|
||||
The system SHALL support API versioning to enable backwards compatibility during upgrades.
|
||||
|
||||
#### Scenario: Versioned API endpoint
|
||||
- **WHEN** client calls /api/v1/tasks
|
||||
- **THEN** system routes to current version implementation
|
||||
- **THEN** response works with v1 client expectations
|
||||
|
||||
#### Scenario: Legacy API route
|
||||
- **WHEN** client calls /api/tasks (unversioned)
|
||||
- **THEN** system routes to default version
|
||||
- **THEN** response includes deprecation warning header
|
||||
|
||||
### Requirement: Comprehensive Health Check
|
||||
The system SHALL provide detailed health check endpoints for monitoring.
|
||||
|
||||
#### Scenario: All systems healthy
|
||||
- **WHEN** health check is called and all dependencies are available
|
||||
- **THEN** response includes status=healthy
|
||||
- **THEN** response includes checks object with database=ok, redis=ok
|
||||
|
||||
#### Scenario: Partial system failure
|
||||
- **WHEN** health check is called and Redis is unavailable
|
||||
- **THEN** response includes status=degraded
|
||||
- **THEN** response includes checks object with database=ok, redis=error
|
||||
|
||||
### Requirement: Project Templates
|
||||
The system SHALL support project templates to standardize project creation.
|
||||
|
||||
#### Scenario: Create project from template
|
||||
- **WHEN** user creates project selecting a template
|
||||
- **THEN** system copies TaskStatus definitions from template
|
||||
- **THEN** system copies CustomField definitions from template
|
||||
- **THEN** project is created with predefined structure
|
||||
|
||||
#### Scenario: Save project as template
|
||||
- **WHEN** user saves existing project as template
|
||||
- **THEN** system creates template with project's TaskStatus definitions
|
||||
- **THEN** system creates template with project's CustomField definitions
|
||||
- **THEN** template is available for future project creation
|
||||
|
||||
|
||||
@@ -148,6 +148,51 @@
|
||||
- **THEN** 顯示完整操作歷史
|
||||
- **AND** 支援依時間、操作者、檔案篩選
|
||||
|
||||
### Requirement: Storage Path Validation
|
||||
The system SHALL validate file storage configuration on startup to ensure reliability.
|
||||
|
||||
#### Scenario: Valid NAS storage path
|
||||
- **WHEN** application starts with valid UPLOAD_DIR configuration
|
||||
- **THEN** system verifies path exists and is writable
|
||||
- **THEN** system logs confirmation of storage configuration
|
||||
|
||||
#### Scenario: Invalid storage path
|
||||
- **WHEN** application starts with invalid or inaccessible UPLOAD_DIR
|
||||
- **THEN** system logs error with specific issue (not found, not writable)
|
||||
- **THEN** system falls back to local storage with warning
|
||||
|
||||
#### Scenario: Storage health check
|
||||
- **WHEN** health check endpoint is called
|
||||
- **THEN** response includes storage availability status
|
||||
- **THEN** response includes available disk space if accessible
|
||||
|
||||
### Requirement: Notification Delivery Reliability
|
||||
The system SHALL ensure notification delivery even during temporary Redis failures.
|
||||
|
||||
#### Scenario: Redis temporarily unavailable
|
||||
- **WHEN** Redis publish fails due to connection error
|
||||
- **THEN** system queues message in local memory
|
||||
- **WHEN** Redis connection recovers
|
||||
- **THEN** system retries queued messages
|
||||
|
||||
#### Scenario: Queue overflow prevention
|
||||
- **WHEN** local message queue exceeds maximum size
|
||||
- **THEN** oldest messages are dropped
|
||||
- **THEN** system logs warning about dropped messages
|
||||
|
||||
### Requirement: Task Deletion Safety
|
||||
The system SHALL warn users when deleting tasks with unresolved blockers.
|
||||
|
||||
#### Scenario: Delete task with active blockers
|
||||
- **WHEN** user attempts to delete task with unresolved blockers
|
||||
- **THEN** system returns warning with blocker count
|
||||
- **THEN** user must confirm or use force_delete flag
|
||||
|
||||
#### Scenario: Force delete with blockers
|
||||
- **WHEN** user force deletes task with blockers
|
||||
- **THEN** system auto-resolves all blockers with "task deleted" reason
|
||||
- **THEN** system proceeds with task deletion
|
||||
|
||||
## Data Model
|
||||
|
||||
```
|
||||
|
||||
@@ -148,6 +148,36 @@ The system SHALL provide a visual workload heatmap interface for managers.
|
||||
- **WHEN** user selects a department from the filter
|
||||
- **THEN** the heatmap shows only users from that department
|
||||
|
||||
### Requirement: Manager Workload Visibility
|
||||
The system SHALL allow department managers to view workload data for all members within their department.
|
||||
|
||||
#### Scenario: Manager views department member workload
|
||||
- **WHEN** a department manager requests workload data for a user in their department
|
||||
- **THEN** system returns the workload data for that user
|
||||
|
||||
#### Scenario: Manager denied access to other department workload
|
||||
- **WHEN** a department manager requests workload data for a user in a different department
|
||||
- **THEN** system returns 403 Forbidden error
|
||||
|
||||
#### Scenario: Regular user cannot view others' workload
|
||||
- **WHEN** a non-manager user requests workload data for another user
|
||||
- **THEN** system returns 403 Forbidden error
|
||||
|
||||
### Requirement: Cross-Department Project Membership
|
||||
The system SHALL support explicit project membership to enable cross-department collaboration.
|
||||
|
||||
#### Scenario: Add cross-department member to project
|
||||
- **WHEN** project owner adds a user from another department as project member
|
||||
- **THEN** user gains access to the project regardless of department
|
||||
|
||||
#### Scenario: Project member accesses cross-department project
|
||||
- **WHEN** a project member from another department accesses project resources
|
||||
- **THEN** system grants access based on project membership
|
||||
|
||||
#### Scenario: Non-member denied access despite same department
|
||||
- **WHEN** a user not in project membership list attempts to access confidential project
|
||||
- **THEN** system denies access unless user is in the project's department
|
||||
|
||||
## Data Model
|
||||
|
||||
```
|
||||
|
||||
@@ -277,6 +277,53 @@ The system SHALL allow assigning tasks to users during creation and editing.
|
||||
- resource_id: 被刪除的專案 ID
|
||||
- changes: [{ field: "is_active", old_value: true, new_value: false }]
|
||||
|
||||
### Requirement: Task Dependency Cycle Prevention
|
||||
The system SHALL detect and prevent circular dependencies between tasks to ensure Gantt charts can be properly rendered.
|
||||
|
||||
#### Scenario: Direct circular dependency rejected
|
||||
- **WHEN** user attempts to create dependency where Task A depends on Task B and Task B depends on Task A
|
||||
- **THEN** system rejects the operation with 400 Bad Request
|
||||
- **THEN** error message includes the cycle path (e.g., "Circular dependency detected: A -> B -> A")
|
||||
|
||||
#### Scenario: Indirect circular dependency rejected
|
||||
- **WHEN** user attempts to create dependency that would form a cycle (A -> B -> C -> A)
|
||||
- **THEN** system rejects the operation with 400 Bad Request
|
||||
- **THEN** error message includes the full cycle path
|
||||
|
||||
#### Scenario: Valid dependency chain accepted
|
||||
- **WHEN** user creates dependencies forming a valid DAG (directed acyclic graph)
|
||||
- **THEN** system accepts and saves the dependencies
|
||||
- **THEN** Gantt chart renders correctly with proper task ordering
|
||||
|
||||
### Requirement: Optimistic Locking for Task Updates
|
||||
The system SHALL use optimistic locking to prevent concurrent update conflicts on tasks.
|
||||
|
||||
#### Scenario: Concurrent update detected
|
||||
- **WHEN** user A and user B both load task at version 1
|
||||
- **WHEN** user A saves changes, incrementing version to 2
|
||||
- **WHEN** user B attempts to save with version 1
|
||||
- **THEN** system returns 409 Conflict error
|
||||
- **THEN** error message instructs user to refresh and retry
|
||||
|
||||
#### Scenario: Sequential updates succeed
|
||||
- **WHEN** user loads task at version N
|
||||
- **WHEN** user saves changes with correct version N
|
||||
- **THEN** system accepts update and increments version to N+1
|
||||
|
||||
### Requirement: Soft Delete Cascade Restore
|
||||
The system SHALL restore child tasks when parent task is restored from soft delete.
|
||||
|
||||
#### Scenario: Parent task restored with children
|
||||
- **WHEN** soft-deleted parent task is restored
|
||||
- **THEN** system identifies child tasks deleted at same timestamp
|
||||
- **THEN** system recursively restores all matching child tasks
|
||||
- **THEN** audit log records restoration of parent and children
|
||||
|
||||
#### Scenario: Selective restore without children
|
||||
- **WHEN** user explicitly requests restore without cascade
|
||||
- **THEN** only parent task is restored
|
||||
- **THEN** child tasks remain in deleted state
|
||||
|
||||
## Data Model
|
||||
|
||||
```
|
||||
|
||||
@@ -108,6 +108,66 @@ The system SHALL implement rate limiting to protect against brute force attacks
|
||||
- **WHEN** different IPs make requests
|
||||
- **THEN** each IP has its own rate limit counter
|
||||
|
||||
### Requirement: Comprehensive API Rate Limiting
|
||||
The system SHALL enforce rate limits on all sensitive API endpoints to prevent abuse and ensure service availability.
|
||||
|
||||
#### Scenario: Task creation rate limit exceeded
|
||||
- **WHEN** user exceeds 60 task creation requests per minute
|
||||
- **THEN** system returns 429 Too Many Requests
|
||||
- **THEN** response includes Retry-After header
|
||||
|
||||
#### Scenario: Report generation rate limit exceeded
|
||||
- **WHEN** user exceeds 5 report generation requests per minute
|
||||
- **THEN** system returns 429 Too Many Requests
|
||||
- **THEN** response includes rate limit headers
|
||||
|
||||
#### Scenario: Rate limit headers provided
|
||||
- **WHEN** user makes any rate-limited API request
|
||||
- **THEN** response includes X-RateLimit-Limit header
|
||||
- **THEN** response includes X-RateLimit-Remaining header
|
||||
- **THEN** response includes X-RateLimit-Reset header
|
||||
|
||||
#### Scenario: Rate limit window reset
|
||||
- **WHEN** rate limit window expires
|
||||
- **THEN** user can make requests again up to the limit
|
||||
- **THEN** X-RateLimit-Remaining resets to maximum
|
||||
|
||||
### Requirement: Input Length Validation
|
||||
The system SHALL enforce maximum length limits on all user-provided string inputs to prevent DoS attacks and database overflow.
|
||||
|
||||
#### Scenario: Task title exceeds maximum length
|
||||
- **WHEN** user submits a task with title longer than 500 characters
|
||||
- **THEN** system returns 422 Validation Error with descriptive message
|
||||
|
||||
#### Scenario: Description field within limits
|
||||
- **WHEN** user submits content with description under 10000 characters
|
||||
- **THEN** system accepts the input and processes normally
|
||||
|
||||
### Requirement: Secure WebSocket Authentication
|
||||
The system SHALL authenticate WebSocket connections without exposing tokens in URL query parameters.
|
||||
|
||||
#### Scenario: WebSocket connection with token in first message
|
||||
- **WHEN** client connects to WebSocket endpoint
|
||||
- **THEN** server waits for authentication message containing JWT token
|
||||
- **THEN** server validates token before accepting further messages
|
||||
|
||||
#### Scenario: WebSocket connection timeout without authentication
|
||||
- **WHEN** client connects but does not send authentication within 10 seconds
|
||||
- **THEN** server closes the connection with appropriate error code
|
||||
|
||||
### Requirement: Path Traversal Protection
|
||||
The system SHALL prevent file path traversal attacks by validating all file paths resolve within the designated storage directory.
|
||||
|
||||
#### Scenario: Path traversal attempt detected
|
||||
- **WHEN** request contains file path with "../" or absolute path outside storage
|
||||
- **THEN** system rejects request and logs security warning
|
||||
- **THEN** system returns 403 Forbidden error
|
||||
|
||||
#### Scenario: Valid file path within storage
|
||||
- **WHEN** request contains valid relative file path
|
||||
- **THEN** system resolves path and verifies it is within storage directory
|
||||
- **THEN** system processes file operation normally
|
||||
|
||||
## Data Model
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user