chore: archive remaining OpenSpec proposals

Archived proposals:
- add-trigger-conditions-weekly-subscription: Trigger conditions and weekly subscription
- update-api-consistency: WebSocket auth, optimistic locking, workload defaults

All implementations were already complete in previous commits (f5f870d).
Updated tasks.md with implementation summary.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beabigegg
2026-01-11 18:47:14 +08:00
parent 679b89ae4c
commit df50d5e7f8
15 changed files with 98 additions and 12 deletions

View File

@@ -0,0 +1,30 @@
## Context
The current API behavior is functionally correct but has ambiguities that cause client confusion: WebSocket handshake messaging differs from inline docs, 409 conflict responses are inconsistent for clients, and workload heatmap defaults vary based on calendar edge cases (Sunday).
## Goals / Non-Goals
- Goals:
- Make WebSocket auth expectations explicit and consistent.
- Provide a stable, machine-readable conflict response for optimistic locking.
- Define predictable workload heatmap defaults and edge-case handling.
- Non-Goals:
- Full API version migration (/api to /api/v1).
- Redesign of workload UI or heatmap visualization.
## Decisions
- WebSocket auth handshake: keep first-message authentication; do not require a pre-auth banner. Add explicit invalid-token error message prior to close.
- Optimistic locking: return a standardized 409 payload containing a human-readable message plus current/provided version fields.
- Workload defaults: show all accessible users by default (including zero workload); support `hide_empty=true` to exclude them. When `week_start` is omitted and today is Sunday, extend the default week window to include the upcoming week to avoid empty default views.
- Caching: include `hide_empty` in cache key and cache the default path to keep latency stable.
## Risks / Trade-offs
- Returning more users by default may increase response sizes; cache should offset this.
- Sunday window extension changes semantics of "current week"; clients must understand the rule.
- Conflict payload change may require frontend updates if it expects a string-only detail.
## Migration Plan
- Update specs first, then implement backend changes.
- Update frontend only if new defaults or conflict payloads require parsing changes.
- Add regression tests for WebSocket auth invalid token, conflict payload shape, and heatmap defaults.
## Open Questions
- Should we add an explicit `auth_required` message before waiting for the auth payload (client UX improvement), or keep the minimal handshake?

View File

@@ -0,0 +1,14 @@
# Change: Update API Consistency for WebSocket Auth, Workload Defaults, and Task Locking
## Why
Several API behaviors are currently ambiguous or inconsistent (WebSocket auth handshake messaging, optimistic locking conflict payloads, and workload heatmap defaults). These gaps can confuse clients and reduce product completeness.
## What Changes
- Clarify WebSocket authentication error handling and client expectations.
- Standardize optimistic locking conflict responses for task updates.
- Define workload heatmap default inclusion rules and Sunday week-window behavior.
- Align workload heatmap `hide_empty` defaults and caching behavior.
## Impact
- Affected specs: user-auth, task-management, resource-management
- Affected code: backend WebSocket router, task update endpoint, workload service/router, workload cache; frontend workload views may require adjustments depending on default behavior.

View File

@@ -0,0 +1,35 @@
## MODIFIED Requirements
### Requirement: Workload Heatmap UI
The system SHALL provide a visual workload heatmap interface for managers.
#### Scenario: View workload heatmap
- **GIVEN** user is logged in as manager or admin
- **WHEN** user navigates to /workload page without filters
- **THEN** system displays a heatmap showing all accessible users' workload
- **AND** users with zero workload are included by default
- **AND** each user cell is color-coded by load level (green/yellow/red)
#### Scenario: Hide empty workloads
- **GIVEN** user is viewing the workload page
- **WHEN** user enables the hide_empty filter
- **THEN** the heatmap excludes users with zero workload
#### Scenario: Navigate between weeks
- **GIVEN** user is viewing the workload page
- **WHEN** user clicks previous/next week buttons
- **THEN** the heatmap updates to show that week's workload data
#### Scenario: Default week window on Sunday
- **GIVEN** today is Sunday and user opens workload page without selecting week_start
- **THEN** the default heatmap window includes tasks due in the upcoming week
#### Scenario: View user workload details
- **GIVEN** user is viewing the workload heatmap
- **WHEN** user clicks on a specific user's cell
- **THEN** a modal/drawer opens showing that user's task breakdown
- **AND** tasks show title, project, time estimate, and due date
#### Scenario: Filter by department
- **GIVEN** user is a system admin
- **WHEN** user selects a department from the filter
- **THEN** the heatmap shows only users from that department

View File

@@ -0,0 +1,16 @@
## MODIFIED Requirements
### 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
- **AND** response includes a human-readable message instructing refresh and retry
- **AND** response includes the current and provided version numbers
#### 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

View File

@@ -0,0 +1,18 @@
## MODIFIED Requirements
### 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 without a query token
- **THEN** server waits for authentication message containing JWT token
- **THEN** server validates token before accepting further messages
- **THEN** server sends an authentication acknowledgment message
#### Scenario: WebSocket connection with invalid token
- **WHEN** client sends an invalid or expired token
- **THEN** server sends an error message indicating invalid or expired token
- **THEN** server closes the connection with an authentication error code
#### 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

View File

@@ -0,0 +1,34 @@
## 1. Implementation
- [x] 1.1 Update WebSocket auth spec and align server handshake/error messaging with the agreed behavior
- [x] 1.2 Update optimistic locking conflict response spec and implement standardized payload
- [x] 1.3 Update workload heatmap defaults (hide_empty, week window) and cache behavior
- [x] 1.4 Update frontend workload views and API handling if required by new defaults
- [x] 1.5 Add/adjust tests for WebSocket auth, conflict responses, and workload heatmap defaults
---
## Implementation Summary
### Changes Made (commit f5f870d)
1. **WebSocket Auth** (`backend/app/api/websocket/router.py`)
- Standardized error codes: 4001 (invalid token), 4003 (access denied), 4004 (not found)
- Clear error reasons in WebSocket close messages
2. **Optimistic Locking** (`backend/app/api/tasks/router.py`)
- 409 Conflict response with standardized payload:
- `error: "conflict"`
- `message`, `current_version`, `provided_version`, `your_version`
3. **Workload Heatmap** (`backend/app/api/workload/router.py`, `workload_service.py`)
- `hide_empty=True` as default
- Caching only when `hide_empty=True`
- Week bounds handle Sunday correctly (returns previous Monday)
4. **Frontend** (already aligned)
- `workload.ts`: `hideEmpty: boolean = true` default
- TaskDetailModal, GanttChart, CalendarView: Handle 409 conflict with conflict banner UI
5. **Tests** (`backend/tests/test_workload.py`)
- Week bounds tests including Sunday handling
- Load level calculation tests