feat: Initial commit - Task Reporter incident response system
Complete implementation of the production line incident response system (生產線異常即時反應系統) including: Backend (FastAPI): - User authentication with AD integration and session management - Chat room management (create, list, update, members, roles) - Real-time messaging via WebSocket (typing indicators, reactions) - File storage with MinIO (upload, download, image preview) Frontend (React + Vite): - Authentication flow with token management - Room list with filtering, search, and pagination - Real-time chat interface with WebSocket - File upload with drag-and-drop and image preview - Member management and room settings - Breadcrumb navigation - 53 unit tests (Vitest) Specifications: - authentication: AD auth, sessions, JWT tokens - chat-room: rooms, members, templates - realtime-messaging: WebSocket, messages, reactions - file-storage: MinIO integration, file management - frontend-core: React SPA structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
272
openspec/specs/frontend-core/spec.md
Normal file
272
openspec/specs/frontend-core/spec.md
Normal file
@@ -0,0 +1,272 @@
|
||||
# frontend-core Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-react-frontend. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: User Authentication Interface
|
||||
The frontend SHALL provide a login interface that authenticates users against the backend API and maintains session state.
|
||||
|
||||
#### Scenario: Successful login
|
||||
- **WHEN** a user enters valid AD credentials and submits the login form
|
||||
- **THEN** the system SHALL:
|
||||
- Send POST request to `/api/auth/login`
|
||||
- Store the returned token in localStorage
|
||||
- Redirect user to the room list page
|
||||
- Display the user's display name in the navigation
|
||||
|
||||
#### Scenario: Failed login with invalid credentials
|
||||
- **WHEN** a user enters invalid credentials
|
||||
- **THEN** the system SHALL:
|
||||
- Display error message "Invalid credentials"
|
||||
- Keep user on login page
|
||||
- Clear the password field
|
||||
|
||||
#### Scenario: Session persistence across page refresh
|
||||
- **WHEN** a user refreshes the page while logged in
|
||||
- **THEN** the system SHALL:
|
||||
- Retrieve token from localStorage
|
||||
- Validate session is still active
|
||||
- Restore user session without requiring re-login
|
||||
|
||||
#### Scenario: Logout
|
||||
- **WHEN** a logged-in user clicks the logout button
|
||||
- **THEN** the system SHALL:
|
||||
- Send POST request to `/api/auth/logout`
|
||||
- Clear token from localStorage
|
||||
- Redirect to login page
|
||||
|
||||
### Requirement: Incident Room List
|
||||
The frontend SHALL display a filterable, searchable list of incident rooms accessible to the current user.
|
||||
|
||||
#### Scenario: Display room list
|
||||
- **WHEN** a logged-in user navigates to the room list page
|
||||
- **THEN** the system SHALL:
|
||||
- Fetch rooms from `GET /api/rooms`
|
||||
- Display rooms as cards with title, status, severity, and timestamp
|
||||
- Show the user's role in each room
|
||||
- Order by last activity (most recent first)
|
||||
|
||||
#### Scenario: Filter rooms by status
|
||||
- **WHEN** a user selects a status filter (Active, Resolved, Archived)
|
||||
- **THEN** the system SHALL:
|
||||
- Update the room list to show only rooms matching the filter
|
||||
- Preserve other active filters
|
||||
|
||||
#### Scenario: Search rooms
|
||||
- **WHEN** a user enters text in the search box
|
||||
- **THEN** the system SHALL:
|
||||
- Filter rooms by title and description containing the search text
|
||||
- Update results in real-time (debounced)
|
||||
|
||||
#### Scenario: Create new room
|
||||
- **WHEN** a user clicks "New Room" and fills the creation form
|
||||
- **THEN** the system SHALL:
|
||||
- Display template selection if templates exist
|
||||
- Submit room creation to `POST /api/rooms`
|
||||
- Navigate to the new room on success
|
||||
- Show error message on failure
|
||||
|
||||
### Requirement: Incident Room Detail View
|
||||
The frontend SHALL display complete incident room information including metadata, members, and provide management controls for authorized users.
|
||||
|
||||
#### Scenario: View room details
|
||||
- **WHEN** a user navigates to a room detail page
|
||||
- **THEN** the system SHALL:
|
||||
- Fetch room details from `GET /api/rooms/{room_id}`
|
||||
- Display room title, status, severity, location, description
|
||||
- Show member list with roles
|
||||
- Display created timestamp and last activity
|
||||
|
||||
#### Scenario: Update room metadata (Owner/Editor)
|
||||
- **WHEN** an owner or editor updates room fields (title, severity, description)
|
||||
- **THEN** the system SHALL:
|
||||
- Submit changes to `PATCH /api/rooms/{room_id}`
|
||||
- Update the UI optimistically
|
||||
- Revert on failure with error message
|
||||
|
||||
#### Scenario: Change room status (Owner only)
|
||||
- **WHEN** a room owner changes status to Resolved or Archived
|
||||
- **THEN** the system SHALL:
|
||||
- Prompt for confirmation
|
||||
- Submit status change to backend
|
||||
- Update room header to reflect new status
|
||||
- Broadcast status change to connected members
|
||||
|
||||
#### Scenario: View room with insufficient permissions
|
||||
- **WHEN** a user tries to access a room they are not a member of
|
||||
- **THEN** the system SHALL:
|
||||
- Display "Access Denied" message
|
||||
- Provide option to request access or return to room list
|
||||
|
||||
### Requirement: Real-time Chat Interface
|
||||
The frontend SHALL provide a real-time chat interface using WebSocket connections for instant message delivery.
|
||||
|
||||
#### Scenario: Connect to room chat
|
||||
- **WHEN** a user opens a room detail page
|
||||
- **THEN** the system SHALL:
|
||||
- Establish WebSocket connection to `/api/ws/{room_id}?token={token}`
|
||||
- Load message history from REST API
|
||||
- Display connection status indicator
|
||||
- Subscribe to real-time message updates
|
||||
|
||||
#### Scenario: Send text message
|
||||
- **WHEN** a user types a message and presses Enter or clicks Send
|
||||
- **THEN** the system SHALL:
|
||||
- Send message via WebSocket
|
||||
- Display message immediately (optimistic update)
|
||||
- Show delivery confirmation when acknowledged
|
||||
- Show error indicator if delivery fails
|
||||
|
||||
#### Scenario: Receive message from other user
|
||||
- **WHEN** another user sends a message to the room
|
||||
- **THEN** the system SHALL:
|
||||
- Display the new message in the chat
|
||||
- Scroll to the new message if user is at bottom
|
||||
- Show notification badge if user has scrolled up
|
||||
|
||||
#### Scenario: Display typing indicator
|
||||
- **WHEN** another user is typing
|
||||
- **THEN** the system SHALL:
|
||||
- Show "{username} is typing..." indicator
|
||||
- Hide indicator after 3 seconds of inactivity
|
||||
|
||||
#### Scenario: Edit own message
|
||||
- **WHEN** a user edits their own message within edit window
|
||||
- **THEN** the system SHALL:
|
||||
- Display edit input pre-filled with original content
|
||||
- Submit edit via WebSocket
|
||||
- Update message with "edited" indicator
|
||||
|
||||
#### Scenario: Delete own message
|
||||
- **WHEN** a user deletes their own message
|
||||
- **THEN** the system SHALL:
|
||||
- Prompt for confirmation
|
||||
- Submit delete via WebSocket
|
||||
- Remove or mark message as deleted in UI
|
||||
|
||||
#### Scenario: WebSocket reconnection
|
||||
- **WHEN** WebSocket connection is lost
|
||||
- **THEN** the system SHALL:
|
||||
- Display "Reconnecting..." indicator
|
||||
- Attempt reconnection with exponential backoff
|
||||
- Restore connection and sync missed messages
|
||||
- Show error after max retry attempts
|
||||
|
||||
### Requirement: File Upload and Management Interface
|
||||
The frontend SHALL provide file upload capabilities with progress indication, preview for images, and file management controls.
|
||||
|
||||
#### Scenario: Upload file via button
|
||||
- **WHEN** a user clicks the upload button and selects a file
|
||||
- **THEN** the system SHALL:
|
||||
- Validate file type and size client-side
|
||||
- Display upload progress bar
|
||||
- Upload to `POST /api/rooms/{room_id}/files`
|
||||
- Show file in chat/file list on success
|
||||
- Display error message on failure
|
||||
|
||||
#### Scenario: Upload file via drag and drop
|
||||
- **WHEN** a user drags a file into the chat area
|
||||
- **THEN** the system SHALL:
|
||||
- Show drop zone indicator
|
||||
- Accept the file on drop
|
||||
- Proceed with upload as button upload
|
||||
|
||||
#### Scenario: Preview image file
|
||||
- **WHEN** a user clicks on an uploaded image
|
||||
- **THEN** the system SHALL:
|
||||
- Open image in a modal preview
|
||||
- Allow zoom and pan
|
||||
- Provide download button
|
||||
|
||||
#### Scenario: Download file
|
||||
- **WHEN** a user clicks download on a file
|
||||
- **THEN** the system SHALL:
|
||||
- Fetch presigned URL from `GET /api/rooms/{room_id}/files/{file_id}`
|
||||
- Trigger browser download with original filename
|
||||
|
||||
#### Scenario: Delete file (uploader or owner)
|
||||
- **WHEN** file uploader or room owner clicks delete on a file
|
||||
- **THEN** the system SHALL:
|
||||
- Prompt for confirmation
|
||||
- Submit delete to `DELETE /api/rooms/{room_id}/files/{file_id}`
|
||||
- Remove file from UI
|
||||
|
||||
#### Scenario: View file list
|
||||
- **WHEN** a user opens the files panel in a room
|
||||
- **THEN** the system SHALL:
|
||||
- Fetch files from `GET /api/rooms/{room_id}/files`
|
||||
- Display files with thumbnails for images
|
||||
- Show filename, size, uploader, and timestamp
|
||||
- Support filtering by file type
|
||||
|
||||
### Requirement: Member Management Interface
|
||||
The frontend SHALL provide member management controls for room owners and editors with appropriate role-based access.
|
||||
|
||||
#### Scenario: View member list
|
||||
- **WHEN** a user views a room
|
||||
- **THEN** the system SHALL:
|
||||
- Display all active members
|
||||
- Show each member's role (Owner, Editor, Viewer)
|
||||
- Indicate online status for connected members
|
||||
|
||||
#### Scenario: Add member (Owner/Editor)
|
||||
- **WHEN** an owner or editor adds a new member
|
||||
- **THEN** the system SHALL:
|
||||
- Display member search/input field
|
||||
- Allow role selection
|
||||
- Submit to `POST /api/rooms/{room_id}/members`
|
||||
- Update member list on success
|
||||
|
||||
#### Scenario: Change member role (Owner only)
|
||||
- **WHEN** an owner changes another member's role
|
||||
- **THEN** the system SHALL:
|
||||
- Display role selector
|
||||
- Submit to `PATCH /api/rooms/{room_id}/members/{user_id}`
|
||||
- Update member display on success
|
||||
|
||||
#### Scenario: Remove member (Owner/Editor)
|
||||
- **WHEN** an owner or editor removes a member
|
||||
- **THEN** the system SHALL:
|
||||
- Prompt for confirmation
|
||||
- Submit to `DELETE /api/rooms/{room_id}/members/{user_id}`
|
||||
- Remove member from list
|
||||
|
||||
#### Scenario: Transfer ownership (Owner only)
|
||||
- **WHEN** a room owner transfers ownership to another member
|
||||
- **THEN** the system SHALL:
|
||||
- Prompt for confirmation with warning
|
||||
- Submit to `POST /api/rooms/{room_id}/transfer-ownership`
|
||||
- Update roles in UI (current owner becomes Editor)
|
||||
|
||||
### Requirement: Responsive Layout and Navigation
|
||||
The frontend SHALL provide a responsive layout that works on desktop and tablet devices with intuitive navigation.
|
||||
|
||||
#### Scenario: Desktop layout
|
||||
- **WHEN** viewed on desktop (>1024px)
|
||||
- **THEN** the system SHALL:
|
||||
- Display sidebar navigation
|
||||
- Show room list and detail side-by-side when applicable
|
||||
- Display member panel as sidebar
|
||||
|
||||
#### Scenario: Tablet layout
|
||||
- **WHEN** viewed on tablet (768px-1024px)
|
||||
- **THEN** the system SHALL:
|
||||
- Collapse sidebar to icons or hamburger menu
|
||||
- Use full width for content areas
|
||||
- Stack panels vertically
|
||||
|
||||
#### Scenario: Navigation between pages
|
||||
- **WHEN** a user navigates using browser back/forward
|
||||
- **THEN** the system SHALL:
|
||||
- Maintain correct route state
|
||||
- Preserve scroll position where applicable
|
||||
- Not lose unsent message drafts
|
||||
|
||||
#### Scenario: Error handling
|
||||
- **WHEN** an API request fails
|
||||
- **THEN** the system SHALL:
|
||||
- Display user-friendly error message
|
||||
- Provide retry option where applicable
|
||||
- Log error details for debugging
|
||||
- Not crash or show blank screen
|
||||
|
||||
Reference in New Issue
Block a user