diff --git a/RE_Developer_Checklist.md b/RE_Developer_Checklist.md new file mode 100644 index 0000000..fdccb3d --- /dev/null +++ b/RE_Developer_Checklist.md @@ -0,0 +1,265 @@ +# RE Workflow - Developer Action Checklist +## Week-by-Week Task List for Developers + +**Current Week:** Week 2 +**Target Launch:** End of December 2025 + +--- + +## 🔥 WEEK 2 (THIS WEEK) - Complete Foundation + +### Backend Developer Tasks (3 days) + +#### Day 1: Database Setup +- [ ] Install PostgreSQL 16 +- [ ] Create database `re_workflow_db` +- [ ] Run schema SQL from `RE_Workflow_Complete_Project_Setup.md` (lines 980-1427) +- [ ] Verify all 15 tables created +- [ ] Test database connection +- [ ] ✅ Deliverable: Database ready + +#### Day 2: Express & Middleware +- [ ] Complete `src/app.ts` (Express setup) +- [ ] Configure helmet, cors, body-parser +- [ ] Setup Winston logger +- [ ] Create error handler middleware +- [ ] Test `/health` endpoint +- [ ] ✅ Deliverable: Server running + +#### Day 3: Sequelize Models +- [ ] Configure Sequelize connection +- [ ] Create models: + - [ ] User.ts + - [ ] WorkflowRequest.ts + - [ ] ApprovalLevel.ts + - [ ] Participant.ts + - [ ] Document.ts + - [ ] WorkNote.ts + - [ ] Activity.ts + - [ ] Notification.ts + - [ ] TATTracking.ts + - [ ] ConclusionRemark.ts +- [ ] Define model associations +- [ ] Test queries +- [ ] ✅ Deliverable: ORM working + +--- + +### Frontend Developer Tasks (4 days) + +#### Day 1: Complete UI Extraction +- [ ] Finish remaining 20% of Figma components +- [ ] Fix any styling bugs +- [ ] Test mobile responsive (320px - 1920px) +- [ ] Ensure all dummy data displays +- [ ] ✅ Deliverable: 100% UI extraction + +#### Day 2-3: Redux Store Setup (CRITICAL) +- [ ] Create `src/redux/store.ts` +- [ ] Create `src/redux/hooks.ts` +- [ ] Create slices: + - [ ] authSlice.ts + - [ ] workflowSlice.ts + - [ ] approvalSlice.ts + - [ ] notificationSlice.ts + - [ ] documentSlice.ts + - [ ] workNoteSlice.ts + - [ ] participantSlice.ts + - [ ] uiSlice.ts +- [ ] Configure Redux DevTools +- [ ] Setup Redux persist +- [ ] ✅ Deliverable: Redux working + +#### Day 4: Axios API Layer (CRITICAL) +- [ ] Create `src/services/api.ts` (Axios instance) +- [ ] Setup request interceptor (add JWT) +- [ ] Setup response interceptor (handle errors) +- [ ] Create service files: + - [ ] auth.service.ts + - [ ] workflow.service.ts + - [ ] approval.service.ts + - [ ] document.service.ts + - [ ] notification.service.ts + - [ ] workNote.service.ts + - [ ] participant.service.ts + - [ ] dashboard.service.ts + - [ ] user.service.ts +- [ ] Create PrivateRoute component +- [ ] ✅ Deliverable: API layer ready + +--- + +## WEEK 3: SSO Authentication + +### Backend (2 days) +- [ ] Configure SSO Bridge (config/sso.ts) +- [ ] Implement SSO callback handler +- [ ] User sync from Active Directory +- [ ] Generate JWT tokens +- [ ] Auth middleware +- [ ] APIs: + - [ ] GET /api/v1/auth/login (redirect to SSO) + - [ ] GET /api/v1/auth/callback (handle SSO) + - [ ] POST /api/v1/auth/logout + - [ ] GET /api/v1/auth/me + - [ ] GET /api/v1/users/search + +### Frontend (1.5 days) +- [ ] Create SSO callback page +- [ ] Handle token from SSO +- [ ] Store JWT in Redux + localStorage +- [ ] Implement protected routes +- [ ] Add logout button in header +- [ ] Fetch and display user profile + +--- + +## WEEK 4-5: Workflow Creation Wizard + +### Backend (1 week) +- [ ] POST /api/v1/workflows (create workflow) +- [ ] POST /api/v1/workflows/:id/approvals (add level) +- [ ] POST /api/v1/workflows/:id/participants (add spectator) +- [ ] POST /api/v1/workflows/:id/documents (upload file) +- [ ] PATCH /api/v1/workflows/:id/submit (submit workflow) +- [ ] GET /api/v1/workflows (list with filters) +- [ ] TAT calculation logic (working days vs calendar days) + +### Frontend (1.5 weeks) +- [ ] Step 1: Template selection → Redux +- [ ] Step 2: Basic info (title, description, priority) → Redux + validation +- [ ] Step 3: Approval workflow builder + - [ ] Dynamic levels (add/remove) + - [ ] User @mention search + - [ ] TAT calculation (real-time) + - [ ] Approval flow summary +- [ ] Step 4: Spectators (@mention) +- [ ] Step 5: Document upload (react-dropzone) +- [ ] Step 6: Review & submit +- [ ] Multi-step API submission flow + +**Most Time-Consuming:** Step 3 (approval builder) - 2-3 days + +--- + +## WEEK 6-7: Approvals & TAT Tracking + +### Backend (1.5 weeks) +- [ ] PATCH /api/v1/workflows/:id/approvals/:levelId/approve +- [ ] PATCH /api/v1/workflows/:id/approvals/:levelId/reject +- [ ] Approval state machine logic +- [ ] TAT monitoring cron job (runs every 30 min) +- [ ] Notification system (8 notification types) +- [ ] Activity logging service + +### Frontend (2 weeks) +- [ ] My Requests page (tabs, search, filter, pagination) +- [ ] Open/Closed Requests pages +- [ ] Request Detail page: + - [ ] Overview tab + - [ ] Workflow tab (approval timeline) + - [ ] Documents tab (preview, download) + - [ ] Activity tab (timeline) +- [ ] TAT progress bar (color-coded) +- [ ] Approve/Reject modals (with validation) +- [ ] Notification bell with dropdown + +**Most Time-Consuming:** Request detail page with all tabs - 3-4 days + +--- + +## WEEK 8: Documents & Work Notes + +### Backend (3 days) +- [ ] Document storage (GCP Cloud Storage) +- [ ] Document APIs (upload, download, preview) +- [ ] Work notes APIs +- [ ] @mention parsing and notifications +- [ ] Emoji reactions + +### Frontend (2 days) +- [ ] Connect work notes to backend (already has UI + emoji!) +- [ ] Connect document upload with progress bar +- [ ] PDF/image preview modal +- [ ] File download functionality + +**Advantage:** Work notes UI already complete! + +--- + +## WEEK 9: Dashboard & AI + +### Backend (3 days) +- [ ] Dashboard statistics APIs +- [ ] OpenAI/Gemini integration +- [ ] AI conclusion generation +- [ ] Workflow closure API + +### Frontend (3 days) +- [ ] Dashboard with charts (Recharts) +- [ ] Conclusion display & edit +- [ ] Close workflow functionality +- [ ] Search & filter components + +--- + +## WEEK 10: Testing & Deployment + +### Backend (4 days) +- [ ] Unit tests (Jest + ts-jest) +- [ ] Integration tests (Supertest) +- [ ] Swagger documentation +- [ ] Performance optimization +- [ ] Docker + CI/CD +- [ ] Deploy to GCP + +### Frontend (4 days) +- [ ] Component tests (Vitest) +- [ ] Integration tests +- [ ] Loading states everywhere +- [ ] Error boundaries +- [ ] Production build +- [ ] Docker + CI/CD +- [ ] Deploy to GCP + +--- + +## 🎯 Daily Developer Checklist + +### Before Starting Any Task: +- [ ] Is the prerequisite task complete? +- [ ] Do I have all required information? +- [ ] Is the backend API ready (for frontend tasks)? + +### While Working: +- [ ] Following TypeScript strict mode +- [ ] Adding proper error handling +- [ ] Adding loading states +- [ ] Writing clean, commented code +- [ ] Testing as I build + +### Before Marking Complete: +- [ ] Feature works end-to-end +- [ ] Handles errors gracefully +- [ ] Responsive on mobile +- [ ] Code reviewed +- [ ] Committed to Git + +--- + +## 📞 Quick Communication + +### Blockers: +- Backend waiting on SSO details? → Continue with non-auth features +- Frontend waiting on APIs? → Work on UI polish, validations, Redux + +### Daily Standup (15 min): +1. What did I complete yesterday? +2. What am I working on today? +3. Any blockers or questions? + +--- + +**Last Updated:** October 23, 2025 +**Next Review:** Weekly (every Friday) + diff --git a/RE_Executive_Summary.md b/RE_Executive_Summary.md new file mode 100644 index 0000000..9b01287 --- /dev/null +++ b/RE_Executive_Summary.md @@ -0,0 +1,189 @@ +# RE Workflow Management System - Executive Summary +## Project Status & Timeline + +**Date:** October 23, 2025 +**Project:** RE Workflow Management System (Non-Templatized) +**Target Launch:** End of December 2025 + +--- + +## ✅ What's Complete (10%) + +1. **Frontend UI Extraction:** 80% complete from Figma + - All pages visually complete + - Mobile responsive (320px - 1920px) + - **But:** No functionality, just visual components with dummy data + +2. **Work Notes Feature:** Partial functionality + - UI complete + - Emoji selection working + - Document selection working + - **Needs:** Backend API integration + +3. **Backend Repository:** 70% setup + - Folder structure created + - Dependencies installed + - **Needs:** Database setup, API development + +--- + +## ❌ What's NOT Complete (90%) + +1. **Database:** 0% (not created yet) +2. **Redux Store:** 0% (not created) +3. **API Service Layer:** 0% (not configured) +4. **Form Validations:** 0% +5. **API Integration:** 0% +6. **Business Logic:** 0% (TAT calculations, workflows) +7. **Authentication:** 0% (SSO not integrated) +8. **All Backend APIs:** 0% + +--- + +## 🔐 Authentication Approach + +### SSO Login (RE SSO Bridge) +- **No login/signup screens needed** (SSO handles authentication) +- Users authenticate with company credentials +- Auto-sync from Active Directory +- **Frontend work:** Minimal (1.5 days) +- **Backend work:** SSO integration (2 days) + +**Figma Note:** No login/signup screens in Figma (not needed for SSO) + +--- + +## 📅 Revised Timeline (10 Weeks) + +| Week | Focus | Backend | Frontend | Milestone | +|------|-------|---------|----------|-----------| +| 1 | Setup | 70% done | 80% UI done | In progress | +| 2 | Foundation | Database + ORM | Redux + API layer | THIS WEEK | +| 3 | SSO | SSO integration | SSO callback | Auth working | +| 4-5 | Workflow | Workflow APIs | Wizard integration | Can create workflows | +| 6-7 | Approvals | Approval APIs + TAT | Request pages + modals | Can approve/reject | +| 8 | Collaboration | Documents + Work notes | Connect APIs | Collaboration working | +| 9 | Analytics | Dashboard + AI | Charts + polish | All features done | +| 10 | Launch | Testing + deployment | Testing + deployment | Production! 🚀 | + +--- + +## 🎯 Core Features + +### 1. Workflow Creation (Weeks 4-5) +- 6-step wizard to create workflow requests +- Dynamic approval hierarchy (up to 10 levels) +- @mention user search for approvers/spectators +- Document upload (drag-drop, max 10MB) +- TAT calculation (working days vs calendar days) + +### 2. Approval Actions (Weeks 6-7) +- Approve/reject with mandatory comments +- Multi-level approval flow +- TAT tracking with color-coded progress bars +- Automated reminders (80% TAT used) +- Breach alerts (100% TAT exceeded) + +### 3. Collaboration (Week 8) +- Work notes (chat with @mentions) +- Emoji reactions +- Document preview and download +- Real-time notifications + +### 4. Dashboard & Analytics (Week 9) +- Statistics and charts +- AI-powered conclusions (using OpenAI/Gemini) +- Search and filters + +--- + +## ⚠️ Reality Check + +### Common Misconception: +"Frontend is 80% done because UI is extracted from Figma" + +### Reality: +- UI extraction = 20% of total frontend work +- 80% UI done = 16% of frontend complete +- Still need: Redux (20%), API integration (30%), validations (20%), testing (10%) + +### Impact: +- Initial estimate: 6-8 weeks +- Realistic estimate: 10 weeks +- **Reason:** UI is just visual shell, needs 84% more work for functionality + +--- + +## 🚨 Risks & Dependencies + +### High Risk: +1. **SSO Integration:** Awaiting final confirmation and SSO details +2. **TAT Calculation:** Complex logic for working days +3. **Multi-level Approvals:** Complex state machine +4. **Backend-Frontend Sync:** Frontend blocked without APIs + +### Mitigation: +1. SSO: Can build temporary standard login if delayed (3-4 days) +2. TAT: Write comprehensive unit tests +3. Approvals: Thorough testing of all scenarios +4. Sync: Daily standups, clear API documentation + +--- + +## 💰 Resource Requirements + +### Team: +- 2-3 Backend Developers (Node.js + TypeScript + PostgreSQL) +- 2-3 Frontend Developers (React + TypeScript + Redux) +- 1 QA Engineer (Week 9-10) +- 1 DevOps Engineer (Week 10) + +### Infrastructure: +- PostgreSQL 16 database +- GCP Cloud Storage (for documents) +- GCP Cloud Run or VM (for hosting) +- OpenAI API (for AI conclusions) + +--- + +## 🎯 Success Criteria + +**Week 2:** ✅ Foundation complete (database, Redux, API layer) +**Week 3:** ✅ SSO authentication working +**Week 5:** ✅ Users can create workflows +**Week 7:** ✅ Users can approve/reject +**Week 9:** ✅ All features functional +**Week 10:** ✅ Production deployment + +--- + +## 📊 Budget & Timeline + +**Estimated Timeline:** 10 weeks (50 working days) +**Target Launch:** End of December 2025 +**Current Progress:** 10% (Week 2 of 10) +**Confidence Level:** Medium (realistic with current team) + +**Key Assumption:** SSO integration details provided by Week 3 + +--- + +## 📞 Next Steps + +### This Week (Week 2): +1. **Backend:** Complete database schema setup +2. **Frontend:** Setup Redux store and API layer +3. **Both:** Ready for feature development by week end + +### Immediate Requirements: +1. SSO Bridge documentation and credentials +2. Active Directory access for user sync +3. GCP project setup for storage +4. OpenAI API key for conclusions + +--- + +**Prepared By:** .NET Expert Team +**Status:** Realistic assessment with corrected estimates +**Focus:** Core workflow features (creation, approvals, collaboration) + diff --git a/RE_Feature_Status_Tracker.md b/RE_Feature_Status_Tracker.md new file mode 100644 index 0000000..ec21753 --- /dev/null +++ b/RE_Feature_Status_Tracker.md @@ -0,0 +1,394 @@ +# RE Workflow - Feature Status Tracker +## Quick Reference for Project Progress + +**Last Updated:** October 23, 2025 +**Overall Completion:** 10% + +--- + +## 🎨 Frontend UI Status (Figma Extraction) + +| Feature/Page | UI Extracted | Functionality | API Integration | Status | +|--------------|--------------|---------------|-----------------|--------| +| **Header & Sidebar** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | +| **Dashboard** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | +| **Create Workflow Wizard** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | +| **My Requests** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | +| **Request Detail** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | +| **Approve/Reject Modals** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | +| **Work Notes** | ✅ 100% | 🔄 30% | ❌ 0% | Emoji + Docs Working | +| **Documents Tab** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | +| **Notifications** | ✅ 80% | ❌ 0% | ❌ 0% | UI Only | + +**Overall Frontend:** 16% Complete (UI with dummy data, no functionality) + +--- + +## ⚙️ Backend API Status + +| Feature | APIs Designed | APIs Built | Tested | Status | +|---------|---------------|------------|--------|--------| +| **Database Schema** | ✅ Yes | ❌ No | ❌ No | 0% | +| **SSO Authentication** | ✅ Yes | ❌ No | ❌ No | 0% | +| **Workflow Creation** | ✅ Yes | ❌ No | ❌ No | 0% | +| **Approval Actions** | ✅ Yes | ❌ No | ❌ No | 0% | +| **TAT Tracking** | ✅ Yes | ❌ No | ❌ No | 0% | +| **Notifications** | ✅ Yes | ❌ No | ❌ No | 0% | +| **Documents** | ✅ Yes | ❌ No | ❌ No | 0% | +| **Work Notes** | ✅ Yes | ❌ No | ❌ No | 0% | +| **Dashboard** | ✅ Yes | ❌ No | ❌ No | 0% | +| **AI Conclusions** | ✅ Yes | ❌ No | ❌ No | 0% | + +**Overall Backend:** 10% Complete (repo setup only) + +--- + +## 🚀 Core Features Breakdown + +### Feature 1: Workflow Creation Wizard ⭐⭐⭐⭐⭐ (Highest Priority) + +**What Users Do:** +1. Click "Create New Request" +2. Select "Custom Request" +3. Fill basic info (title, description, priority) +4. Build approval hierarchy (levels, approvers, TAT) +5. Add spectators +6. Upload documents +7. Review and submit + +**Backend Work:** +- [ ] Workflow CRUD APIs +- [ ] Approval levels APIs +- [ ] Participant APIs +- [ ] Document upload (GCP storage) +- [ ] Submit workflow logic +- **Estimated:** 1 week + +**Frontend Work:** +- [ ] Connect 6 wizard steps to Redux +- [ ] Real-time TAT calculation +- [ ] User @mention search +- [ ] File upload with progress +- [ ] Form validations +- [ ] Multi-step API submission +- **Estimated:** 1.5 weeks + +**Current Status:** +- UI: ✅ 80% (dummy data) +- Functionality: ❌ 0% + +--- + +### Feature 2: Request Management ⭐⭐⭐⭐⭐ (Highest Priority) + +**What Users Do:** +1. View "My Requests" (all their workflows) +2. View "Open Requests" (pending their action) +3. View "Closed Requests" (completed) +4. Search and filter requests +5. Click request to see details + +**Backend Work:** +- [ ] Workflow listing APIs with filters +- [ ] Pagination +- [ ] Search (full-text) +- [ ] Filter (status, priority, date range) +- **Estimated:** 3 days + +**Frontend Work:** +- [ ] My Requests page (tabs, search, filter) +- [ ] Open/Closed Requests pages +- [ ] Request cards with status badges +- [ ] Pagination +- [ ] Loading skeletons +- **Estimated:** 1 week + +**Current Status:** +- UI: ✅ 80% (dummy cards) +- Functionality: ❌ 0% + +--- + +### Feature 3: Approval Actions ⭐⭐⭐⭐⭐ (Highest Priority) + +**What Users Do:** +1. Open request detail page +2. View approval workflow timeline +3. See TAT progress bar +4. Click "Approve" or "Reject" button +5. Add mandatory comments +6. Submit decision + +**Backend Work:** +- [ ] Approve/reject APIs +- [ ] Approval state machine logic +- [ ] TAT calculation (working days vs calendar days) +- [ ] Move to next level logic +- [ ] Notification triggers +- [ ] Activity logging +- **Estimated:** 1 week + +**Frontend Work:** +- [ ] Request detail page +- [ ] Workflow timeline tab +- [ ] TAT progress bar (color-coded) +- [ ] Approve/Reject modals +- [ ] Comment validation +- [ ] Success/error handling +- **Estimated:** 1 week + +**Current Status:** +- UI: ✅ 80% (modals exist) +- Functionality: ❌ 0% + +--- + +### Feature 4: TAT Monitoring ⭐⭐⭐⭐ (High Priority) + +**What System Does:** +1. Cron job runs every 30 minutes +2. Checks all active workflows +3. Calculates TAT percentage used +4. Sends alerts: + - 80% TAT used → Warning notification + - 100% TAT used → Breach notification + +**Backend Work:** +- [ ] TAT calculation service +- [ ] Cron job setup (node-cron) +- [ ] Notification triggers +- [ ] TAT status updates +- **Estimated:** 2 days + +**Frontend Work:** +- [ ] Display TAT progress bar +- [ ] Color code based on status: + - Green: < 50% used + - Yellow: 50-80% used + - Red: > 80% used +- [ ] Show remaining time +- **Estimated:** 1 day (included in Request Detail) + +**Current Status:** +- Backend: ❌ 0% +- Frontend UI: ✅ 80% +- Logic: ❌ 0% + +--- + +### Feature 5: Work Notes (Chat) ⭐⭐⭐⭐ (High Priority) + +**What Users Do:** +1. Open request detail +2. Go to work notes section +3. Type message with @mentions +4. Add emojis +5. Attach documents +6. Send message + +**Backend Work:** +- [ ] Work notes CRUD APIs +- [ ] @mention parsing +- [ ] Notification to mentioned users +- [ ] Emoji reactions API +- [ ] Attachments API +- **Estimated:** 2 days + +**Frontend Work:** +- [ ] Connect chat to backend API +- [ ] Fetch messages (with polling every 10 sec) +- [ ] Send message +- [ ] @mention autocomplete +- [ ] Emoji reactions +- [ ] **Estimated:** 1 day (UI + emoji already working!) + +**Current Status:** +- UI: ✅ 100% +- Emoji Selection: ✅ Working +- Document Selection: ✅ Working +- Backend API: ❌ 0% + +--- + +### Feature 6: Document Management ⭐⭐⭐ (Medium Priority) + +**What Users Do:** +1. Upload documents (PDF, Word, Excel, PPT, Images) +2. Preview PDF/images +3. Download any document +4. Link Google Docs/Sheets + +**Backend Work:** +- [ ] File upload (Multer middleware) +- [ ] GCP Cloud Storage integration +- [ ] Document CRUD APIs +- [ ] Generate signed URLs +- [ ] File validation (type, size) +- **Estimated:** 2 days + +**Frontend Work:** +- [ ] Drag-drop upload (react-dropzone) +- [ ] Upload progress bar +- [ ] Preview modal (PDF, images) +- [ ] Download functionality +- [ ] Google Docs/Sheets links +- **Estimated:** 1.5 days + +**Current Status:** +- UI: ✅ 80% +- Upload logic: ❌ 0% + +--- + +### Feature 7: Notifications ⭐⭐⭐ (Medium Priority) + +**What Users See:** +1. Bell icon in header (with unread count) +2. Click to see notification dropdown +3. Click notification to go to request +4. Mark as read / Mark all as read + +**Notification Types:** +- New approval assignment +- Approval/rejection +- TAT warning (80%) +- TAT breach (100%) +- @mention in work note +- Document uploaded +- Spectator added +- Request closed + +**Backend Work:** +- [ ] Notification CRUD APIs +- [ ] Trigger notifications on events +- [ ] Mark read/unread +- [ ] Cleanup old notifications +- **Estimated:** 2 days + +**Frontend Work:** +- [ ] Notification bell component +- [ ] Dropdown panel +- [ ] Polling (every 30 sec) +- [ ] Toast for high-priority +- [ ] Navigation to related request +- **Estimated:** 1 day + +**Current Status:** +- UI: ✅ 80% +- Polling logic: ❌ 0% + +--- + +### Feature 8: Dashboard ⭐⭐ (Lower Priority) + +**What Users See:** +- Total requests count +- Pending approvals count +- Approved/Rejected counts +- TAT breached count +- Charts (pie, bar, line) +- Recent activities +- Pending actions widget + +**Backend Work:** +- [ ] Statistics calculation APIs +- [ ] Recent activities API +- [ ] Pending actions API +- [ ] Caching for performance +- **Estimated:** 1.5 days + +**Frontend Work:** +- [ ] Metric cards +- [ ] Charts (Recharts library) +- [ ] Recent activities widget +- [ ] Auto-refresh +- **Estimated:** 1.5 days + +**Current Status:** +- UI: ✅ 80% +- Data integration: ❌ 0% + +--- + +### Feature 9: AI Conclusions ⭐⭐ (Lower Priority) + +**What System Does:** +1. After final approval, generate AI conclusion +2. Summarize approval comments + work notes +3. Initiator can edit before finalizing +4. Conclusion displayed in closed requests + +**Backend Work:** +- [ ] OpenAI API integration +- [ ] Compile workflow data for prompt +- [ ] Generate conclusion +- [ ] Store AI remark +- [ ] Update conclusion API +- **Estimated:** 1.5 days + +**Frontend Work:** +- [ ] Display AI-generated conclusion +- [ ] Edit modal (for initiator) +- [ ] Save edited conclusion +- [ ] Read-only for others +- **Estimated:** 1 day + +**Current Status:** +- Backend: ❌ 0% +- Frontend UI: ✅ 80% + +--- + +## 📊 Progress Summary + +### By Category: + +| Category | Total Work | Completed | Remaining | % Done | +|----------|-----------|-----------|-----------|--------| +| **Database Schema** | 1 week | 0 days | 1 week | 0% | +| **Backend APIs** | 6 weeks | 0 days | 6 weeks | 0% | +| **Frontend UI** | 1 week | 0.8 weeks | 0.2 weeks | 80% | +| **Redux Setup** | 3 days | 0 days | 3 days | 0% | +| **API Integration** | 3 weeks | 0 days | 3 weeks | 0% | +| **Validations** | 1 week | 0 days | 1 week | 0% | +| **Testing** | 1 week | 0 days | 1 week | 0% | +| **Deployment** | 1 week | 0 days | 1 week | 0% | + +**TOTAL:** ~16 weeks of work, 1.6 weeks done (10%) + +--- + +## 🔥 Critical Path + +**Week 2:** Database + Redux (BLOCKS EVERYTHING) +**Week 3:** SSO auth (BLOCKS AUTHENTICATED FEATURES) +**Weeks 4-5:** Workflow creation (CORE FEATURE) +**Weeks 6-7:** Approvals & TAT (CORE FEATURE) +**Week 8:** Collaboration (CORE FEATURE) +**Week 9:** Dashboard (SECONDARY) +**Week 10:** Testing & Launch + +**Cannot skip or reorder!** + +--- + +## 💡 What to Focus On + +### Core Application Features (85% of effort): +1. ✅ Workflow Creation Wizard +2. ✅ Approval Actions +3. ✅ TAT Tracking +4. ✅ Work Notes +5. ✅ Document Management +6. ✅ Notifications +7. ✅ Request Management Pages + +### Secondary Features (15% of effort): +8. Dashboard & Analytics +9. AI Conclusions +10. Search & Filters + +--- + +**Focus:** Build core workflow features first, then analytics/dashboard last! + diff --git a/RE_Task_Timeline_SSO_Based.md b/RE_Task_Timeline_SSO_Based.md new file mode 100644 index 0000000..6fb8c6f --- /dev/null +++ b/RE_Task_Timeline_SSO_Based.md @@ -0,0 +1,332 @@ +# RE Workflow Management System - Task Timeline +## SSO-Based Authentication | Realistic Progress Tracking + +**Version:** 2.0 +**Date:** October 23, 2025 +**Authentication:** SSO via RE SSO Bridge (No login/signup screens) +**Current Status:** Frontend UI 80% extracted, Backend 70% setup + +--- + +## 🎯 Current Project Status + +### Overall Progress: 10% +- **Backend:** 10% (repo 70% setup, database 0%, APIs 0%) +- **Frontend:** 16% (UI 80% extracted, but no functionality) + +### Reality Check: +✅ **What We Have:** +- Frontend UI components from Figma (80% extracted, mobile responsive) +- Work notes UI + partial functionality (emoji, document selection working) +- Dependencies installed +- Repository structure in progress + +❌ **What We DON'T Have:** +- No Redux store created +- No API service layer +- No form validations +- No API integration +- No business logic +- No authentication working +- No database setup + +**Translation:** Having UI ≠ Having features. We have the "look" but not the "functionality." + +--- + +## 🔐 SSO Authentication (No Login Screens) + +### How SSO Works: +1. User visits app → App redirects to RE SSO Bridge +2. User logs in with RE credentials (handled by SSO) +3. SSO redirects back to app with token +4. App validates token, syncs user from Active Directory +5. User lands on dashboard (logged in) + +### What We Build: +**Frontend (1.5 days):** +- SSO callback handler page +- Protected route guards +- Logout button + +**Backend (2 days):** +- SSO OAuth2 integration +- User sync from Active Directory +- JWT session management + +**No Need For:** +- ❌ Login page +- ❌ Signup page +- ❌ Password reset pages +- ❌ Email verification + +--- + +## 📅 Week-by-Week Timeline (10 Weeks) + +### **Week 1 (Completed):** Sprint 0 Setup +- ✅ Frontend UI extraction 80% (Figma) +- 🔄 Backend repo setup 70% +- ❌ Database: Not started +- ❌ Redux: Not created +- ❌ API layer: Not configured + +--- + +### **Week 2 (CURRENT):** Complete Foundation + +**Backend (3 days):** +- 🔥 Database schema setup (1 day) ← CRITICAL +- Express + middleware configuration (0.5 days) +- Sequelize ORM + models (1.5 days) + +**Frontend (4 days):** +- Complete UI extraction 20% remaining (1 day) +- 🔥 Setup Redux store + 8 slices (2 days) ← CRITICAL +- 🔥 Configure Axios API layer (1 day) ← CRITICAL + +**Target:** Foundation ready for feature development + +--- + +### **Week 3:** SSO Authentication + +**Backend (2 days):** +- SSO Bridge OAuth2 integration +- User sync from Active Directory +- JWT token generation +- Auth APIs + +**Frontend (1.5 days):** +- SSO callback page +- Protected routes +- Logout button +- User profile display + +**Target:** Users can login via SSO + +--- + +### **Week 4:** Workflow Creation Wizard (Part 1) + +**Backend (4 days):** +- Workflow CRUD APIs +- Approval levels APIs +- User search API +- TAT calculation logic + +**Frontend (4 days):** +- Template selection (connect to Redux) +- Basic information form (validation) +- Approval workflow builder (complex!) + - Dynamic levels + - User @mention search + - Real-time TAT calculation + +**Target:** First 3 wizard steps functional + +--- + +### **Week 5:** Workflow Creation Wizard (Part 2) + +**Backend (3 days):** +- Participant management APIs +- Document upload APIs (GCP storage) +- Workflow submission logic + +**Frontend (4 days):** +- Participants step (spectator @mention) +- Documents step (drag-drop upload) +- Review & submit step +- Multi-step API integration + +**Target:** Complete workflow creation working + +--- + +### **Week 6:** Request Management + +**Backend (4 days):** +- Workflow listing APIs (filters, search, pagination) +- Approval/rejection APIs +- TAT tracking service +- Activity logging + +**Frontend (4 days):** +- My Requests page (tabs, search, filter) +- Open/Closed Requests pages +- Request detail page (Overview tab) +- TAT progress bar component + +**Target:** Users can view all their requests + +--- + +### **Week 7:** Approval Actions + +**Backend (3 days):** +- Approve/reject workflow logic +- TAT monitoring cron job (every 30 min) +- Notification system (8 types) + +**Frontend (4 days):** +- Workflow tab (approval timeline) +- Documents tab (preview, download) +- Activity tab (timeline) +- Approve/Reject modals + +**Target:** Users can approve/reject requests + +--- + +### **Week 8:** Collaboration Features + +**Backend (4 days):** +- Work notes APIs (@mentions) +- Document preview/download +- Activity timeline APIs + +**Frontend (2 days):** +- Connect work notes to backend +- Connect document APIs +- Notification bell with polling + +**Target:** Work notes and documents working + +--- + +### **Week 9:** Dashboard & Analytics + +**Backend (3 days):** +- Dashboard statistics APIs +- AI conclusion generation +- Workflow closure API + +**Frontend (4 days):** +- Dashboard with charts +- Search & filter components +- Conclusion display & edit +- Closure functionality + +**Target:** Dashboard and AI conclusions working + +--- + +### **Week 10:** Testing & Deployment + +**Backend (4 days):** +- Unit tests (Jest) +- Integration tests +- API documentation (Swagger) +- Deployment setup + +**Frontend (4 days):** +- Component tests (Vitest) +- Integration tests +- Performance optimization +- Production build & deployment + +**Target:** Production launch! 🚀 + +--- + +## 📊 Task Summary + +### Backend: 25 Tasks +- Sprint 0: 4 tasks (3 days) +- Sprint 1: 2 tasks (2 days) - SSO +- Sprint 2: 4 tasks (8 days) - Workflow creation +- Sprint 3: 3 tasks (6 days) - Approvals & TAT +- Sprint 4: 3 tasks (5 days) - Documents & Work notes +- Sprint 5: 3 tasks (4 days) - Dashboard & AI +- Sprint 6: 6 tasks (8 days) - Testing & deployment + +**Total: ~8 weeks (42 days)** + +--- + +### Frontend: 30 Tasks (Reduced - No login screens!) +- Sprint 0: 5 tasks (4 days) - Foundation +- Sprint 1: 3 tasks (2.5 days) - SSO callback +- Sprint 2: 8 tasks (9 days) - Workflow wizard +- Sprint 3: 9 tasks (10 days) - Request management +- Sprint 4: 4 tasks (5 days) - Collaboration +- Sprint 5: 4 tasks (4 days) - Dashboard +- Sprint 6: 4 tasks (5 days) - Testing + +**Total: ~8 weeks (40 days)** + +--- + +## 🎯 This Week's Priorities (Week 2) + +### Backend Must Complete: +1. 🔥 **Database schema** - Blocks everything (1 day) +2. Express.js configuration (0.5 days) +3. Sequelize ORM + all models (1.5 days) + +### Frontend Must Complete: +1. Complete UI extraction 20% (1 day) +2. 🔥 **Setup Redux store + 8 slices** - Cannot skip (2 days) +3. 🔥 **Configure Axios API layer** - Cannot skip (1 day) + +**End of Week 2:** Both teams ready for feature development + +--- + +## 📋 Core Features Focus + +### 1. Workflow Creation (Week 4-5) - CORE FEATURE +- 6-step wizard +- Approval hierarchy builder (dynamic levels, @mention, TAT) +- Document upload +- Submit workflow + +### 2. Approval Actions (Week 6-7) - CORE FEATURE +- Approve/reject with comments +- TAT tracking (working days vs calendar days) +- Notifications +- Activity timeline + +### 3. Collaboration (Week 8) - CORE FEATURE +- Work notes (chat with @mentions, emojis) +- Document management +- Real-time notifications + +### 4. Analytics (Week 9) - SECONDARY +- Dashboard with charts +- AI-powered conclusions +- Search & filters + +--- + +## 📖 Documentation References + + + + +## ⚠️ Key Insights + +1. **SSO = No login screens** (saves 3-4 days frontend work) +2. **80% UI ≠ 80% done** (actually 16% of total work) +3. **Integration is 80% of work** (Redux, API, validation, logic) +5. **Focus on core features** (workflow creation, approvals, work notes) + +--- + +## 🚀 Success Metrics + +**Week 2:** ✅ Foundation complete (database + Redux) +**Week 3:** ✅ SSO authentication working +**Week 5:** ✅ Can create workflows +**Week 7:** ✅ Can approve/reject +**Week 9:** ✅ All features functional +**Week 10:** ✅ Production deployment + +--- + +**Prepared By:** .NET Expert Team +**Target Launch:** End of December 2025 +**Current Progress:** 10% Complete +**Focus:** Core workflow features (creation, approvals, collaboration) + diff --git a/RE_Workflow_Detailed_Sprint_Guide.md b/RE_Workflow_Detailed_Sprint_Guide.md new file mode 100644 index 0000000..d77c2ed --- /dev/null +++ b/RE_Workflow_Detailed_Sprint_Guide.md @@ -0,0 +1,2285 @@ +# RE Workflow Management System - Detailed Sprint Implementation Guide +## Comprehensive Feature Breakdown for Development Team + +**Version:** 1.0 +**Date:** October 23, 2025 +**Project:** RE Workflow Management System (Non-Templatized) +**Focus:** Core Application Features (Workflow Creation, Approvals, Work Notes, Documents) + +--- + +## 📖 Table of Contents +1. [Sprint 0: Foundation Setup](#sprint-0-foundation-setup) +2. [Sprint 1: SSO Authentication](#sprint-1-sso-authentication) +3. [Sprint 2: Workflow Creation Wizard](#sprint-2-workflow-creation-wizard) +4. [Sprint 3: Approval Actions & TAT Tracking](#sprint-3-approval-actions--tat-tracking) +5. [Sprint 4: Documents & Work Notes](#sprint-4-documents--work-notes) +6. [Sprint 5: Dashboard & Analytics](#sprint-5-dashboard--analytics) +7. [Sprint 6: Testing & Deployment](#sprint-6-testing--deployment) + +--- + +## Sprint 0: Foundation Setup + +### Backend Foundation (3 days) + +**BE-001 to BE-004:** Database, Express, Sequelize setup +- See main task document for technical setup details +- Focus: Get server running with database connection + +### Frontend Foundation (4 days) + +**Current Status:** +- ✅ UI Components: 80% extracted from Figma +- ❌ Redux Store: Not created (2-3 days needed) +- ❌ API Service Layer: Not configured (1 day needed) +- ❌ Route Guards: Not implemented (1 day needed) + +**Critical Work This Week:** +1. Complete UI extraction (20% remaining) +2. **Setup Redux store - CANNOT SKIP** +3. **Configure Axios API layer - CANNOT SKIP** +4. Implement protected routes + +--- + +## Sprint 1: SSO Authentication (Week 2-3) + +### 🔐 SSO Integration Overview + +**Important:** No login/signup/password reset screens needed! + +#### Backend SSO Integration (BE-101: 1.5 days) + +**SSO Flow Implementation:** + +**Step 1: Configure SSO Bridge** +```typescript +// src/config/sso.ts +export const ssoConfig = { + authorizationURL: process.env.SSO_AUTHORIZATION_URL, // RE SSO Bridge URL + tokenURL: process.env.SSO_TOKEN_URL, + userInfoURL: process.env.SSO_USERINFO_URL, + clientID: process.env.SSO_CLIENT_ID, + clientSecret: process.env.SSO_CLIENT_SECRET, + callbackURL: process.env.SSO_CALLBACK_URL, // https://workflow.re.com/api/v1/auth/callback + scope: ['openid', 'profile', 'email', 'employee_info'] +}; +``` + +**Step 2: Implement SSO Auth Service** +```typescript +// src/services/auth.service.ts +import passport from 'passport'; +import { Strategy as OAuth2Strategy } from 'passport-oauth2'; + +// Configure Passport OAuth2 strategy +passport.use('re-sso', new OAuth2Strategy({ + authorizationURL: ssoConfig.authorizationURL, + tokenURL: ssoConfig.tokenURL, + clientID: ssoConfig.clientID, + clientSecret: ssoConfig.clientSecret, + callbackURL: ssoConfig.callbackURL +}, async (accessToken, refreshToken, profile, done) => { + // Get user info from SSO + const userInfo = await fetchUserInfoFromSSO(accessToken); + + // Sync user to local database + const user = await syncUserFromAD(userInfo); + + return done(null, user); +})); + +async function syncUserFromAD(ssoUserInfo) { + // Check if user exists in local database + let user = await User.findOne({ where: { employee_id: ssoUserInfo.employeeId } }); + + if (!user) { + // Create new user from AD info + user = await User.create({ + employee_id: ssoUserInfo.employeeId, + email: ssoUserInfo.email, + first_name: ssoUserInfo.firstName, + last_name: ssoUserInfo.lastName, + department: ssoUserInfo.department, + designation: ssoUserInfo.designation, + phone: ssoUserInfo.phone, + profile_picture_url: ssoUserInfo.profilePicture + }); + } else { + // Update existing user with latest AD info + await user.update({ + email: ssoUserInfo.email, + first_name: ssoUserInfo.firstName, + last_name: ssoUserInfo.lastName, + department: ssoUserInfo.department, + designation: ssoUserInfo.designation, + last_login: new Date() + }); + } + + return user; +} +``` + +**Step 3: Implement Auth Controller** +```typescript +// src/controllers/auth.controller.ts +export const authController = { + // Initiate SSO login + login: (req, res) => { + // Redirect to SSO Bridge + passport.authenticate('re-sso')(req, res); + }, + + // Handle SSO callback + callback: async (req, res) => { + passport.authenticate('re-sso', async (err, user) => { + if (err || !user) { + return res.redirect('/auth/error?message=authentication_failed'); + } + + // Generate JWT token for app session + const jwtToken = generateJWT({ + userId: user.user_id, + email: user.email, + employeeId: user.employee_id + }); + + // Redirect to frontend with token + res.redirect(`${process.env.FRONTEND_URL}/auth/callback?token=${jwtToken}`); + })(req, res); + }, + + // Get current user + me: async (req, res) => { + const user = await User.findByPk(req.user.userId); + res.json({ success: true, data: user }); + }, + + // Logout + logout: (req, res) => { + // Clear session + req.logout(); + + // Redirect to SSO logout + const ssoLogoutUrl = `${ssoConfig.logoutURL}?redirect_uri=${process.env.FRONTEND_URL}`; + res.json({ success: true, redirectUrl: ssoLogoutUrl }); + } +}; +``` + +#### Frontend SSO Integration (FE-101, FE-102: 1.5 days) + +**Frontend Work (Minimal):** + +**1. SSO Callback Handler (FE-101: 1 day)** +```typescript +// src/pages/Auth/SSOCallback.tsx +const SSOCallback = () => { + const navigate = useNavigate(); + const dispatch = useAppDispatch(); + const [error, setError] = useState(null); + + useEffect(() => { + // Get token from URL params + const params = new URLSearchParams(window.location.search); + const token = params.get('token'); + const errorMsg = params.get('error'); + + if (errorMsg) { + setError('Authentication failed. Please try again.'); + setTimeout(() => navigate('/'), 3000); + return; + } + + if (token) { + // Store JWT token + localStorage.setItem('accessToken', token); + + // Update Redux state + dispatch(setAuthenticated(true)); + + // Fetch user details + dispatch(fetchCurrentUser()); + + // Redirect to dashboard + navigate('/dashboard'); + } + }, []); + + if (error) { + return ; + } + + return ( +
+ +

Authenticating... Please wait.

+
+ ); +}; +``` + +**2. Protected Routes (FE-101: Included in above)** +```typescript +// src/routes/PrivateRoute.tsx +const PrivateRoute = ({ children }) => { + const { isAuthenticated } = useAppSelector(state => state.auth); + + if (!isAuthenticated) { + // Redirect to SSO login + window.location.href = `${API_BASE_URL}/auth/login`; + return ; + } + + return <>{children}; +}; +``` + +**3. Logout Button (FE-102: 0.5 days)** +```typescript +// In Header component +const handleLogout = async () => { + try { + // Call logout API + const response = await authService.logout(); + + // Clear local state + dispatch(clearAuth()); + localStorage.removeItem('accessToken'); + + // Redirect to SSO logout + window.location.href = response.data.redirectUrl; + } catch (error) { + console.error('Logout failed:', error); + } +}; + +// Logout button in header + +``` + +**4. User Profile Display (FE-103: 1 day)** +```typescript +// Fetch user on app load +useEffect(() => { + if (isAuthenticated) { + dispatch(fetchCurrentUser()); // GET /api/v1/auth/me + } +}, [isAuthenticated]); + +// Display in header dropdown + + + + {user.display_name} + {user.email} + {user.department} + ID: {user.employee_id} + + + Edit Profile + Logout + +``` + +**Sprint 1 Summary:** +- ✅ SSO handles authentication (no login screens needed) +- ✅ Frontend just handles callback and redirects +- ✅ Users auto-synced from Active Directory +- ✅ Simple logout button +- **Total Frontend Work:** 1.5-2 days (not 4-5 days!) + +--- + +## Sprint 2: Workflow Creation Wizard (Weeks 3-4) + +### 🎯 Focus: Enable users to create workflow requests + +This is the **CORE FEATURE** of the application! + +--- + +### Step 1: Template Selection (FE-202: 0.5 days) + +**UI Status:** ✅ Already from Figma (80%) + +**What to Build:** +```typescript +// src/components/workflow/TemplateSelector.tsx +const TemplateSelector = () => { + const [selectedTemplate, setSelectedTemplate] = useState('CUSTOM'); + const dispatch = useAppDispatch(); + + const handleSelect = (type) => { + setSelectedTemplate(type); + // Save to Redux + dispatch(setWorkflowTemplateType(type)); + }; + + return ( +
+ handleSelect('CUSTOM')} + > + 📋 + Custom Request (Non-Templatized) + + Create a flexible workflow tailored to your specific needs. + Define approval levels, TAT, and participants dynamically. + + Available + + + + 📄 + Template Request + + Use predefined workflow templates for common processes. + + Coming Soon + +
+ ); +}; +``` + +**Deliverable:** User can select "Custom Request" + +--- + +### Step 2: Basic Information (FE-203: 1 day) + +**UI Status:** ✅ Already from Figma + +**What to Build:** + +**1. Request Title Field:** +```typescript +const [title, setTitle] = useState(''); +const [titleError, setTitleError] = useState(''); + +const validateTitle = (value) => { + if (!value || value.trim() === '') { + setTitleError('Request title is required'); + return false; + } + if (value.length > 500) { + setTitleError('Title must be less than 500 characters'); + return false; + } + setTitleError(''); + return true; +}; + + { + setTitle(e.target.value); + validateTitle(e.target.value); + }} + error={!!titleError} + helperText={titleError || `${title.length}/500 characters`} + placeholder="E.g., Approval for new office location" + required + fullWidth +/> +``` + +**2. Rich Text Description:** +```typescript +// Use React Quill or similar +import ReactQuill from 'react-quill'; + +const [description, setDescription] = useState(''); + +const quillModules = { + toolbar: [ + ['bold', 'italic', 'underline'], + [{ 'list': 'ordered'}, { 'list': 'bullet' }], + ['link'], + [{ 'table': 'insert-table' }], + ] +}; + + +{description.length} / 5000 +``` + +**3. Priority Selection:** +```typescript +const [priority, setPriority] = useState('STANDARD'); + + setPriority(e.target.value)}> + } + label={ +
+ Standard + + TAT calculated using working days (Mon-Fri, excluding weekends) + +
+ } + /> + } + label={ +
+ Express (Urgent) + + TAT calculated using calendar days (includes weekends) + +
+ } + /> +
+``` + +**4. Save to Redux:** +```typescript +const handleNext = () => { + if (!validateTitle(title) || !description) { + toast.error('Please fill all required fields'); + return; + } + + // Save to Redux + dispatch(updateWorkflowBasicInfo({ + title, + description, + priority + })); + + // Go to next step + setActiveStep(2); // Approval Workflow step +}; +``` + +**Deliverable:** Basic information captured and validated + +--- + +### Step 3: Approval Workflow Builder (FE-204: 2-3 days) + +**UI Status:** ✅ Already from Figma +**Complexity:** ⭐⭐⭐⭐⭐ (MOST COMPLEX SCREEN) + +**What to Build:** + +**1. Dynamic Approval Levels (Core Logic)** + +```typescript +// State management for approval levels +const [approvalLevels, setApprovalLevels] = useState([ + { + levelNumber: 1, + levelName: '', + approverId: null, + approverDetails: null, + tatValue: '', + tatUnit: 'hours' // or 'days' + } +]); + +// Add new level +const handleAddLevel = () => { + if (approvalLevels.length >= 10) { + toast.error('Maximum 10 approval levels allowed'); + return; + } + + setApprovalLevels([ + ...approvalLevels, + { + levelNumber: approvalLevels.length + 1, + levelName: '', + approverId: null, + approverDetails: null, + tatValue: '', + tatUnit: 'hours' + } + ]); +}; + +// Remove level +const handleRemoveLevel = (levelNumber) => { + if (approvalLevels.length === 1) { + toast.error('At least one approval level is required'); + return; + } + + setApprovalLevels( + approvalLevels + .filter(level => level.levelNumber !== levelNumber) + .map((level, index) => ({ ...level, levelNumber: index + 1 })) // Renumber + ); +}; +``` + +**2. User Search for Approver (@mention)** + +```typescript +// User search component +const ApproverSearch = ({ levelIndex, onSelectUser }) => { + const [searchQuery, setSearchQuery] = useState(''); + const [searchResults, setSearchResults] = useState([]); + const [loading, setLoading] = useState(false); + + // Debounced search + useEffect(() => { + const timer = setTimeout(async () => { + if (searchQuery.length >= 2) { + setLoading(true); + try { + // Call user search API + const response = await userService.searchUsers(searchQuery); + setSearchResults(response.data); + } catch (error) { + console.error('User search failed:', error); + } finally { + setLoading(false); + } + } else { + setSearchResults([]); + } + }, 300); + + return () => clearTimeout(timer); + }, [searchQuery]); + + return ( +
+ setSearchQuery(e.target.value)} + InputProps={{ + startAdornment: , + endAdornment: loading && + }} + /> + + {searchResults.length > 0 && ( + + {searchResults.map(user => ( + { + onSelectUser(user); + setSearchQuery(''); + setSearchResults([]); + }} + > + + + {user.display_name} + {user.email} + {user.department} • {user.designation} + + + ))} + + )} +
+ ); +}; +``` + +**3. TAT Input and Real-Time Calculation** + +```typescript +// TAT calculation logic +const calculateTotalTAT = () => { + let totalHours = 0; + + approvalLevels.forEach(level => { + const tatValue = parseFloat(level.tatValue) || 0; + + if (level.tatUnit === 'days') { + totalHours += tatValue * 24; + } else { + totalHours += tatValue; + } + }); + + return { + totalHours, + totalDays: Math.ceil(totalHours / 24), + displayText: `${totalHours} hours (${Math.ceil(totalHours / 24)} days)` + }; +}; + +// Update total TAT when levels change +const totalTAT = useMemo(() => calculateTotalTAT(), [approvalLevels]); + +// TAT display + + Total TAT + {totalTAT.totalHours} hours + {totalTAT.totalDays} days + + Est. Completion: {calculateExpectedDate(totalTAT.totalHours, priority)} + + +``` + +**4. Approval Level UI (For Each Level)** + +```typescript +{approvalLevels.map((level, index) => ( + + + Level {level.levelNumber} + {approvalLevels.length > 1 && ( + handleRemoveLevel(level.levelNumber)}> + + + )} + + + {/* Level Name (Optional) */} + updateLevel(index, 'levelName', e.target.value)} + placeholder="E.g., Department Head Approval" + fullWidth + /> + + {/* Approver Selection */} + updateLevel(index, 'approver', user)} + /> + + {level.approverDetails && ( + + + + {level.approverDetails.display_name} + {level.approverDetails.department} + + updateLevel(index, 'approver', null)}> + + + + )} + + {/* TAT Input */} + + updateLevel(index, 'tatValue', e.target.value)} + placeholder="E.g., 48" + required + /> + + + +))} + + +``` + +**5. Approval Flow Summary (Live Preview)** + +```typescript + + Approval Flow Summary + + {approvalLevels.map((level, index) => ( + + {level.levelNumber} + + + {level.levelName || `Level ${level.levelNumber}`} + + + {level.approverDetails?.display_name || 'Not selected'} + + TAT: {level.tatValue} {level.tatUnit} + + {index < approvalLevels.length - 1 && } + + ))} + + + Total TAT: {totalTAT.displayText} + + +``` + +**6. Validation Before Next Step** + +```typescript +const validateApprovalWorkflow = () => { + // Check at least 1 level + if (approvalLevels.length === 0) { + toast.error('At least one approval level is required'); + return false; + } + + // Check each level + for (let i = 0; i < approvalLevels.length; i++) { + const level = approvalLevels[i]; + + // Check approver selected + if (!level.approverId) { + toast.error(`Please select an approver for Level ${level.levelNumber}`); + return false; + } + + // Check TAT value + if (!level.tatValue || parseFloat(level.tatValue) <= 0) { + toast.error(`Please enter valid TAT for Level ${level.levelNumber}`); + return false; + } + } + + // Check for duplicate approvers + const approverIds = approvalLevels.map(l => l.approverId); + const uniqueApproverIds = new Set(approverIds); + if (approverIds.length !== uniqueApproverIds.size) { + toast.error('Same person cannot be approver at multiple levels'); + return false; + } + + return true; +}; + +const handleNext = () => { + if (!validateApprovalWorkflow()) { + return; + } + + // Save to Redux + dispatch(setApprovalLevels(approvalLevels)); + + // Calculate and save total TAT + dispatch(setTotalTAT(calculateTotalTAT())); + + // Go to next step + setActiveStep(3); // Participants step +}; +``` + +**Backend Integration (BE-201, BE-202: 2.5 days):** +- POST /api/v1/workflows - Create draft workflow +- POST /api/v1/workflows/:id/approvals - Add approval levels +- GET /api/v1/users/search - User search for @mention + +**Deliverable:** Approval hierarchy builder fully functional + +--- + +### Step 4: Participants & Access (FE-205: 1 day) + +**UI Status:** ✅ Already from Figma + +**What to Build:** + +**Spectator Management:** +```typescript +const [spectators, setSpectators] = useState([]); + +// Add spectator (reuse ApproverSearch component) +const handleAddSpectator = (user) => { + // Check if already added + if (spectators.find(s => s.user_id === user.user_id)) { + toast.warning('User already added as spectator'); + return; + } + + // Check if user is already an approver + const isApprover = approvalLevels.some(l => l.approverId === user.user_id); + if (isApprover) { + toast.warning('User is already an approver'); + return; + } + + setSpectators([...spectators, user]); + toast.success(`${user.display_name} added as spectator`); +}; + +// Remove spectator +const handleRemoveSpectator = (userId) => { + setSpectators(spectators.filter(s => s.user_id !== userId)); +}; + +// Display + + {spectators.map(spectator => ( + } + label={spectator.display_name} + onDelete={() => handleRemoveSpectator(spectator.user_id)} + /> + ))} + + +// Save to Redux +dispatch(setSpectators(spectators)); +``` + +**Backend Integration (BE-203: 1 day):** +- POST /api/v1/workflows/:id/participants - Add spectators + +**Deliverable:** Spectator management functional + +--- + +### Step 5: Documents & Attachments (FE-206: 1 day) + +**UI Status:** ✅ Already from Figma + +**What to Build:** + +**File Upload with react-dropzone:** +```typescript +import { useDropzone } from 'react-dropzone'; + +const [files, setFiles] = useState([]); +const [uploadProgress, setUploadProgress] = useState({}); + +const onDrop = useCallback((acceptedFiles, rejectedFiles) => { + // Handle rejected files + rejectedFiles.forEach(({ file, errors }) => { + errors.forEach(error => { + if (error.code === 'file-too-large') { + toast.error(`${file.name} is too large. Max size: 10MB`); + } else if (error.code === 'file-invalid-type') { + toast.error(`${file.name} has invalid type`); + } + }); + }); + + // Add accepted files + setFiles(prevFiles => [...prevFiles, ...acceptedFiles]); +}, []); + +const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop, + accept: { + 'application/pdf': ['.pdf'], + 'application/msword': ['.doc'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'], + 'application/vnd.ms-excel': ['.xls'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'], + 'application/vnd.ms-powerpoint': ['.ppt'], + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['.pptx'], + 'image/jpeg': ['.jpg', '.jpeg'], + 'image/png': ['.png'], + 'image/gif': ['.gif'] + }, + maxSize: 10 * 1024 * 1024, // 10MB + multiple: true +}); + + + + {isDragActive ? ( +

Drop files here...

+ ) : ( + <> + +

Drag files here or click to browse

+ Supported: PDF, Word, Excel, PPT, Images (Max 10MB each) + + )} +
+``` + +**File List Display:** +```typescript + + {files.map((file, index) => ( + + + {file.name} + {(file.size / 1024 / 1024).toFixed(2)} MB + handleRemoveFile(index)}> + + + + ))} + +``` + +**Google Docs/Sheets Links:** +```typescript +const [googleDocsLink, setGoogleDocsLink] = useState(''); +const [googleSheetsLink, setGoogleSheetsLink] = useState(''); + +const validateGoogleLink = (url, type) => { + if (!url) return true; + + const pattern = type === 'docs' + ? /^https:\/\/docs\.google\.com\/document\// + : /^https:\/\/docs\.google\.com\/spreadsheets\//; + + return pattern.test(url); +}; + + setGoogleDocsLink(e.target.value)} + error={!validateGoogleLink(googleDocsLink, 'docs')} + helperText={!validateGoogleLink(googleDocsLink, 'docs') && 'Invalid Google Docs URL'} + placeholder="https://docs.google.com/document/d/..." + fullWidth +/> +``` + +**Backend Integration (BE-401: 2 days):** +- POST /api/v1/workflows/:id/documents - Upload files +- File upload with Multer +- Cloud storage integration (GCP or local) + +**Deliverable:** Document upload functional + +--- + +### Step 6: Review & Submit (FE-207, FE-208: 2 days) + +**UI Status:** ✅ Already from Figma + +**What to Build:** + +**1. Complete Summary Display:** +```typescript +const ReviewStep = () => { + // Get all data from Redux + const workflowData = useAppSelector(state => state.workflow.currentDraft); + const { templateType, title, description, priority } = workflowData.basicInfo; + const { levels } = workflowData.approvals; + const { spectators } = workflowData.participants; + const { files, googleDocsLink, googleSheetsLink } = workflowData.documents; + + return ( + + {/* Request Overview */} +
+ Request Overview + + + + {templateType} + + + + + + +
+ + {/* Basic Information */} +
+ + Basic Information + setActiveStep(1)}>Edit + + {title} + +
+ + {/* Approval Workflow */} +
+ + Approval Workflow + setActiveStep(2)}>Edit + + + {levels.map((level, index) => ( + + {level.levelNumber} + {level.approverDetails.display_name} + {level.tatValue} {level.tatUnit} + {index < levels.length - 1 && } + + ))} + + Total TAT: {calculateTotalTAT().displayText} +
+ + {/* Participants */} +
+ + Participants & Access + setActiveStep(3)}>Edit + + {spectators.length} spectators + + {spectators.map(s => ( + + ))} + +
+ + {/* Documents */} +
+ + Documents & Attachments + setActiveStep(4)}>Edit + + {files.length} files uploaded + + {files.map((file, index) => ( + + + {file.name} + {(file.size / 1024 / 1024).toFixed(2)} MB + + ))} + + {googleDocsLink && Google Doc} + {googleSheetsLink && Google Sheet} +
+
+ ); +}; +``` + +**2. Submit Workflow (Complex Multi-Step API)** + +```typescript +const handleSubmitWorkflow = async () => { + setSubmitting(true); + + try { + // Step 1: Create workflow draft + const workflowResponse = await workflowService.createWorkflow({ + title: workflowData.basicInfo.title, + description: workflowData.basicInfo.description, + priority: workflowData.basicInfo.priority, + total_levels: workflowData.approvals.levels.length, + total_tat_hours: calculateTotalTAT().totalHours, + is_draft: false + }); + + const workflowId = workflowResponse.data.request_id; + + // Step 2: Upload documents + if (files.length > 0) { + for (const file of files) { + const formData = new FormData(); + formData.append('file', file); + + await documentService.uploadDocument(workflowId, formData, { + onUploadProgress: (progressEvent) => { + const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total); + setUploadProgress(prev => ({ ...prev, [file.name]: progress })); + } + }); + } + } + + // Step 3: Create approval levels + for (const level of workflowData.approvals.levels) { + await approvalService.createApprovalLevel(workflowId, { + level_number: level.levelNumber, + level_name: level.levelName, + approver_id: level.approverId, + tat_hours: level.tatUnit === 'days' ? level.tatValue * 24 : level.tatValue + }); + } + + // Step 4: Add spectators + if (spectators.length > 0) { + for (const spectator of spectators) { + await participantService.addSpectator(workflowId, { + user_id: spectator.user_id, + participant_type: 'SPECTATOR' + }); + } + } + + // Step 5: Submit workflow for approval + await workflowService.submitWorkflow(workflowId); + + // Success! + toast.success('Workflow submitted successfully!'); + + // Clear wizard state + dispatch(clearWorkflowDraft()); + + // Navigate to request detail + navigate(`/workflows/${workflowId}`); + + } catch (error) { + console.error('Workflow submission failed:', error); + toast.error(error.response?.data?.message || 'Failed to submit workflow'); + } finally { + setSubmitting(false); + } +}; +``` + +**3. Save as Draft:** +```typescript +const handleSaveDraft = async () => { + setSavingDraft(true); + + try { + const response = await workflowService.createWorkflow({ + ...workflowData, + is_draft: true + }); + + toast.success('Draft saved successfully!'); + navigate('/workflows/my-requests'); + } catch (error) { + toast.error('Failed to save draft'); + } finally { + setSavingDraft(false); + } +}; +``` + +**Deliverable:** Complete workflow submission with error handling + +--- + +## Sprint 3: Approval Actions & TAT Tracking (Weeks 5-6) + +### 🎯 Focus: Enable approvers to approve/reject workflows + +--- + +### Request Detail Page Structure (FE-303: 2 days) + +**UI Status:** ✅ Already from Figma + +**What to Build:** + +**1. Fetch Workflow Data on Load:** +```typescript +const RequestDetail = () => { + const { id } = useParams(); + const dispatch = useAppDispatch(); + const { currentWorkflow, loading, error } = useAppSelector(state => state.workflow); + + useEffect(() => { + // Fetch workflow details + dispatch(fetchWorkflowById(id)); + + // Fetch approvals + dispatch(fetchApprovals(id)); + + // Fetch documents + dispatch(fetchDocuments(id)); + + // Fetch activities + dispatch(fetchActivities(id)); + + // Fetch TAT status + dispatch(fetchTATStatus(id)); + }, [id]); + + if (loading) return ; + if (error) return ; + if (!currentWorkflow) return ; + + return ( + + + + + + + + + + + {/* Tab content */} + + + + + + + ); +}; +``` + +**2. TAT Progress Bar (Key Feature):** +```typescript +const TATProgressBar = ({ workflow }) => { + // Calculate TAT status + const tatStatus = useMemo(() => { + if (!workflow.tat_start_date) return null; + + const startTime = new Date(workflow.tat_start_date); + const currentTime = new Date(); + const totalTAT = workflow.total_tat_hours; + + const elapsedHours = (currentTime - startTime) / (1000 * 60 * 60); + const percentageUsed = (elapsedHours / totalTAT) * 100; + const remainingHours = totalTAT - elapsedHours; + + let status = 'ON_TRACK'; + let color = 'success'; + + if (percentageUsed >= 100) { + status = 'BREACHED'; + color = 'error'; + } else if (percentageUsed >= 80) { + status = 'APPROACHING'; + color = 'warning'; + } + + return { + elapsedHours: Math.floor(elapsedHours), + remainingHours: Math.max(0, Math.floor(remainingHours)), + percentageUsed: Math.min(100, percentageUsed), + status, + color + }; + }, [workflow]); + + if (!tatStatus) return null; + + return ( + + TAT Progress + + + + + {tatStatus.elapsedHours} hours + + + + + {tatStatus.remainingHours > 0 + ? `${tatStatus.remainingHours} hours` + : `${Math.abs(tatStatus.remainingHours)} hours overdue` + } + + + + + + {tatStatus.status === 'ON_TRACK' && '✓ On Track'} + {tatStatus.status === 'APPROACHING' && '⚠ Approaching Deadline'} + {tatStatus.status === 'BREACHED' && '🚨 TAT Breached'} + + + + + ); +}; +``` + +--- + +### Approve/Reject Modals (FE-307: 1.5 days) + +**UI Status:** ✅ Already from Figma + +**What to Build:** + +**Approve Request Modal:** +```typescript +const ApproveModal = ({ open, onClose, workflow, currentLevel }) => { + const [comments, setComments] = useState(''); + const [submitting, setSubmitting] = useState(false); + const dispatch = useAppDispatch(); + + const handleApprove = async () => { + // Validate comments + if (!comments || comments.trim() === '') { + toast.error('Comments are required for approval'); + return; + } + + if (comments.length > 500) { + toast.error('Comments must be less than 500 characters'); + return; + } + + setSubmitting(true); + + try { + // Call approve API + await approvalService.approveRequest(workflow.request_id, currentLevel.level_id, { + comments: comments.trim() + }); + + // Refresh workflow data + dispatch(fetchWorkflowById(workflow.request_id)); + + // Success notification + toast.success('Request approved successfully!'); + + // Close modal + onClose(); + + } catch (error) { + toast.error(error.response?.data?.message || 'Failed to approve request'); + } finally { + setSubmitting(false); + } + }; + + return ( + + + Approve Request + + + + + +

Title: {workflow.title}

+

Initiator: {workflow.initiator_name}

+

Current Level: Level {currentLevel.level_number}

+
+ + + + + {currentLevel.is_final_approver + ? "⚠️ As final approver, your approval will close this request" + : "Your approval will move this request to the next level" + } + + + setComments(e.target.value)} + multiline + rows={4} + fullWidth + required + error={comments.length > 500} + helperText={`${comments.length}/500 characters`} + /> +
+ + + + + +
+ ); +}; +``` + +**Reject Request Modal (Similar Structure):** +```typescript +// Same structure as Approve, but: +// - Red/danger styling +// - Warning message about closure +// - "Rejection Reason" instead of "Comments" +// - Confirmation prompt: "Are you sure?" +``` + +**Backend Integration (BE-301: 2 days):** +- PATCH /api/v1/workflows/:id/approvals/:levelId/approve +- PATCH /api/v1/workflows/:id/approvals/:levelId/reject +- Complex approval state machine logic +- TAT tracking updates +- Notifications to next approver/initiator + +**Deliverable:** Approval/rejection functionality working + +--- + +### TAT Monitoring Cron Job (BE-302: 2 days) + +**Backend Implementation:** +```typescript +// src/jobs/tatMonitor.job.ts +import cron from 'node-cron'; + +// Run every 30 minutes +cron.schedule('*/30 * * * *', async () => { + console.log('Running TAT monitoring job...'); + + // Get all active workflows + const activeWorkflows = await WorkflowRequest.findAll({ + where: { + status: ['PENDING', 'IN_PROGRESS'] + }, + include: [ + { + model: ApprovalLevel, + where: { status: 'IN_PROGRESS' }, + required: true + } + ] + }); + + for (const workflow of activeWorkflows) { + const currentLevel = workflow.approval_levels[0]; + + // Calculate elapsed time + const elapsedHours = calculateElapsedHours( + currentLevel.level_start_time, + new Date(), + workflow.priority // STANDARD or EXPRESS + ); + + const percentageUsed = (elapsedHours / currentLevel.tat_hours) * 100; + + // Determine TAT status + let tatStatus = 'ON_TRACK'; + if (percentageUsed >= 100) { + tatStatus = 'BREACHED'; + } else if (percentageUsed >= 80) { + tatStatus = 'APPROACHING'; + } + + // Update TAT tracking + await TATTracking.upsert({ + request_id: workflow.request_id, + level_id: currentLevel.level_id, + tat_status: tatStatus, + percentage_used: percentageUsed, + remaining_hours: currentLevel.tat_hours - elapsedHours, + checked_at: new Date() + }); + + // Send notifications based on status + if (percentageUsed >= 100 && !currentLevel.breach_alert_sent) { + // TAT Breached - send urgent notification + await notificationService.create({ + user_id: currentLevel.approver_id, + request_id: workflow.request_id, + notification_type: 'TAT_BREACH', + title: 'TAT BREACHED!', + message: `Request ${workflow.request_number} has exceeded TAT deadline`, + priority: 'URGENT' + }); + + // Mark alert sent + await currentLevel.update({ breach_alert_sent: true }); + + } else if (percentageUsed >= 80 && !currentLevel.warning_alert_sent) { + // TAT Warning - send high priority notification + await notificationService.create({ + user_id: currentLevel.approver_id, + request_id: workflow.request_id, + notification_type: 'TAT_WARNING', + title: 'TAT Warning: Action Required', + message: `Request ${workflow.request_number} has used 80% of TAT`, + priority: 'HIGH' + }); + + // Mark alert sent + await currentLevel.update({ warning_alert_sent: true }); + } + } + + console.log(`TAT monitoring completed. Checked ${activeWorkflows.length} workflows.`); +}); +``` + +**Deliverable:** Automated TAT monitoring and alerts + +--- + +## Sprint 4: Documents & Work Notes (Week 7) + +### 📎 Focus: Document management and collaboration + +--- + +### Document Management (BE-401, FE-305: 2 days total) + +**Backend Document Upload (BE-401: 1.5 days):** + +```typescript +// src/services/storage.service.ts +import { Storage } from '@google-cloud/storage'; +import multer from 'multer'; + +const storage = new Storage({ + projectId: process.env.GCP_PROJECT_ID, + keyFilename: process.env.GCP_KEY_FILE +}); + +const bucket = storage.bucket(process.env.GCP_BUCKET_NAME); + +export const uploadToGCP = async (file) => { + const fileName = `${Date.now()}-${file.originalname}`; + const blob = bucket.file(fileName); + + const blobStream = blob.createWriteStream({ + metadata: { + contentType: file.mimetype + } + }); + + return new Promise((resolve, reject) => { + blobStream.on('error', reject); + blobStream.on('finish', async () => { + const publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`; + resolve({ fileName, publicUrl }); + }); + blobStream.end(file.buffer); + }); +}; + +// src/controllers/document.controller.ts +export const documentController = { + upload: async (req, res) => { + const { id: requestId } = req.params; + const file = req.file; + + // Upload to GCP + const { fileName, publicUrl } = await uploadToGCP(file); + + // Save metadata to database + const document = await Document.create({ + request_id: requestId, + uploaded_by: req.user.userId, + file_name: file.originalname, + file_type: file.mimetype, + file_size: file.size, + file_path: fileName, + storage_url: publicUrl + }); + + // Create activity log + await Activity.create({ + request_id: requestId, + user_id: req.user.userId, + activity_type: 'DOCUMENT_UPLOADED', + activity_description: `Uploaded document: ${file.originalname}` + }); + + res.json({ success: true, data: document }); + } +}; +``` + +**Frontend Document Display (FE-305: 0.5 days):** + +```typescript +const DocumentsTab = ({ workflowId }) => { + const dispatch = useAppDispatch(); + const { documents, loading } = useAppSelector(state => state.document); + const [previewModal, setPreviewModal] = useState({ open: false, document: null }); + + useEffect(() => { + dispatch(fetchDocuments(workflowId)); + }, [workflowId]); + + const handlePreview = (document) => { + if (document.file_type.includes('pdf') || document.file_type.includes('image')) { + setPreviewModal({ open: true, document }); + } else { + toast.info('Preview not available. Please download to view.'); + } + }; + + const handleDownload = async (documentId) => { + try { + const response = await documentService.getDownloadUrl(documentId); + window.open(response.data.downloadUrl, '_blank'); + } catch (error) { + toast.error('Failed to download document'); + } + }; + + return ( + + {loading && } + + {!loading && documents.length === 0 && ( + + +

No documents uploaded yet

+
+ )} + + + {documents.map(doc => ( + + + {doc.file_name} + {(doc.file_size / 1024 / 1024).toFixed(2)} MB + + Uploaded by {doc.uploader_name} +
+ {formatDate(doc.uploaded_at)} +
+ + {(doc.file_type.includes('pdf') || doc.file_type.includes('image')) && ( + handlePreview(doc)}> + + + )} + handleDownload(doc.document_id)}> + + + +
+ ))} +
+ + setPreviewModal({ open: false, document: null })} + /> +
+ ); +}; +``` + +--- + +### Work Notes / Chat (BE-402, FE-308: 2 days total) + +**UI Status:** ✅ Already from Figma + Partial functionality +**Current:** Document selection and emoji working +**Needs:** Backend API integration, @mentions, real data + +**Backend Work Notes API (BE-402: 1.5 days):** + +```typescript +// src/controllers/workNote.controller.ts +export const workNoteController = { + getAll: async (req, res) => { + const { id: requestId } = req.params; + + const workNotes = await WorkNote.findAll({ + where: { request_id: requestId }, + include: [{ + model: User, + attributes: ['user_id', 'display_name', 'profile_picture_url'] + }], + order: [['created_at', 'ASC']] + }); + + res.json({ success: true, data: workNotes }); + }, + + create: async (req, res) => { + const { id: requestId } = req.params; + const { message } = req.body; + + // Parse @mentions from message + const mentionedUserIds = parseMentions(message); + + // Create work note + const workNote = await WorkNote.create({ + request_id: requestId, + user_id: req.user.userId, + message, + mentioned_users: mentionedUserIds, + has_attachment: false + }); + + // Send notifications to mentioned users + for (const mentionedUserId of mentionedUserIds) { + await Notification.create({ + user_id: mentionedUserId, + request_id: requestId, + notification_type: 'WORK_NOTE_MENTION', + title: `${req.user.displayName} mentioned you`, + message: `"${message.substring(0, 100)}..."`, + priority: 'NORMAL', + action_url: `/workflows/${requestId}#work-notes` + }); + } + + // Create activity + await Activity.create({ + request_id: requestId, + user_id: req.user.userId, + activity_type: 'WORK_NOTE_ADDED', + activity_description: `Added a work note` + }); + + res.json({ success: true, data: workNote }); + }, + + addReaction: async (req, res) => { + const { noteId } = req.params; + const { emoji } = req.body; + + const workNote = await WorkNote.findByPk(noteId); + + // Update reactions (JSONB column) + const reactions = workNote.reactions || {}; + if (!reactions[emoji]) { + reactions[emoji] = []; + } + + // Toggle reaction + const userIdIndex = reactions[emoji].indexOf(req.user.userId); + if (userIdIndex > -1) { + reactions[emoji].splice(userIdIndex, 1); // Remove + } else { + reactions[emoji].push(req.user.userId); // Add + } + + await workNote.update({ reactions }); + + res.json({ success: true, data: workNote }); + } +}; + +// Helper function to parse @mentions +function parseMentions(message) { + const mentionPattern = /@(\w+)|@"([^"]+)"/g; + const mentions = []; + let match; + + while ((match = mentionPattern.exec(message)) !== null) { + const username = match[1] || match[2]; + // Look up user in database + const user = await User.findOne({ + where: { + [Op.or]: [ + { email: { [Op.like]: `%${username}%` } }, + { display_name: { [Op.like]: `%${username}%` } } + ] + } + }); + + if (user) { + mentions.push(user.user_id); + } + } + + return [...new Set(mentions)]; // Remove duplicates +} +``` + +**Frontend Work Notes Integration (FE-308: 0.5 days):** + +Since UI and emoji/doc selection already work, just connect to backend: + +```typescript +const WorkNotes = ({ workflowId }) => { + const dispatch = useAppDispatch(); + const { notes, loading } = useAppSelector(state => state.workNote); + const [message, setMessage] = useState(''); + const [sending, setSending] = useState(false); + const messagesEndRef = useRef(null); + + // Fetch notes on load + useEffect(() => { + dispatch(fetchWorkNotes(workflowId)); + + // Poll for new messages every 10 seconds + const interval = setInterval(() => { + dispatch(fetchWorkNotes(workflowId)); + }, 10000); + + return () => clearInterval(interval); + }, [workflowId]); + + // Auto-scroll to bottom + useEffect(() => { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }, [notes]); + + const handleSendMessage = async () => { + if (!message.trim()) return; + + setSending(true); + + try { + await dispatch(createWorkNote({ + workflowId, + message: message.trim() + })); + + setMessage(''); // Clear input + + } catch (error) { + toast.error('Failed to send message'); + } finally { + setSending(false); + } + }; + + const handleAddReaction = async (noteId, emoji) => { + try { + await dispatch(addReactionToNote({ noteId, emoji })); + } catch (error) { + toast.error('Failed to add reaction'); + } + }; + + return ( + + + {notes.map(note => ( + + + + + {note.user.display_name} + {getUserRole(note.user_id)} + {formatRelativeTime(note.created_at)} + + {note.message} + {note.has_attachment && } + + {Object.entries(note.reactions || {}).map(([emoji, userIds]) => ( + handleAddReaction(note.note_id, emoji)} + /> + ))} + showEmojiPicker(note.note_id)} /> + + + + ))} +
+ + + +