Phase 2.1: Database schema + credentials storage Added migration 011 with: - credentials table: Encrypted OAuth tokens per service - integration_config table: Base URLs, project names, space keys Added models: - Credential: Stores token hash and encrypted token - IntegrationConfig: Stores service configuration TDD tests (7 passing): - Table creation verification - Column structure validation - Insert/retrieve operations - Service uniqueness constraints - Migration tracking - Idempotency checks All tests pass. Schema ready for OAuth2 implementation.
6.7 KiB
Ticket Summary - AI Disclaimer Modal
Description
Added a mandatory AI disclaimer warning that users must accept before creating new issues. This ensures users understand the risks and limitations of AI-assisted triage and accept responsibility for any actions taken based on AI recommendations.
Acceptance Criteria
- Disclaimer appears automatically on first visit to New Issue page
- Modal blocks interaction with page until user accepts or cancels
- Acceptance is persisted across sessions
- Clear, professional warning about AI limitations
- Covers key risks: mistakes, hallucinations, incorrect commands
- Emphasizes user responsibility and accountability
- Includes best practices for safe AI usage
- Cancel button returns user to dashboard
- Modal re-appears if user tries to create issue without accepting
Work Implemented
Frontend Changes
File: src/pages/NewIssue/index.tsx
-
Modal Component:
- Full-screen overlay with backdrop
- Centered modal dialog (max-width 2xl)
- Scrollable content area for long disclaimer text
- Professional styling with proper contrast
-
Disclaimer Content:
- Header: "AI-Assisted Triage Disclaimer"
- Warning Section (red background):
- AI can provide incorrect, incomplete, or outdated information
- AI can hallucinate false information
- Recommendations may not apply to specific environments
- Commands may have unintended consequences (data loss, downtime, security issues)
- Responsibility Section (yellow background):
- User is solely responsible for all actions taken
- Must verify AI suggestions against documentation
- Must test in non-production first
- Must understand commands before executing
- Must have backups and rollback plans
- Best Practices:
- Treat AI as starting point, not definitive answer
- Consult senior engineers for critical systems
- Review AI content for accuracy
- Maintain change control processes
- Document decisions
- Legal acknowledgment
-
State Management:
showDisclaimerstate controls modal visibilityuseEffecthook checks localStorage on page load- Acceptance stored as
tftsr-ai-disclaimer-acceptedin localStorage - Persists across sessions and app restarts
-
User Flow:
- User visits New Issue → Modal appears
- User clicks "I Understand and Accept" → Modal closes, localStorage updated
- User clicks "Cancel" → Navigates back to dashboard
- User tries to create issue without accepting → Modal re-appears
- After acceptance, modal never shows again (unless localStorage cleared)
Technical Details
Storage: localStorage.getItem("tftsr-ai-disclaimer-accepted")
- Key:
tftsr-ai-disclaimer-accepted - Value:
"true"when accepted - Scope: Per-browser, persists across sessions
Validation Points:
- Page load - Shows modal if not accepted
- "Start Triage" button click - Re-checks acceptance before proceeding
Styling:
- Dark overlay:
bg-black/50 - Modal:
bg-backgroundwith border and shadow - Red warning box:
bg-destructive/10 border-destructive/20 - Yellow responsibility box:
bg-yellow-500/10 border-yellow-500/20 - Scrollable content:
max-h-[60vh] overflow-y-auto
Testing Needed
Manual Testing
-
First Visit Flow:
- Navigate to New Issue page
- Verify modal appears automatically
- Verify page content is blocked/dimmed
- Verify modal is scrollable
- Verify all sections are visible and readable
-
Acceptance Flow:
- Click "I Understand and Accept"
- Verify modal closes
- Verify can now create issues
- Refresh page
- Verify modal does NOT re-appear
-
Cancel Flow:
- Clear localStorage:
localStorage.removeItem("tftsr-ai-disclaimer-accepted") - Go to New Issue page
- Click "Cancel" button
- Verify redirected to dashboard
- Go back to New Issue page
- Verify modal appears again
- Clear localStorage:
-
Rejection Flow:
- Clear localStorage
- Go to New Issue page
- Close modal without accepting (if possible)
- Fill in issue details
- Click "Start Triage"
- Verify modal re-appears before issue creation
-
Visual Testing:
- Test in light theme - verify text contrast
- Test in dark theme - verify text contrast
- Test on mobile viewport - verify modal fits
- Test with very long issue title - verify modal remains on top
- Verify warning colors are distinct (red vs yellow boxes)
-
Accessibility:
- Verify modal can be navigated with keyboard
- Verify "Accept" button can be focused and activated with Enter
- Verify "Cancel" button can be focused
- Verify modal traps focus (Tab doesn't leave modal)
- Verify text is readable at different zoom levels
Browser Testing
Test localStorage persistence across:
- Chrome/Edge
- Firefox
- Safari
- Browser restart
- Tab close and reopen
Edge Cases
- Multiple browser tabs - verify acceptance in one tab reflects in others on reload
- Incognito/private browsing - verify modal appears every session
- localStorage quota exceeded - verify graceful degradation
- Disabled JavaScript - app won't work, but no crashes
- Fast double-click on Accept - verify no duplicate localStorage writes
Security Considerations
Disclaimer Bypass Risk: Users could theoretically bypass the disclaimer by:
- Manually setting localStorage:
localStorage.setItem("tftsr-ai-disclaimer-accepted", "true") - Using browser dev tools
Mitigation: This is acceptable because:
- The disclaimer is for liability protection, not security
- Users who bypass it are technical enough to understand the risks
- The disclaimer is shown prominently and is hard to miss accidentally
- Acceptance is logged client-side (could be enhanced to log server-side for audit)
Future Enhancement:
- Log acceptance event to backend with timestamp
- Store acceptance in database tied to user session
- Require periodic re-acceptance (e.g., every 90 days)
- Add version tracking to re-show on disclaimer updates
Legal Notes
This disclaimer should be reviewed by legal counsel to ensure:
- Adequate liability protection
- Compliance with jurisdiction-specific requirements
- Appropriate language for organizational use
- Clear "Use at your own risk" messaging
Recommended additions (by legal):
- Add version number/date to disclaimer
- Log acceptance with timestamp for audit trail
- Consider adding "This is an experimental tool" if applicable
- Add specific disclaimer for any regulated environments (healthcare, finance, etc.)