diff --git a/CLAUDE.md b/CLAUDE.md
index 3c9d028e..29fa251c 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -292,38 +292,60 @@ This repository uses **BMAD Core** for AI-assisted development:
### FloDoc Enhancement - Current Development Workflow
-**Current Task:** Creating comprehensive PRD for 3-portal cohort management system
-
-**Workflow Process:**
-1. **Section-by-Section PRD Creation** - Following BMAD brownfield-prd-tmpl.yaml
-2. **Advanced Elicitation** - Each section requires user approval before proceeding
-3. **Iterative Development** - No implementation until complete PRD approval
-
-**Current Status:** Starting fresh PRD creation
-
-**Section Sequence:**
-1. ✅ Intro Analysis & Context (pending)
-2. ✅ Requirements (pending)
-3. ✅ Technical Constraints & Integration (pending)
-4. ✅ UI Enhancement Goals (pending)
-5. ✅ Epic & Story Structure (pending)
-6. ✅ Epic Details (pending)
-
-**Key Principles:**
-- **No code changes until PRD is complete and approved**
-- **Each section must be explicitly approved before moving to next**
-- **BMAD template guides all sections**
-- **Advanced elicitation for every section**
+**Completed Task:** `create-brownfield-prd` - Comprehensive PRD for 3-portal cohort management system
+
+**PRD Status:** ✅ COMPLETE
+- **Location:** `docs/prd.md`
+- **Sections:** 6 sections following BMAD brownfield-prd-tmpl.yaml
+- **Stories:** 21 stories across 7 phases (Phases 1-7 complete, Phase 8 with 2 infrastructure stories)
+- **Commits:** Stories 8.0 and 8.0.1 committed to git
+
+**Workflow Progress:**
+1. ✅ **Section 1:** Intro Analysis & Context - Complete
+2. ✅ **Section 2:** Requirements (FR1-FR24) - Complete
+3. ✅ **Section 3:** Technical Constraints & Integration (TC1-TC10) - Complete
+4. ✅ **Section 4:** UI Enhancement Goals (UI1-UI10) - Complete
+5. ✅ **Section 5:** Epic & Story Structure (5.1-5.8) - Complete
+6. ✅ **Section 6:** Epic Details (6.1-6.7) - Complete
+7. ✅ **Section 6.8:** Phase 8 - Deployment & Documentation - Complete (Stories 8.0, 8.0.1)
+
+**Current Phase:** ✅ **VALIDATION PHASE** (PO Agent)
+
+**Next Agent:** PO (Product Owner) Agent
+- **Task:** `po-master-checklist` - Validate all artifacts for integration safety
+- **Purpose:** Verify story completeness, security, integration requirements, and BMAD compliance
+- **Action:** PO will review `docs/prd.md` and flag any issues requiring updates
+
+**After PO Validation:**
+1. If issues found → Return to PM/Dev to fix
+2. If approved → Move to story sharding (optional for IDE)
+3. Then → Story implementation with Dev/QA agents
+
+**Key Principles Followed:**
+- ✅ No code changes until PRD complete
+- ✅ Each story approved before committing
+- ✅ Strict Story 4.6 structure compliance
+- ✅ Advanced elicitation for every section
+- ✅ Single institution model (not multi-tenant)
+- ✅ Ad-hoc access pattern (no account creation for students/sponsors)
+- ✅ Local Docker infrastructure (no production dependencies)
+
+**Deferred Stories (Production Infrastructure):**
+- Story 8.1: Production Infrastructure Setup (AWS)
+- Story 8.2: Deployment Automation & CI/CD
+- Story 8.3: Monitoring & Alerting
+- Story 8.4: Documentation & Training
+
+**Reason for Deferral:** Management wants to validate FloDoc system locally first before investing in production infrastructure.
### Next Steps for FloDoc Enhancement
-1. **Complete PRD** - Section-by-section with user approval
-2. **Architect Review** - Winston reviews authentication strategy
-3. **Database Migrations** - Create cohorts, enrollments, institutions tables
-4. **Portal Development** - Build three Vue portals
-5. **Workflow Integration** - Connect to DocuSeal submission system
-6. **Excel Export** - Implement using rubyXL gem
-7. **Testing** - Add specs for cohort workflows
+1. **PO Validation** - Run `po-master-checklist` on complete PRD
+2. **Address PO Feedback** - Fix any flagged issues
+3. **Story Sharding** (Optional) - Create docs/prd/ folder for IDE support
+4. **Story Implementation** - Dev agent implements stories 8.0 and 8.0.1
+5. **QA Review** - QA agent reviews implementation
+6. **Management Demo** - Run demo scripts to validate system
### Brownfield PRD Story Structure
diff --git a/docs/PO_Master_Validation_Report.md b/docs/PO_Master_Validation_Report.md
new file mode 100644
index 00000000..587280ac
--- /dev/null
+++ b/docs/PO_Master_Validation_Report.md
@@ -0,0 +1,1123 @@
+# PO Master Validation Report - FloDoc v3 PRD
+
+**Date:** 2026-01-13
+**Validator:** Sarah (Product Owner)
+**Project:** FloDoc v3 - 3-Portal Cohort Management System
+**Document:** `docs/prd.md` (v2.0, 872KB, 27,272 lines)
+
+---
+
+## Executive Summary
+
+**Project Type:** Brownfield Enhancement (DocuSeal → FloDoc 3-Portal Cohort Management)
+**UI/UX:** ✅ Yes (3 custom portals with TailwindCSS design system)
+**Overall Readiness:** **85%**
+**Recommendation:** ✅ **CONDITIONAL APPROVAL**
+**Critical Blocking Issues:** 3
+**High-Priority Issues:** 5
+**Medium-Priority Issues:** 5
+**Sections Skipped:** 1.1 (Greenfield only)
+
+### Quick Decision Matrix
+
+| Criteria | Status | Notes |
+|----------|--------|-------|
+| Foundation Solid | ✅ YES | Database, models, architecture well-defined |
+| Integration Safe | ⚠️ PARTIAL | Brownfield integration approaches defined, but production deployment deferred |
+| MVP Scope Defined | ✅ YES | 21 stories across 7 phases, clear scope boundaries |
+| Content Complete | ⚠️ PARTIAL | 85% complete, gaps in production readiness |
+| Ready for Dev | ⚠️ CONDITIONAL | Must address 3 blocking issues first |
+
+---
+
+## 1. PROJECT SETUP & INITIALIZATION
+
+### ✅ Status: APPROVED (0 Critical Issues)
+
+#### 1.1 Project Scaffolding [[SKIPPED - Greenfield Only]]
+
+#### 1.2 Existing System Integration [[BROWNFIELD ONLY]] ✅
+
+**Evidence:**
+- **Existing Analysis:** `DOCUSEAL_APP_ANALYSIS.md`, `current-app-sitemap.md` (8,725 bytes)
+- **Integration Strategy:** Section 4.2 defines "Database Integration Strategy: New Tables Only"
+- **Foreign Keys:** Links to `templates`, `submissions`, `users` tables without modification
+- **Development Environment:** Story 8.0: Complete Docker Compose setup (PostgreSQL, Redis, Minio, MailHog)
+- **Testing Approach:** Stories 7.1-7.5: Comprehensive testing including regression
+- **Rollback Procedures:** Every story includes Rollback Procedure section
+
+**Key Integration Points:**
+```ruby
+# New Tables (No existing table modifications)
+- institutions
+- cohorts → references :templates (existing)
+- cohort_enrollments → references :submissions (existing)
+```
+
+#### 1.3 Development Environment ✅
+
+**Evidence:**
+- **Tools:** Ruby 3.4.2, Rails 7.x, Vue.js 3, TailwindCSS 3.4.17
+- **Database:** PostgreSQL 15, Redis 7
+- **Storage:** Minio (S3-compatible), MailHog (email testing)
+- **Commands:** Story 8.0 provides complete setup:
+ ```bash
+ docker-compose -f docker-compose.dev.yml up -d
+ bundle install && rails db:prepare && rails assets:precompile
+ ```
+
+#### 1.4 Core Dependencies ✅
+
+**Evidence:**
+- **Critical Gems:** Devise, Cancancan, Sidekiq, HexaPDF, rubyXL (FR23)
+- **Frontend:** Shakapacker 8.0, Vue Test Utils
+- **Version Lock:** All versions specified in Story 8.0 Dockerfile
+- **Compatibility:** No conflicts identified with existing DocuSeal stack
+
+---
+
+## 2. INFRASTRUCTURE & DEPLOYMENT
+
+### ⚠️ Status: CONDITIONAL APPROVAL (2 Critical Issues)
+
+#### 2.1 Database & Data Store Setup ✅
+
+**Evidence:**
+- **Schema First:** Story 1.1: Database schema before any operations
+- **Migrations:** Complete schema for 3 new tables with indexes
+- **Reversibility:** Acceptance Criteria: "Migrations are reversible"
+- **Seed Data:** Story 8.0.1: `scripts/demo-data.rb` for testing
+
+**Schema Summary:**
+```
+institutions (1 record per deployment)
+ ├── cohorts (maps to templates)
+ │ └── cohort_enrollments (maps to submissions)
+```
+
+#### 2.2 API & Service Configuration ✅
+
+**Evidence:**
+- **API Framework:** Story 3.1: RESTful API with `/api/v1/flodoc/` namespace
+- **Services:** Story 1.2: CohortService, InvitationService, SponsorService
+- **Authentication:** Reuses Devise + JWT (NFR3)
+- **Compatibility:** CR1: "No breaking changes to existing public APIs"
+
+#### 2.3 Deployment Pipeline ⚠️ **CRITICAL ISSUE #1**
+
+**Status:** ❌ INCOMPLETE
+
+**What's Missing:**
+- Production CI/CD pipeline configuration
+- Infrastructure as Code (Terraform/CloudFormation)
+- Blue-green or canary deployment strategy
+- DNS/domain registration process
+- Production environment configuration
+
+**Evidence from PRD:**
+- Story 8.0: Local Docker infrastructure only
+- Stories 8.1-8.4: **DEFERRED** to "Production Infrastructure"
+- Section 2.3: No deployment pipeline definition
+
+**Impact:**
+Cannot deploy to production after local validation. System is "local demo ready" but not "production ready."
+
+**Recommendation:**
+Choose one of:
+- **Option A:** Add Stories 8.1-8.4 to current PRD scope
+- **Option B:** Explicitly declare this is local-only MVP
+- **Option C:** Add minimal Story 8.1 (Basic Production Deployment)
+
+#### 2.4 Testing Infrastructure ✅
+
+**Evidence:**
+- **Frameworks:** RSpec, Vue Test Utils, Capybara
+- **Stories 7.1-7.5:** Complete testing strategy
+ - 7.1: End-to-end workflow testing
+ - 7.2: Mobile responsiveness
+ - 7.3: Performance (50+ students)
+ - 7.4: Security audit
+ - 7.5: User acceptance testing
+- **Regression Test:** NFR22: "All DocuSeal tests must continue passing"
+- **Integration Test:** Story 7.1 validates new-to-existing connections
+
+---
+
+## 3. EXTERNAL DEPENDENCIES & INTEGRATIONS
+
+### ⚠️ Status: CONDITIONAL APPROVAL (1 Critical Issue)
+
+#### 3.1 Third-Party Services ✅
+
+**Evidence:**
+- **Local Development:** Docker containers (no external accounts needed)
+- **Storage:** Minio (local S3-compatible)
+- **Email:** MailHog (local SMTP testing)
+- **Credentials:** Environment variables in Docker
+
+#### 3.2 External APIs ✅
+
+**Evidence:**
+- **PDF Processing:** HexaPDF, PDFium (existing dependencies)
+- **Excel Export:** rubyXL (new for FR23)
+- **No New APIs:** All integrations are local libraries
+
+#### 3.3 Infrastructure Services ⚠️ **CRITICAL ISSUE #2-4**
+
+**Status:** ❌ INCOMPLETE (Production Only)
+
+**What's Missing:**
+- Cloud resource provisioning (AWS/GCP/Azure)
+- DNS/domain registration
+- CDN/static asset hosting
+- Production monitoring infrastructure
+- User analytics infrastructure
+
+**Evidence from PRD:**
+- Section 3.3: Infrastructure services not addressed
+- Story 8.0: Local Docker only
+- Stories 8.1-8.4: Deferred
+
+**Impact:**
+Production environment requirements undefined.
+
+**Recommendation:**
+These are tracked under Stories 8.1-8.4 (deferred). Decide if current scope is:
+- Local demo only (accept gaps)
+- Production-ready (add stories)
+
+---
+
+## 4. UI/UX CONSIDERATIONS
+
+### ✅ Status: APPROVED (0 Critical Issues)
+
+#### 4.1 Design System Setup ✅
+
+**Evidence:**
+- **Framework:** Vue.js 3 with Composition API
+- **Styling:** TailwindCSS 3.4.17 (replacing DaisyUI per CR3)
+- **Responsive:** 4 breakpoints (640, 768, 1024, 1280px)
+- **Accessibility:** WCAG 2.1 AA compliance
+- **Design System:** Custom colors, typography, components
+
+**Portal-Specific Requirements:**
+- **TP Portal:** Admin-first, progressive disclosure, bulk operations
+- **Student Portal:** Mobile-first, 3-click completion, progress indicators
+- **Sponsor Portal:** Review-optimized, bulk signing, keyboard shortcuts
+
+#### 4.2 Frontend Infrastructure ✅
+
+**Evidence:**
+- **Build Pipeline:** Shakapacker 8.0 (Webpack)
+- **Asset Optimization:** `rails assets:precompile`
+- **Component Workflow:** `
+
+
+```
+
+3. **Register Globally**:
+```javascript
+// app/javascript/application.js
+import FlodocCustomButton from './elements/FlodocCustomButton.vue'
+app.component('FlodocCustomButton', FlodocCustomButton)
+```
+
+---
+
+#### 1.8.7 Extending Background Jobs
+
+**Current**: Sidekiq queues for emails, webhooks, PDF generation
+
+**Adding New Job Type:**
+
+1. **Create Job**:
+```ruby
+# app/jobs/flodoc/custom_analysis_job.rb
+class Flodoc::CustomAnalysisJob < ApplicationJob
+ queue_as :analytics
+
+ def perform(cohort_id)
+ cohort = Flodoc::Cohort.find(cohort_id)
+ # Custom analysis logic
+ Flodoc::AnalysisReport.generate(cohort)
+ end
+end
+```
+
+2. **Enqueue Job**:
+```ruby
+# In any service or controller
+Flodoc::CustomAnalysisJob.perform_later(@cohort.id)
+```
+
+3. **Monitor in Sidekiq**:
+```ruby
+# config/sidekiq.yml
+:queues:
+ - default
+ - mailers
+ - webhooks
+ - pdf
+ - analytics # New queue
+```
+
+---
+
+#### 1.8.8 Adding Custom Validations
+
+**Current**: Standard Rails validations
+
+**Custom Validation Pattern:**
+
+1. **Create Validator**:
+```ruby
+# app/validators/flodoc/sponsor_email_validator.rb
+class Flodoc::SponsorEmailValidator < ActiveModel::Validator
+ def validate(record)
+ unless record.email.end_with?('@company.com')
+ record.errors.add(:email, 'must be a company email')
+ end
+ end
+end
+```
+
+2. **Use in Model**:
+```ruby
+# app/models/flodoc/submitter.rb
+class Flodoc::Submitter < ApplicationRecord
+ validates_with Flodoc::SponsorEmailValidator, if: :sponsor?
+end
+```
+
+---
+
+#### 1.8.9 Database Extension Patterns
+
+**Adding New Tables:**
+
+1. **Migration**:
+```ruby
+# db/migrate/20260114120000_create_flodoc_custom_data.rb
+class CreateFlodocCustomData < ActiveRecord::Migration[7.0]
+ def change
+ create_table :flodoc_custom_data do |t|
+ t.references :cohort, null: false, foreign_key: true
+ t.jsonb :data
+ t.timestamps
+ end
+
+ add_index :flodoc_custom_data, [:cohort_id, :created_at]
+ end
+end
+```
+
+2. **Model**:
+```ruby
+# app/models/flodoc/custom_datum.rb
+class Flodoc::CustomDatum < ApplicationRecord
+ belongs_to :cohort
+ validates :data, presence: true
+end
+```
+
+---
+
+#### 1.8.10 Event System Extension
+
+**Current**: SubmissionEvents for audit trail
+
+**Adding Custom Events:**
+
+1. **Define Event Types**:
+```ruby
+# app/models/flodoc/event_type.rb
+class Flodoc::EventType < ApplicationRecord
+ TYPES = %w[
+ cohort_created
+ cohort_completed
+ submitter_signed
+ sponsor_invited
+ document_downloaded
+ custom_alert_sent # New event
+ ].freeze
+end
+```
+
+2. **Track Custom Events**:
+```ruby
+# app/services/flodoc/event_tracker.rb
+module Flodoc
+ class EventTracker
+ def self.track(cohort, event_type, user, metadata = {})
+ Flodoc::SubmissionEvent.create!(
+ cohort: cohort,
+ event_type: event_type,
+ user: user,
+ metadata: metadata
+ )
+ end
+ end
+end
+```
+
+3. **Query Events**:
+```ruby
+# In reports or analytics
+Flodoc::SubmissionEvent
+ .where(cohort_id: cohort.id)
+ .where(event_type: 'custom_alert_sent')
+ .where('created_at > ?', 30.days.ago)
+ .count
+```
+
+---
+
+#### 1.8.11 Integration Checklist
+
+When extending FloDoc, verify:
+
+- ✅ **Security**: New endpoints use JWT/auth tokens
+- ✅ **Multi-tenancy**: Check single-institution vs multi-institution
+- ✅ **Database**: Proper foreign keys and indexes
+- ✅ **Background Jobs**: Sidekiq queue exists
+- ✅ **API Versioning**: Use `/api/v1/flodoc/` namespace
+- ✅ **Vue Components**: Follow design system (FR28)
+- ✅ **Testing**: RSpec coverage for new code
+- ✅ **Rollback**: Migration can be reversed
+- ✅ **Documentation**: Update this extensibility guide
+
+---
+
+**Note**: This is optional documentation for future development. All current stories (1.1-8.0.1) are complete and ready for implementation.
---
@@ -1354,14 +1898,107 @@ end
##### Background
-Models must follow existing DocuSeal patterns:
-- Inherit from `ApplicationRecord`
-- Use `strip_attributes` for data cleaning
-- Include soft delete functionality
-- Define proper associations and validations
-- Follow naming conventions
+Models must follow existing DocuSeal patterns:
+- Inherit from `ApplicationRecord`
+- Use `strip_attributes` for data cleaning
+- Include soft delete functionality
+- Define proper associations and validations
+- Follow naming conventions
+
+##### Technical Implementation Notes
+
+**Feature Flag System:**
+
+```ruby
+# app/models/feature_flag.rb
+class FeatureFlag < ApplicationRecord
+ validates :name, uniqueness: true
+
+ def self.enabled?(feature_name)
+ flag = find_by(name: feature_name)
+ flag&.enabled || false
+ end
+
+ def self.enable!(feature_name)
+ find_or_create_by(name: feature_name).update(enabled: true)
+ end
+
+ def self.disable!(feature_name)
+ find_or_create_by(name: feature_name).update(enabled: false)
+ end
+end
+
+# app/controllers/concerns/feature_flag_check.rb
+module FeatureFlagCheck
+ extend ActiveSupport::Concern
+
+ def require_feature(feature_name)
+ unless FeatureFlag.enabled?(feature_name)
+ render json: { error: "Feature not available" }, status: 403
+ end
+ end
+end
+
+# Usage in FloDoc controllers
+class Flodoc::CohortsController < ApplicationController
+ before_action :require_feature(:flodoc_cohorts)
+
+ # ...
+end
+```
+
+**Database Migration for Feature Flags:**
+```ruby
+# db/migrate/20250113000001_create_feature_flags.rb
+class CreateFeatureFlags < ActiveRecord::Migration[7.0]
+ def change
+ create_table :feature_flags do |t|
+ t.string :name, null: false, index: { unique: true }
+ t.boolean :enabled, default: false
+ t.text :description
+
+ t.timestamps
+ end
+
+ # Seed default flags
+ reversible do |dir|
+ dir.up do
+ FeatureFlag.create!(name: 'flodoc_cohorts', enabled: false, description: '3-portal cohort management')
+ FeatureFlag.create!(name: 'flodoc_portals', enabled: false, description: 'Student/Sponsor portals')
+ end
+ end
+ end
+end
+```
+
+**Admin UI for Feature Flags:**
+```vue
+
+
+
+
Feature Flags
+
+ {{ flag.description }}
+
+
+
+
+
+
+```
**Model Structure:**
@@ -1520,22 +2157,29 @@ end
4. ✅ All scopes defined
5. ✅ State machine logic correct (if used)
6. ✅ Model methods work as specified
+7. ✅ FeatureFlag model created with enabled?, enable!, disable! methods
+8. ✅ FeatureFlagCheck concern implemented
+9. ✅ Default flags seeded (flodoc_cohorts, flodoc_portals)
+10. ✅ All FloDoc routes protected by feature flags
**Integration:**
1. ✅ IV1: Models don't break existing DocuSeal models
2. ✅ IV2: Associations work with existing tables (templates, submissions)
3. ✅ IV3: Query performance acceptable with 1000+ records
+4. ✅ Feature flags integrate with existing authentication
**Security:**
1. ✅ No mass assignment vulnerabilities
2. ✅ Proper attribute whitelisting
3. ✅ Email validation on all email fields
+4. ✅ Feature flags can disable FloDoc instantly
**Quality:**
1. ✅ Follow existing code style (RuboCop compliant)
2. ✅ All methods have YARD comments
3. ✅ Test coverage > 80%
4. ✅ No N+1 query issues
+5. ✅ Feature flag tests included
##### Integration Verification (IV1-3)
@@ -1556,6 +2200,15 @@ end
- Verify that queries with 1000 cohorts perform in < 100ms
- Verify that state machine transitions are fast
+**IV4: Feature Flag Integration Verification**
+- Verify that `FeatureFlag.enabled?(:flodoc_cohorts)` returns correct boolean
+- Verify that `FeatureFlag.enable!('flodoc_cohorts')` sets flag to true
+- Verify that `FeatureFlag.disable!('flodoc_cohorts')` sets flag to false
+- Verify that `require_feature(:flodoc_cohorts)` blocks access when disabled
+- Verify that `require_feature(:flodoc_cohorts)` allows access when enabled
+- Verify that feature flag UI displays all flags correctly
+- Verify that admin can toggle flags via UI
+
##### Test Requirements
**Model Specs:**
@@ -1608,6 +2261,93 @@ FactoryBot.define do
end
```
+**Feature Flag Specs:**
+```ruby
+# spec/models/feature_flag_spec.rb
+describe FeatureFlag do
+ describe 'validations' do
+ it { should validate_uniqueness_of(:name) }
+ end
+
+ describe '.enabled?' do
+ it 'returns true when flag is enabled' do
+ FeatureFlag.create!(name: 'test_feature', enabled: true)
+ expect(FeatureFlag.enabled?(:test_feature)).to be true
+ end
+
+ it 'returns false when flag is disabled' do
+ FeatureFlag.create!(name: 'test_feature', enabled: false)
+ expect(FeatureFlag.enabled?(:test_feature)).to be false
+ end
+
+ it 'returns false when flag does not exist' do
+ expect(FeatureFlag.enabled?(:nonexistent)).to be false
+ end
+ end
+
+ describe '.enable!' do
+ it 'creates and enables a flag' do
+ FeatureFlag.enable!(:new_feature)
+ flag = FeatureFlag.find_by(name: 'new_feature')
+ expect(flag.enabled).to be true
+ end
+ end
+
+ describe '.disable!' do
+ it 'creates and disables a flag' do
+ FeatureFlag.disable!(:new_feature)
+ flag = FeatureFlag.find_by(name: 'new_feature')
+ expect(flag.enabled).to be false
+ end
+ end
+end
+
+# spec/concerns/feature_flag_check_spec.rb
+describe FeatureFlagCheck do
+ controller(ApplicationController) do
+ include FeatureFlagCheck
+ before_action :require_feature(:test_feature)
+
+ def index
+ render json: { success: true }
+ end
+ end
+
+ it 'allows access when feature is enabled' do
+ FeatureFlag.enable!(:test_feature)
+ get :index
+ expect(response).to have_http_status(:ok)
+ end
+
+ it 'blocks access when feature is disabled' do
+ FeatureFlag.disable!(:test_feature)
+ get :index
+ expect(response).to have_http_status(:forbidden)
+ end
+end
+```
+
+**Integration Specs:**
+```ruby
+# spec/requests/flodoc/cohorts_spec.rb
+describe 'FloDoc Cohorts', type: :request do
+ before do
+ FeatureFlag.enable!(:flodoc_cohorts)
+ end
+
+ it 'allows access when feature flag is enabled' do
+ get '/flodoc/cohorts'
+ expect(response).to have_http_status(:ok)
+ end
+
+ it 'blocks access when feature flag is disabled' do
+ FeatureFlag.disable!(:flodoc_cohorts)
+ get '/flodoc/cohorts'
+ expect(response).to have_http_status(:forbidden)
+ end
+end
+```
+
##### Rollback Procedure
**If models cause issues:**
@@ -1632,6 +2372,15 @@ end
- Comprehensive test coverage
- Staging environment testing
+##### Success Metrics
+
+- **Feature Flag Accuracy**: 100% of flag checks return correct state
+- **Toggle Success Rate**: 99.9% of enable/disable operations succeed
+- **Access Control**: 0 unauthorized access when flag disabled
+- **UI Responsiveness**: Feature flag UI loads in <500ms
+- **Test Coverage**: 100% of feature flag code covered
+- **Zero Breaking Changes**: All existing tests pass
+
#### Story 1.3: Authorization Layer Extension
**Status**: Draft
@@ -6169,27 +6918,439 @@ Token format: JWT with 30-day expiration
#### Student Portal (Ad-hoc Tokens)
-Student tokens are delivered via email invitation:
+Student tokens are delivered via email invitation:
+```
+GET /api/v1/students/{token}/status
+POST /api/v1/students/{token}/submit
+```
+
+Token format: JWT with 30-day expiration
+```
+
+**Error Response Format:**
+
+```json
+{
+ "error": "Validation failed",
+ "errors": [
+ "Template must exist",
+ "Sponsor email can't be blank"
+ ]
+}
+```
+
+**Complete API Contract Examples:**
+
+---
+
+##### Endpoint: POST /api/v1/cohorts
+
+**Purpose:** Create a new cohort with sponsor and student requirements
+
+**Request Headers:**
+```
+Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
+Content-Type: application/json
+X-Request-ID: uuid-for-tracing
+```
+
+**Request Body:**
+```json
+{
+ "name": "Q1 2026 Learnership Program",
+ "template_id": 42,
+ "sponsor_email": "sponsor@company.co.za",
+ "program_type": "learnership",
+ "required_student_uploads": ["id_document", "matric_certificate", "cv"],
+ "cohort_metadata": {
+ "budget_code": "LDN-2026-001",
+ "start_date": "2026-02-01",
+ "end_date": "2026-07-31"
+ }
+}
+```
+
+**Success Response (201 Created):**
+```json
+{
+ "data": {
+ "id": 123,
+ "name": "Q1 2026 Learnership Program",
+ "template_id": 42,
+ "sponsor_email": "sponsor@company.co.za",
+ "program_type": "learnership",
+ "status": "draft",
+ "required_student_uploads": ["id_document", "matric_certificate", "cv"],
+ "created_at": "2026-01-14T10:30:00Z",
+ "updated_at": "2026-01-14T10:30:00Z"
+ },
+ "message": "Cohort created successfully"
+}
+```
+
+**Error Responses:**
+
+*400 Bad Request - Invalid JSON:*
+```json
+{
+ "error": "Invalid JSON format",
+ "details": "Unexpected token '}' at position 45"
+}
+```
+
+*401 Unauthorized - Missing/Invalid Token:*
+```json
+{
+ "error": "Authentication required",
+ "message": "Bearer token missing or invalid"
+}
+```
+
+*403 Forbidden - Insufficient Permissions:*
+```json
+{
+ "error": "Access denied",
+ "message": "User does not have permission to create cohorts"
+}
+```
+
+*404 Not Found - Template Doesn't Exist:*
+```json
+{
+ "error": "Template not found",
+ "message": "Template with ID 42 does not exist"
+}
+```
+
+*422 Unprocessable Entity - Validation Failed:*
+```json
+{
+ "error": "Validation failed",
+ "errors": [
+ "Name can't be blank",
+ "Sponsor email is invalid",
+ "Program type must be one of: learnership, internship, candidacy"
+ ],
+ "details": {
+ "sponsor_email": "must be a valid email address"
+ }
+}
+```
+
+---
+
+##### Endpoint: GET /api/v1/cohorts
+
+**Purpose:** List all cohorts with pagination and filtering
+
+**Request Headers:**
+```
+Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
+Accept: application/json
+```
+
+**Query Parameters:**
+```
+GET /api/v1/cohorts?page=1&per_page=20&status=draft&program_type=learnership&search=Q1
+```
+
+**Success Response (200 OK):**
+```json
+{
+ "data": [
+ {
+ "id": 123,
+ "name": "Q1 2026 Learnership Program",
+ "program_type": "learnership",
+ "status": "draft",
+ "sponsor_email": "sponsor@company.co.za",
+ "student_count": 15,
+ "completed_count": 0,
+ "created_at": "2026-01-14T10:30:00Z"
+ },
+ {
+ "id": 122,
+ "name": "Q4 2025 Internship Program",
+ "program_type": "internship",
+ "status": "completed",
+ "sponsor_email": "hr@company.co.za",
+ "student_count": 25,
+ "completed_count": 25,
+ "created_at": "2025-10-01T09:00:00Z"
+ }
+ ],
+ "meta": {
+ "pagination": {
+ "current_page": 1,
+ "per_page": 20,
+ "total_pages": 3,
+ "total_entries": 45
+ },
+ "filters": {
+ "status": "draft",
+ "program_type": "learnership",
+ "search": "Q1"
+ }
+ }
+}
+```
+
+**Error Responses:**
+
+*429 Too Many Requests - Rate Limit Exceeded:*
+```json
+{
+ "error": "Rate limit exceeded",
+ "message": "100 requests per minute limit reached",
+ "retry_after": 45
+}
+```
+
+---
+
+##### Endpoint: POST /api/v1/cohorts/{id}/start_signing
+
+**Purpose:** Transition cohort from draft to TP signing phase
+
+**Request Headers:**
+```
+Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
+Content-Type: application/json
+```
+
+**Request Body:**
+```json
+{
+ "notify_tp": true,
+ "message": "Please review and sign the cohort agreement"
+}
+```
+
+**Success Response (200 OK):**
+```json
+{
+ "data": {
+ "id": 123,
+ "status": "tp_signing",
+ "tp_signed_at": "2026-01-14T11:00:00Z",
+ "next_state": "student_enrollment"
+ },
+ "message": "Cohort moved to TP signing phase"
+}
+```
+
+**Error Responses:**
+
+*422 Unprocessable Entity - Invalid State Transition:*
+```json
+{
+ "error": "Invalid state transition",
+ "message": "Cannot transition from 'completed' to 'tp_signing'",
+ "allowed_transitions": ["draft -> tp_signing", "tp_signing -> student_enrollment"]
+}
+```
+
+*409 Conflict - Already Signed:*
+```json
+{
+ "error": "Already signed",
+ "message": "TP has already signed this cohort"
+}
+```
+
+---
+
+##### Endpoint: GET /api/v1/sponsor/{token}/dashboard
+
+**Purpose:** Sponsor dashboard view (ad-hoc authentication)
+
+**Request Headers:**
+```
+Accept: application/json
+```
+
+**Path Parameters:**
+- `token`: Ad-hoc JWT token sent via email
+
+**Success Response (200 OK):**
+```json
+{
+ "data": {
+ "cohort": {
+ "id": 123,
+ "name": "Q1 2026 Learnership Program",
+ "program_type": "learnership",
+ "tp_signed_at": "2026-01-14T11:00:00Z"
+ },
+ "students": [
+ {
+ "email": "student1@example.com",
+ "status": "complete",
+ "completed_at": "2026-01-14T12:00:00Z",
+ "document_url": "/api/v1/submissions/456/document"
+ },
+ {
+ "email": "student2@example.com",
+ "status": "in_progress",
+ "last_activity": "2026-01-14T12:30:00Z"
+ }
+ ],
+ "summary": {
+ "total_students": 15,
+ "completed": 12,
+ "pending": 3,
+ "completion_rate": "80%"
+ },
+ "actions": {
+ "can_review": true,
+ "can_finalize": false,
+ "can_remind": true
+ }
+ },
+ "token_expiry": "2026-02-13T10:30:00Z"
+}
+```
+
+**Error Responses:**
+
+*401 Unauthorized - Invalid Token:*
+```json
+{
+ "error": "Invalid token",
+ "message": "Sponsor token expired or invalid",
+ "renewal_url": "/api/v1/sponsor/renew?email=sponsor@company.co.za"
+}
+```
+
+*403 Forbidden - Access Denied:*
+```json
+{
+ "error": "Access denied",
+ "message": "Cohort not ready for sponsor review yet"
+}
+```
+
+---
+
+##### Endpoint: POST /api/v1/students/{token}/submit
+
+**Purpose:** Student submits their completed document
+
+**Request Headers:**
+```
+Content-Type: application/json
+```
+
+**Request Body:**
+```json
+{
+ "values": {
+ "full_name": "John Doe",
+ "id_number": "9001015000081",
+ "signature": "data:image/png;base64,iVBORw0KGgo...",
+ "declaration": true,
+ "upload_url": "https://storage.example.com/uploads/john_doe_cv.pdf"
+ }
+}
+```
+
+**Success Response (200 OK):**
+```json
+{
+ "data": {
+ "submission_id": 456,
+ "status": "completed",
+ "completed_at": "2026-01-14T13:00:00Z",
+ "document_url": "/api/v1/submissions/456/final-document"
+ },
+ "message": "Document submitted successfully"
+}
+```
+
+**Error Responses:**
+
+*400 Bad Request - Missing Required Fields:*
+```json
+{
+ "error": "Missing required fields",
+ "errors": [
+ "signature is required",
+ "id_number must be 13 digits"
+ ]
+}
+```
+
+*422 Unprocessable Entity - Invalid Data:*
+```json
+{
+ "error": "Validation failed",
+ "errors": [
+ "ID number format invalid",
+ "Signature must be a valid image"
+ ],
+ "invalid_fields": {
+ "id_number": "Must be 13 digits without spaces",
+ "signature": "Image must be PNG or JPG, max 2MB"
+ }
+}
+```
+
+---
+
+##### Endpoint: POST /api/v1/webhooks
+
+**Purpose:** Webhook event delivery (internal system)
+
+**Request Headers:**
```
-GET /api/v1/students/{token}/status
-POST /api/v1/students/{token}/submit
+Content-Type: application/json
+X-Signature: sha256=...
+X-Event-Type: submission.completed
```
-Token format: JWT with 30-day expiration
+**Request Body:**
+```json
+{
+ "event": "submission.completed",
+ "timestamp": "2026-01-14T13:00:00Z",
+ "data": {
+ "submission_id": 456,
+ "cohort_id": 123,
+ "student_email": "student1@example.com",
+ "document_url": "https://api.example.com/submissions/456/document"
+ }
+}
```
-**Error Response Format:**
+**Success Response (200 OK):**
+```json
+{
+ "status": "received",
+ "message": "Event processed successfully"
+}
+```
+
+**Error Responses:**
+*401 Unauthorized - Invalid Signature:*
```json
{
- "error": "Validation failed",
- "errors": [
- "Template must exist",
- "Sponsor email can't be blank"
- ]
+ "error": "Invalid signature",
+ "message": "Webhook signature verification failed"
+}
+```
+
+*500 Internal Server Error:*
+```json
+{
+ "error": "Webhook delivery failed",
+ "message": "Max retry attempts exceeded",
+ "retry_count": 3
}
```
+---
+
**Rate Limiting:**
```ruby
@@ -6233,38 +7394,61 @@ end
1. ✅ OpenAPI/Swagger spec for all endpoints
2. ✅ Static documentation in /docs/api
3. ✅ Versioning strategy documented
-4. ✅ Authentication methods documented
-5. ✅ Error response format documented
-6. ✅ Rate limiting implemented and documented
-7. ✅ Code examples provided
+4. ✅ Authentication methods documented (JWT + ad-hoc tokens)
+5. ✅ Error response format documented with all error codes
+6. ✅ Rate limiting implemented and documented (100 req/min)
+7. ✅ Code examples provided for all 6 core endpoints
8. ✅ Change log maintained
+9. ✅ Complete request/response examples for POST /cohorts
+10. ✅ Complete request/response examples for GET /cohorts
+11. ✅ Complete request/response examples for POST /cohorts/{id}/start_signing
+12. ✅ Complete request/response examples for GET /sponsor/{token}/dashboard
+13. ✅ Complete request/response examples for POST /students/{token}/submit
+14. ✅ Complete request/response examples for POST /webhooks
+15. ✅ All error scenarios documented (400, 401, 403, 404, 422, 429, 500)
**Quality:**
1. ✅ Documentation is comprehensive
2. ✅ Examples are runnable/verifiable
3. ✅ Coverage of all 11+ endpoints
4. ✅ Clear migration path for API versions
+5. ✅ All HTTP status codes documented
+6. ✅ All request headers documented
+7. ✅ All response fields explained
+8. ✅ Ad-hoc token flow clearly documented
**Integration:**
1. ✅ IV1: Documentation matches actual implementation
2. ✅ IV2: Examples work without modification
3. ✅ IV3: Static docs don't affect app performance
+4. ✅ IV4: All documented endpoints exist in routes
-##### Integration Verification (IV1-3)
+##### Integration Verification (IV1-4)
**IV1: Documentation Accuracy**
-- Verify all documented endpoints exist
-- Verify request/response schemas match
-- Verify examples work with real API
+- Verify all documented endpoints exist in routes
+- Verify request/response schemas match actual implementation
+- Verify examples work with real API calls
+- Verify all error codes are correct
**IV2: Readability**
- Verify docs are clear and understandable
-- Verify examples are helpful
+- Verify examples are helpful and complete
- Verify structure is logical
+- Verify ad-hoc token flow is explained clearly
**IV3: Impact**
- Verify docs don't slow down app
-- Verify-generated docs are up-to-date
+- Verify generated docs are up-to-date
+- Verify static docs load quickly
+
+**IV4: API Contract Completeness**
+- Verify POST /cohorts examples match actual request/response
+- Verify GET /cohorts pagination works as documented
+- Verify state transition endpoints work as specified
+- Verify sponsor/student token authentication works
+- Verify webhook delivery matches documentation
+- Verify all headers and status codes are correct
##### Test Requirements
@@ -6319,6 +7503,15 @@ end
- Automate swagger generation from tests
- Review docs before releases
+##### Success Metrics
+
+- **Documentation Coverage**: 100% of endpoints documented with examples
+- **Example Accuracy**: 100% of examples work without modification
+- **Error Code Coverage**: All 7 error types documented (400, 401, 403, 404, 422, 429, 500)
+- **Endpoint Coverage**: All 11+ API endpoints fully documented
+- **Readability Score**: Documentation passes clarity review
+- **Version Clarity**: Migration path between versions is clear
+
---
### 6.4 Phase 4: Frontend - TP Portal
@@ -25031,92 +26224,423 @@ curl -s http://localhost:8080/JSON/spider/action/scan/ \
# Wait for scan
sleep 60
-# Get alerts
-curl -s http://localhost:8080/JSON/core/view/alerts/ \
- -d "baseurl=http://localhost:3000" > zap_results.json
+# Get alerts
+curl -s http://localhost:8080/JSON/core/view/alerts/ \
+ -d "baseurl=http://localhost:3000" > zap_results.json
+
+# Generate report
+zap.sh -cmd -quickurl http://localhost:3000 -quickout zap_report.html
+
+echo "Scan complete. Results in zap_results.json and zap_report.html"
+
+# Kill ZAP
+pkill -f zap.sh
+```
+
+**Brakeman Scan:**
+```bash
+#!/bin/bash
+# script/security_audit.sh
+
+echo "Running Brakeman Security Audit..."
+
+# Run Brakeman
+bundle exec brakeman -o brakeman.json -o brakeman.html
+
+# Run Bundler Audit
+bundle exec bundle-audit check --update
+
+# Check for outdated gems with known vulnerabilities
+bundle exec gem outdated --filter=security
+
+echo "Security audit complete."
+```
+
+##### Rollback Procedure
+
+**If authentication vulnerabilities found:**
+1. Immediately disable affected endpoints
+2. Rotate all JWT secrets
+3. Invalidate all active tokens
+4. Force password reset for affected users
+5. Implement proper fix
+6. Re-run security tests
+7. Monitor for exploitation attempts
+
+**If authorization bypass discovered:**
+1. Disable affected portal/API
+2. Review all ability definitions
+3. Add missing authorization checks
+4. Test all access patterns
+5. Deploy fix with emergency patch
+6. Audit logs for exploitation
+
+**If data breach detected:**
+1. Immediately isolate affected systems
+2. Preserve logs and evidence
+3. Notify affected parties (GDPR requirement)
+4. Rotate all encryption keys
+5. Force re-authentication
+6. Implement additional monitoring
+7. Conduct forensic analysis
+
+**If injection vulnerability found:**
+1. Disable affected input fields
+2. Implement parameterized queries
+3. Add input validation
+4. Sanitize existing data
+5. Re-run injection tests
+6. Monitor for attacks
+
+**If CSRF vulnerability found:**
+1. Enable CSRF protection immediately
+2. Force logout for all users
+3. Require re-authentication
+4. Verify all forms have CSRF tokens
+5. Re-run CSRF tests
+
+**Data Safety:**
+- All security tests use isolated test environment
+- No production data used in security testing
+- Security findings documented, not exploited
+- Emergency patches follow standard deployment process
+- All changes require security review
+
+##### Acceptance Criteria
+
+**Functional:**
+1. ✅ OWASP Top 10 Verification
+ - SQL injection prevention tested
+ - XSS protection verified
+ - CSRF tokens validated
+ - Authentication bypass attempts blocked
+ - Security misconfigurations identified
+
+2. ✅ Authentication Flow Security
+ - Ad-hoc token generation security verified
+ - Token expiration (24h) enforced
+ - JWT secret strength validated (min 256 bits)
+ - Token renewal flow secure
+ - Token reuse prevention working
+ - Cross-portal access blocked
+
+3. ✅ Data Privacy (POPIA Compliance)
+ - Personal data encrypted at rest
+ - Right to deletion implemented
+ - Data retention policies defined (7 years for legal docs)
+ - Student data isolation verified
+ - Audit trail integrity maintained
+
+4. ✅ Penetration Testing Scope
+ - API endpoint fuzzing completed
+ - Token manipulation attempts blocked
+ - Role escalation testing passed
+ - Bulk operation rate limiting verified
+ - Webhook signature verification working
+ - Open redirect prevention validated
+
+5. ✅ Security Headers
+ - Content-Security-Policy configured
+ - X-Frame-Options set to DENY
+ - HSTS enabled
+ - CORS policies restricted
+ - X-Content-Type-Options set
+ - X-XSS-Protection enabled
+
+**Integration:**
+1. ✅ Security tests integrate with CI/CD pipeline
+2. ✅ Audit results logged to SecurityEvent model
+3. ✅ Brakeman runs on every commit
+4. ✅ Security scan reports generated
+
+**Security:**
+1. ✅ No critical vulnerabilities found
+2. ✅ All findings documented with remediation
+3. ✅ Security audit report approved by PO
+4. ✅ Penetration test summary provided
+
+**Quality:**
+1. ✅ Security audit report generated
+2. ✅ Penetration test summary provided
+3. ✅ All test cases passing
+4. ✅ Documentation complete
+
+##### Integration Verification (IV1-4)
+
+**IV1: API Integration**
+- Security tests call `/api/v1/flodoc/*` endpoints
+- Verify token validation on all routes
+- Test rate limiting on auth endpoints
+- Validate webhook signature verification
+
+**IV2: Pinia Store**
+- N/A (backend security focus)
+
+**IV3: Getters**
+- N/A (backend security focus)
+
+**IV4: Token Routing**
+- Ad-hoc token security verified
+- JWT validation on all protected routes
+- Token expiration enforced
+- Token renewal flow tested
+
+##### Rollback Procedure
+
+**If security audit fails (critical vulnerabilities found):**
+1. **Stop deployment immediately** - Do not proceed to production
+2. **Document all critical findings** in security issue tracker
+3. **Prioritize remediation** by severity (Critical > High > Medium)
+4. **Fix critical issues first**:
+ - Authentication bypasses
+ - Data exposure vulnerabilities
+ - SQL injection flaws
+5. **Re-run specific tests** for fixed vulnerabilities
+6. **Full re-audit required** before proceeding
+7. **Get security sign-off** from external auditor if needed
+
+**If security audit reveals data breach risk:**
+1. **Immediately disable affected endpoints**
+2. **Force logout all active sessions**
+3. **Rotate all JWT secrets**
+4. **Notify stakeholders** (PO, legal, compliance)
+5. **Conduct forensic analysis**
+6. **Implement additional monitoring**
+7. **Document incident for compliance**
+
+**If POPIA compliance issues found:**
+1. **Pause all data collection**
+2. **Review data retention policies**
+3. **Implement right-to-deletion mechanism**
+4. **Update privacy documentation**
+5. **Get legal review**
+6. **Re-audit compliance**
+
+**Data Safety:**
+- All security tests use isolated test environment
+- No production data at risk during testing
+- Security findings documented, not exploited
+- All changes require security review before merge
+- Emergency patches follow standard deployment process
+
+##### Test Requirements
+
+**Component Specs:**
+```ruby
+# spec/security/authentication_spec.rb
+require 'rails_helper'
+
+RSpec.describe 'Authentication Security', type: :security do
+ describe 'JWT Token Security' do
+ it 'prevents token tampering' do
+ original_token = generate_valid_token
+ tampered_token = original_token[0..-5] + 'X' * 4
+
+ get '/api/v1/tp/cohorts',
+ headers: { 'Authorization' => "Bearer #{tampered_token}" }
+
+ expect(response).to have_http_status(:unauthorized)
+ end
+
+ it 'enforces token expiration' do
+ expired_token = generate_expired_token
+
+ get '/api/v1/tp/cohorts',
+ headers: { 'Authorization' => "Bearer #{expired_token}" }
+
+ expect(response).to have_http_status(:unauthorized)
+ expect(JSON.parse(response.body)['error']).to include('expired')
+ end
+
+ it 'prevents token reuse after renewal' do
+ token = generate_valid_token
+ old_token = token.dup
+
+ # Renew token
+ post '/api/v1/auth/renew',
+ headers: { 'Authorization' => "Bearer #{old_token}" }
+
+ expect(response).to have_http_status(:success)
+
+ # Old token should be invalid
+ get '/api/v1/tp/cohorts',
+ headers: { 'Authorization' => "Bearer #{old_token}" }
+
+ expect(response).to have_http_status(:unauthorized)
+ end
+ end
+
+ describe 'POPIA Compliance' do
+ it 'encrypts personal data at rest' do
+ cohort = create(:cohort, student_name: 'John Doe', student_email: 'john@example.com')
+
+ # Verify database doesn't contain plaintext
+ raw_cohort = Cohort.find(cohort.id)
+ expect(raw_cohort.encrypted_student_name).not_to eq('John Doe')
+ end
+
+ it 'implements right to deletion' do
+ student = create(:student)
+
+ expect {
+ GDPRCompliance.delete_user_data(student.id)
+ }.to change { Student.where(id: student.id).count }.by(0) # Anonymized, not deleted
+ .and change { student.reload.email }.to('anonymized@local')
+ end
+
+ it 'enforces data retention policies' do
+ old_cohort = create(:cohort, created_at: 7.years.ago)
+
+ expect {
+ Cohort.enforce_retention_policy!
+ }.to change(Cohort, :count).by(-1)
+ end
+ end
+
+ describe 'OWASP Top 10 Coverage' do
+ it 'prevents SQL injection' do
+ malicious_params = {
+ name: "Cohort'; DROP TABLE cohorts; --",
+ student_emails: ["test@example.com'; DROP TABLE users; --"]
+ }
+
+ post '/api/v1/tp/cohorts',
+ params: malicious_params,
+ headers: { 'Authorization' => "Bearer #{tp_token}" }
+
+ expect(response).to have_http_status(:unprocessable_entity)
+ expect(Cohort.count).to eq(0)
+ end
+
+ it 'prevents XSS attacks' do
+ post '/api/v1/tp/cohorts',
+ params: {
+ name: "",
+ student_emails: ["test@example.com"]
+ },
+ headers: { 'Authorization' => "Bearer #{tp_token}" }
+
+ expect(response).to have_http_status(:unprocessable_entity)
+ end
+
+ it 'validates file uploads' do
+ # Test malicious file upload
+ post '/api/v1/student/documents',
+ params: {
+ file: fixture_file_upload('malicious.exe', 'application/x-msdownload')
+ },
+ headers: { 'Authorization' => "Bearer #{student_token}" }
+
+ expect(response).to have_http_status(:unprocessable_entity)
+ end
+ end
+
+ describe 'Penetration Testing Scenarios' do
+ it 'prevents horizontal privilege escalation' do
+ student_a_token = generate_student_token(cohort, student_a)
+ student_b_document = create(:submission, cohort: cohort, student: student_b)
+
+ get "/api/v1/student/documents/#{student_b_document.id}",
+ headers: { 'Authorization' => "Bearer #{student_a_token}" }
+
+ expect(response).to have_http_status(:not_found)
+ end
+
+ it 'prevents vertical privilege escalation' do
+ student_token = generate_student_token
+
+ post '/api/v1/tp/cohorts',
+ params: { name: 'Hacked Cohort' },
+ headers: { 'Authorization' => "Bearer #{student_token}" }
+
+ expect(response).to have_http_status(:forbidden)
+ end
+
+ it 'prevents token brute force attacks' do
+ 100.times do
+ get '/api/v1/tp/cohorts',
+ headers: { 'Authorization' => "Bearer #{invalid_token}" }
+ end
+
+ expect(response).to have_http_status(:too_many_requests)
+ end
+ end
-# Generate report
-zap.sh -cmd -quickurl http://localhost:3000 -quickout zap_report.html
+ describe 'Security Headers' do
+ it 'enforces HTTPS' do
+ get 'http://localhost:3000/api/v1/tp/cohorts',
+ headers: { 'Authorization' => "Bearer #{tp_token}" }
-echo "Scan complete. Results in zap_results.json and zap_report.html"
+ expect([301, 302, 400]).to include(response.status)
+ end
-# Kill ZAP
-pkill -f zap.sh
-```
+ it 'has secure headers' do
+ get '/api/v1/tp/cohorts',
+ headers: { 'Authorization' => "Bearer #{tp_token}" }
-**Brakeman Scan:**
-```bash
-#!/bin/bash
-# script/security_audit.sh
+ expect(response.headers['Content-Security-Policy']).to be_present
+ expect(response.headers['X-Frame-Options']).to eq('DENY')
+ expect(response.headers['Strict-Transport-Security']).to be_present
+ end
+ end
-echo "Running Brakeman Security Audit..."
+ describe 'Webhook Security' do
+ it 'verifies webhook signatures' do
+ payload = { event: 'submission.completed', id: 123 }
+ signature = generate_webhook_signature(payload)
-# Run Brakeman
-bundle exec brakeman -o brakeman.json -o brakeman.html
+ post '/api/v1/webhooks/docuseal',
+ params: payload,
+ headers: { 'X-DocuSeal-Signature' => signature }
-# Run Bundler Audit
-bundle exec bundle-audit check --update
+ expect(response).to have_http_status(:success)
-# Check for outdated gems with known vulnerabilities
-bundle exec gem outdated --filter=security
+ # Invalid signature
+ post '/api/v1/webhooks/docuseal',
+ params: payload,
+ headers: { 'X-DocuSeal-Signature' => 'invalid' }
-echo "Security audit complete."
-```
+ expect(response).to have_http_status(:unauthorized)
+ end
-##### Rollback Procedure
+ it 'prevents replay attacks' do
+ payload = { event: 'submission.completed', id: 123, timestamp: Time.now.to_i }
+ signature = generate_webhook_signature(payload)
-**If authentication vulnerabilities found:**
-1. Immediately disable affected endpoints
-2. Rotate all JWT secrets
-3. Invalidate all active tokens
-4. Force password reset for affected users
-5. Implement proper fix
-6. Re-run security tests
-7. Monitor for exploitation attempts
+ # First request
+ post '/api/v1/webhooks/docuseal',
+ params: payload,
+ headers: { 'X-DocuSeal-Signature' => signature }
-**If authorization bypass discovered:**
-1. Disable affected portal/API
-2. Review all ability definitions
-3. Add missing authorization checks
-4. Test all access patterns
-5. Deploy fix with emergency patch
-6. Audit logs for exploitation
+ expect(response).to have_http_status(:success)
-**If data breach detected:**
-1. Immediately isolate affected systems
-2. Preserve logs and evidence
-3. Notify affected parties (GDPR requirement)
-4. Rotate all encryption keys
-5. Force re-authentication
-6. Implement additional monitoring
-7. Conduct forensic analysis
+ # Replay request
+ post '/api/v1/webhooks/docuseal',
+ params: payload,
+ headers: { 'X-DocuSeal-Signature' => signature }
-**If injection vulnerability found:**
-1. Disable affected input fields
-2. Implement parameterized queries
-3. Add input validation
-4. Sanitize existing data
-5. Re-run injection tests
-6. Monitor for attacks
+ expect(response).to have_http_status(:conflict)
+ end
+ end
+end
+```
-**If CSRF vulnerability found:**
-1. Enable CSRF protection immediately
-2. Force logout for all users
-3. Require re-authentication
-4. Verify all forms have CSRF tokens
-5. Re-run CSRF tests
+**Integration Tests:**
+- End-to-end security workflow tests
+- Token lifecycle tests (creation, renewal, expiration)
+- Role-based access control tests
+- Data encryption verification
+- Audit logging verification
-**Data Safety:**
-- All security tests use isolated test environment
-- No production data used in security testing
-- Security findings documented, not exploited
-- Emergency patches follow standard deployment process
-- All changes require security review
+**E2E Tests:**
+- Penetration simulation tests using OWASP ZAP
+- Complete user journey security validation
+- Rate limiting stress tests
+- Webhook security validation
##### Risk Assessment
-**High Risk** because:
-- Security vulnerabilities can lead to data breaches
+**High Risk because:**
- Document signing involves sensitive PII
- GDPR violations carry heavy fines
- Authentication bypass is critical
@@ -27269,3 +28793,325 @@ echo "System ready for management demo!"
- Bulk operations demonstrated clearly
- Cohort management workflow validated
- Approval to proceed to production infrastructure
+
+---
+
+#### Story 8.5: User Communication & Training Materials
+
+**Status**: Draft
+**Priority**: High (Blocking - Required Before Development)
+**Epic**: Phase 8 - Deployment & Documentation
+**Estimated Effort**: 2 days
+**Risk Level**: Medium
+
+##### User Story
+
+**As a** Training Provider (TP Admin),
+**I want** clear guidance on using FloDoc's 3-portal system,
+**So that** I can manage cohorts effectively without confusion.
+
+##### Background
+
+Existing DocuSeal users need to understand:
+- What changed (3-portal workflow)
+- How to use new features (cohort management)
+- Where to get help (support channels)
+- What's different (ad-hoc student/sponsor access)
+
+Without this communication, adoption will suffer and support will be overwhelmed. This story addresses PO Validation Issue #3 (User Communication & Training Plan Missing).
+
+**Key Deliverables:**
+1. Migration announcement for existing users
+2. TP Portal "Getting Started" guide
+3. Student Portal onboarding tutorial
+4. Sponsor Portal quick-start guide
+5. FAQ with 20 common questions
+6. Support contact process
+
+##### Technical Implementation Notes
+
+**Documentation Structure:**
+```
+docs/user/
+├── migration-announcement.md
+├── tp-portal-guide.md
+├── student-portal-tutorial.md
+├── sponsor-portal-guide.md
+└── faq.md
+```
+
+**Email Templates:**
+```ruby
+# app/views/mailers/user_announcement/
+├── migration_email.html.erb # Existing users
+├── welcome_floDoc.html.erb # New users
+└── feature_highlights.html.erb # Feature overview
+```
+
+**UI Help Integration:**
+```vue
+
+
+
+
+
FloDoc Quick Start
+
+
Create a cohort (5-step wizard)
+
Upload documents and map signatories
+
Sign as TP (auto-fills for all students)
+
Invite students via email
+
Review sponsor submissions
+
+
+
+
+
+
+
+```
+
+**Help Button Component:**
+```vue
+
+
+
+
+
+
+```
+
+**Error Help Mapping:**
+```typescript
+// app/javascript/shared/error-help.ts
+export const ERROR_HELP: Record = {
+ 'token_expired': {
+ message: 'Your access link has expired',
+ action: 'Request a new link from your training provider'
+ },
+ 'invalid_token': {
+ message: 'This link is invalid',
+ action: 'Contact your training provider'
+ },
+ 'cohort_not_found': {
+ message: 'Cohort not found',
+ action: 'Check your email for the correct link'
+ }
+}
+```
+
+##### Acceptance Criteria
+
+**Functional:**
+1. ✅ Migration announcement email sent to all existing DocuSeal users
+2. ✅ TP Portal "Getting Started" guide created (5 steps)
+3. ✅ Student Portal onboarding tutorial (3 steps, mobile-friendly)
+4. ✅ Sponsor Portal quick-start guide (bulk signing focus)
+5. ✅ FAQ document with 20 common questions
+6. ✅ Support contact process defined
+7. ✅ Help overlay on first login for TP Portal
+8. ✅ Help button accessible on all major screens
+9. ✅ Error messages link to contextual help
+
+**UI/UX:**
+1. ✅ Help buttons visible in all portals
+2. ✅ Tutorial tooltips on first login
+3. ✅ Mobile-responsive documentation
+4. ✅ Consistent help iconography
+
+**Integration:**
+1. ✅ Email templates integrate with existing Devise mailer
+2. ✅ Help content served via `/help` routes
+3. ✅ Error help displays in all portals
+
+**Security:**
+1. ✅ No sensitive data in documentation
+2. ✅ Token links in emails are single-use
+3. ✅ Help pages don't expose internal URLs
+
+**Quality:**
+1. ✅ All documentation reviewed by PO
+2. ✅ No spelling/grammar errors
+3. ✅ Consistent branding and tone
+4. ✅ Links verified and working
+
+##### Integration Verification (IV1-4)
+
+**IV1: API Integration**
+- Email sending uses existing Devise mailer infrastructure
+- Help content served via static pages or API endpoints
+- Error help API returns contextual guidance
+
+**IV2: Pinia Store**
+- Help state management for "show on first login"
+- `useHelpStore` with `showTutorial` state
+- `dismissTutorial()` action
+
+**IV3: Getters**
+- `showTutorial: boolean` - determines if help overlay shows
+- `currentHelpSection: string` - loads appropriate guide
+
+**IV4: Token Routing**
+- Email links use secure single-use tokens
+- Token validation before showing help content
+- Token expiration (24h) enforced
+
+##### Rollback Procedure
+
+**If communication fails:**
+1. Revert email templates to original
+2. Remove help overlays from portals
+3. Restore original DocuSeal documentation
+4. Notify users of rollback
+5. Investigate and fix issues
+
+**If documentation is inaccurate:**
+1. Update markdown files immediately
+2. Redeploy help content
+3. Send correction email if needed
+4. Track corrections in changelog
+
+**Data Safety:**
+- No database changes required
+- No production data at risk
+- Documentation can be updated independently
+
+##### Risk Assessment
+
+**MEDIUM because:**
+- User confusion could lead to support overload
+- Poor adoption affects project success
+- Requires coordination with support team
+- Documentation must be accurate
+
+**Specific Risks:**
+1. **Email Fatigue**: Too many emails annoy users
+ - **Mitigation**: Single well-crafted announcement, opt-out option
+
+2. **Documentation Overload**: Too much information
+ - **Mitigation**: Concise guides, progressive disclosure, video tutorials
+
+3. **Support Unprepared**: Team not ready for questions
+ - **Mitigation**: Support team training session before launch
+
+4. **Inaccurate Help**: Wrong information damages trust
+ - **Mitigation**: PO review, user testing, version tracking
+
+**Mitigation Strategies:**
+- Phased communication rollout
+- Clear, concise documentation (< 200 words per guide)
+- Support team training session
+- User feedback collection
+- Regular documentation updates
+
+##### Success Metrics
+
+**User Adoption:**
+- 80% user adoption rate within 30 days
+- <10 support tickets per week
+- Positive user feedback (>4/5 rating)
+- <5% rollback requests
+
+**Documentation Quality:**
+- 100% of links working
+- 0 spelling/grammar errors
+- User testing pass rate >90%
+- Support team confidence >80%
+
+**Communication Effectiveness:**
+- Email open rate >60%
+- Help button usage >30% of sessions
+- Tutorial completion rate >70%
+- FAQ page views >100/month
+
+---
+
+#### Story 8.6: In-App User Documentation & Help System
+
+**Status**: Draft (Deferred - Post-MVP)
+**Priority**: Medium
+**Epic**: Phase 8 - Deployment & Documentation
+**Estimated Effort**: 1.5 days
+**Risk Level**: Low
+
+##### User Story
+
+**As a** User (TP Admin, Student, or Sponsor),
+**I want** contextual help and documentation,
+**So that** I can solve problems without contacting support.
+
+##### Background
+
+Deferred to post-MVP per PO validation. This story adds in-app help system after core functionality is validated.
+
+**Note**: This story is deferred pending successful MVP validation.
+
+##### Acceptance Criteria (Deferred)
+
+**Functional:**
+1. ✅ Help button on every major screen
+2. ✅ Modal with contextual guides
+3. ✅ Error code explanations
+4. ✅ Searchable FAQ
+5. ✅ Keyboard shortcut reference
+
+**UI/UX:**
+1. ✅ Help accessible in 1 click
+2. ✅ Mobile-friendly help modals
+3. ✅ Consistent help iconography
+
+---
+
+#### Story 8.7: Knowledge Transfer & Operations Documentation
+
+**Status**: Draft (Deferred - Post-MVP)
+**Priority**: Medium
+**Epic**: Phase 8 - Deployment & Documentation
+**Estimated Effort**: 1 day
+**Risk Level**: Medium
+
+##### User Story
+
+**As a** Support/Operations Team,
+**I want** comprehensive runbooks and documentation,
+**So that** I can support FloDoc without ad-hoc knowledge transfer.
+
+##### Background
+
+Deferred to post-MVP per PO validation. This story creates operations documentation after system is proven.
+
+**Note**: This story is deferred pending successful MVP validation.
+
+##### Acceptance Criteria (Deferred)
+
+**Functional:**
+1. ✅ Operations runbook created
+2. ✅ Troubleshooting guide (10 common issues)
+3. ✅ Deployment procedure documented
+4. ✅ Incident response plan
+5. ✅ Code review checklist
+6. ✅ Support team training session held
+
+---
+
diff --git a/docs/prd/epic-1-3-portal-cohort-management-system.md b/docs/prd/epic-1-3-portal-cohort-management-system.md
deleted file mode 100644
index 845b9969..00000000
--- a/docs/prd/epic-1-3-portal-cohort-management-system.md
+++ /dev/null
@@ -1,193 +0,0 @@
-# Epic 1: 3-Portal Cohort Management System
-
-**Epic Goal**: Transform DocuSeal into a specialized 3-portal cohort management system that enables training institutions to manage complete document workflows from cohort creation through sponsor finalization.
-
-**Integration Requirements**:
-- Must integrate with existing DocuSeal form builder for agreement templates
-- Must use existing document storage and signing infrastructure
-- Must extend existing authentication and user management
-- Must maintain backward compatibility with all existing DocuSeal features
-
-## Story 1.1: Institution and Admin Management
-
-**As a** system administrator,
-**I want** to create and manage training institutions with multiple admin users (super and regular admins),
-**so that** private training institutions can manage their cohorts independently.
-
-**Acceptance Criteria**:
-1. Database schema for institutions and admin roles exists
-2. Super admins can create institutions and invite other admins
-3. Regular admins can manage cohorts within their institution
-4. Admins cannot access other institutions' data
-5. Role-based permissions are enforced at API and UI levels
-
-**Integration Verification**:
-1. **IV1**: Existing DocuSeal user authentication remains functional
-2. **IV2**: New role system doesn't conflict with existing DocuSeal user roles
-3. **IV3**: Performance impact on existing user operations is minimal
-
-## Story 1.2: Cohort Creation and Template Management
-
-**As an** admin,
-**I want** to create cohorts with program type selection, student count, sponsor email, and upload agreement templates,
-**so that** I can set up training programs with all necessary documentation.
-
-**Acceptance Criteria**:
-1. Cohort creation form captures all required fields
-2. Admins can upload main agreement template using DocuSeal form builder
-3. Admins can upload additional supporting document templates
-4. System validates template formats and requirements
-5. Cohort is saved with all associated templates and metadata
-
-**Integration Verification**:
-1. **IV1**: DocuSeal form builder integration works for template creation
-2. **IV2**: Existing document storage handles new template types
-3. **IV3**: Template associations don't break existing submission workflows
-
-## Story 1.3: Student Invitation and Enrollment
-
-**As an** admin,
-**I want** to generate invite links or send email invitations to students for cohort enrollment,
-**so that** students can access the student portal and begin their submission process.
-
-**Acceptance Criteria**:
-1. Admin can generate unique invite link for each student
-2. Admin can bulk send email invitations to all students
-3. Invite links are single-use and expire after enrollment
-4. Students can access student portal via invite without existing account
-5. Student enrollment creates cohort_enrollment record with "Waiting" state
-
-**Integration Verification**:
-1. **IV1**: Existing DocuSeal email system handles new invitation templates
-2. **IV2**: Authentication works for new users without breaking existing users
-3. **IV3**: Enrollment records link properly to existing user/submission infrastructure
-
-## Story 1.4: Admin Document Verification Workflow
-
-**As an** admin,
-**I want** to manually review and verify student-uploaded documents with ability to reject with reasons,
-**so that** I can ensure document compliance before sponsor review.
-
-**Acceptance Criteria**:
-1. Admin dashboard shows pending verifications across all cohorts
-2. Admin can view student-uploaded documents with preview
-3. Admin can approve or reject documents with required reason
-4. Rejection notifications sent to students with reason
-5. Audit trail captures all verification actions with timestamps
-
-**Integration Verification**:
-1. **IV1**: Document preview uses existing DocuSeal file rendering
-2. **IV2**: Notification system doesn't interfere with existing DocuSeal emails
-3. **IV3**: Audit trail storage doesn't impact existing document storage performance
-
-## Story 1.5: Student Portal - Document Upload and Agreement Completion
-
-**As a** student,
-**I want** to upload required documents, fill and sign the main agreement and supporting documents,
-**so that** I can complete my enrollment requirements.
-
-**Acceptance Criteria**:
-1. Student portal shows their cohort and required documents
-2. Students can upload matric, ID, disability docs, qualifications, certificates
-3. Students can fill and sign main agreement using DocuSeal form builder
-4. Students can fill and sign additional supporting documents
-5. System updates enrollment state from "Waiting" → "In Progress" → "Complete"
-6. Students can submit all documents when complete
-
-**Integration Verification**:
-1. **IV1**: DocuSeal form builder works seamlessly for student-facing forms
-2. **IV2**: File uploads use existing storage and validation
-3. **IV3**: State transitions don't conflict with existing submission states
-
-## Story 1.6: Sponsor Portal - Multi-Student Review and Signing
-
-**As a** sponsor,
-**I want** to review and sign agreements for all students in a cohort, with individual and bulk options,
-**so that** I can efficiently complete sponsor responsibilities.
-
-**Acceptance Criteria**:
-1. Sponsor portal shows cohort overview with all student statuses
-2. Sponsor can view individual student submissions and documents
-3. Sponsor can sign each student's agreements individually
-4. Sponsor can bulk sign all students at once
-5. Sponsor can submit all signatures to finalize cohort
-6. Sponsor portal only accessible after all students complete submissions
-
-**Integration Verification**:
-1. **IV1**: Sponsor authentication works without existing DocuSeal account
-2. **IV2**: Signing workflow uses existing DocuSeal signature infrastructure
-3. **IV3**: Bulk operations don't impact existing single-document signing performance
-
-## Story 1.7: Admin Finalization and Document Access
-
-**As an** admin,
-**I want** to finalize the cohort after sponsor completion and access all signed documents,
-**so that** I can complete the workflow and maintain records.
-
-**Acceptance Criteria**:
-1. Admin can finalize cohort after sponsor submission
-2. System generates complete document packages for each student
-3. Admin can download individual or bulk signed documents
-4. Finalized cohorts show completion status in dashboard
-5. Admin can access historical cohort data and reports
-
-**Integration Verification**:
-1. **IV1**: Document generation uses existing DocuSeal PDF processing
-2. **IV2**: Download functionality doesn't break existing document downloads
-3. **IV3**: Historical data access doesn't impact current cohort performance
-
-## Story 1.8: Notification and Reminder System
-
-**As a** system,
-**I want** to send automated notifications for all workflow events and reminders for incomplete actions,
-**so that** all parties stay informed and workflows complete efficiently.
-
-**Acceptance Criteria**:
-1. Cohort creation triggers admin notification
-2. Student invite sends email with portal access link
-3. Submission reminders sent after configurable delay
-4. State change notifications sent to relevant parties
-5. Sponsor access notification sent when all students complete
-6. Deadline reminders configurable per cohort
-
-**Integration Verification**:
-1. **IV1**: All notifications use existing DocuSeal email infrastructure
-2. **IV2**: Reminder scheduling doesn't impact Sidekiq job queue performance
-3. **IV3**: Email templates maintain existing DocuSeal branding and formatting
-
-## Story 1.9: Dashboard and Analytics
-
-**As an** admin,
-**I want** to see real-time dashboard showing cohort status, completion metrics, and analytics,
-**so that** I can monitor progress and identify bottlenecks.
-
-**Acceptance Criteria**:
-1. Dashboard shows all cohorts with completion percentages
-2. Real-time updates for student submission states
-3. Analytics on completion times, document types, verification rates
-4. Export functionality for reports (CSV, PDF)
-5. Role-based dashboard views (admin vs. sponsor vs. student)
-
-**Integration Verification**:
-1. **IV1**: Dashboard queries don't impact existing DocuSeal performance
-2. **IV2**: Analytics data collection doesn't interfere with document processing
-3. **IV3**: Export functionality uses existing DocuSeal reporting infrastructure
-
-## Story 1.10: State Management and Workflow Orchestration
-
-**As a** system,
-**I want** to manage complex state transitions and workflow orchestration across all three portals,
-**so that** the entire cohort workflow progresses correctly and no steps are skipped.
-
-**Acceptance Criteria**:
-1. State machine defined for all enrollment states (Waiting → In Progress → Complete)
-2. Workflow rules enforced: students can't submit until docs uploaded, sponsor can't access until all students complete, etc.
-3. State transitions are atomic and handle concurrent operations
-4. Rollback capabilities for incorrect state transitions
-5. State history audit trail for troubleshooting
-
-**Integration Verification**:
-1. **IV1**: State management doesn't conflict with existing DocuSeal submission states
-2. **IV2**: Workflow orchestration handles edge cases (student dropout, template changes, etc.)
-3. **IV3**: Performance remains acceptable with large cohorts and concurrent operations
-
diff --git a/docs/prd/epic-and-story-structure.md b/docs/prd/epic-and-story-structure.md
deleted file mode 100644
index c48096a0..00000000
--- a/docs/prd/epic-and-story-structure.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Epic and Story Structure
-
-## Epic Approach
-
-**Epic Structure Decision**: Single comprehensive epic with multiple user stories - This enhancement will be delivered as one cohesive epic because all stories serve the unified objective of enabling 3-portal cohort management. Stories build sequentially (Admin portal → Student portal → Sponsor portal → Analytics) and leverage shared infrastructure. Multiple epics were rejected due to integration gaps and coordination overhead.
-
----
diff --git a/docs/prd/index.md b/docs/prd/index.md
deleted file mode 100644
index 4dcbd3cf..00000000
--- a/docs/prd/index.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# FloDoc Brownfield Enhancement PRD
-
-## Table of Contents
-
-- [FloDoc Brownfield Enhancement PRD](#table-of-contents)
- - [Table of Contents](./table-of-contents.md)
- - [Intro Project Analysis and Context](./intro-project-analysis-and-context.md)
- - [SCOPE ASSESSMENT](./intro-project-analysis-and-context.md#scope-assessment)
- - [Existing Project Overview](./intro-project-analysis-and-context.md#existing-project-overview)
- - [Available Documentation Analysis](./intro-project-analysis-and-context.md#available-documentation-analysis)
- - [Enhancement Scope Definition](./intro-project-analysis-and-context.md#enhancement-scope-definition)
- - [Goals and Background Context](./intro-project-analysis-and-context.md#goals-and-background-context)
- - [Change Log](./intro-project-analysis-and-context.md#change-log)
- - [Requirements](./requirements.md)
- - [Functional Requirements](./requirements.md#functional-requirements)
- - [Non-Functional Requirements](./requirements.md#non-functional-requirements)
- - [Compatibility Requirements](./requirements.md#compatibility-requirements)
- - [Technical Constraints and Integration](./technical-constraints-and-integration.md)
- - [Existing Technology Stack](./technical-constraints-and-integration.md#existing-technology-stack)
- - [Integration Approach](./technical-constraints-and-integration.md#integration-approach)
- - [Code Organization and Standards](./technical-constraints-and-integration.md#code-organization-and-standards)
- - [Deployment and Operations](./technical-constraints-and-integration.md#deployment-and-operations)
- - [Risk Assessment and Mitigation](./technical-constraints-and-integration.md#risk-assessment-and-mitigation)
- - [Epic and Story Structure](./epic-and-story-structure.md)
- - [Epic Approach](./epic-and-story-structure.md#epic-approach)
- - [User Interface Enhancement Goals](./user-interface-enhancement-goals.md)
- - [Integration with Existing UI](./user-interface-enhancement-goals.md#integration-with-existing-ui)
- - [Modified/New Screens and Views](./user-interface-enhancement-goals.md#modifiednew-screens-and-views)
- - [UI Consistency Requirements](./user-interface-enhancement-goals.md#ui-consistency-requirements)
- - [Epic 1: 3-Portal Cohort Management System](./epic-1-3-portal-cohort-management-system.md)
- - [Story 1.1: Institution and Admin Management](./epic-1-3-portal-cohort-management-system.md#story-11-institution-and-admin-management)
- - [Story 1.2: Cohort Creation and Template Management](./epic-1-3-portal-cohort-management-system.md#story-12-cohort-creation-and-template-management)
- - [Story 1.3: Student Invitation and Enrollment](./epic-1-3-portal-cohort-management-system.md#story-13-student-invitation-and-enrollment)
- - [Story 1.4: Admin Document Verification Workflow](./epic-1-3-portal-cohort-management-system.md#story-14-admin-document-verification-workflow)
- - [Story 1.5: Student Portal - Document Upload and Agreement Completion](./epic-1-3-portal-cohort-management-system.md#story-15-student-portal-document-upload-and-agreement-completion)
- - [Story 1.6: Sponsor Portal - Multi-Student Review and Signing](./epic-1-3-portal-cohort-management-system.md#story-16-sponsor-portal-multi-student-review-and-signing)
- - [Story 1.7: Admin Finalization and Document Access](./epic-1-3-portal-cohort-management-system.md#story-17-admin-finalization-and-document-access)
- - [Story 1.8: Notification and Reminder System](./epic-1-3-portal-cohort-management-system.md#story-18-notification-and-reminder-system)
- - [Story 1.9: Dashboard and Analytics](./epic-1-3-portal-cohort-management-system.md#story-19-dashboard-and-analytics)
- - [Story 1.10: State Management and Workflow Orchestration](./epic-1-3-portal-cohort-management-system.md#story-110-state-management-and-workflow-orchestration)
diff --git a/docs/prd/intro-project-analysis-and-context.md b/docs/prd/intro-project-analysis-and-context.md
deleted file mode 100644
index 38d2636b..00000000
--- a/docs/prd/intro-project-analysis-and-context.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Intro Project Analysis and Context
-
-## SCOPE ASSESSMENT
-**⚠️ SIGNIFICANT ENHANCEMENT - System-Wide Impact**
-
-This PRD documents a **Major Feature Addition** that transforms the single-portal DocuSeal platform into a specialized 3-portal cohort management system. This enhancement requires:
-- Multiple coordinated user stories
-- Substantial architectural additions
-- System-wide integration across existing DocuSeal capabilities
-- Estimated timeline: Multiple development cycles
-
-## Existing Project Overview
-
-**Analysis Source**: IDE-based fresh analysis
-
-**Current Project State**:
-
-FloDoc is built on **DocuSeal** - an open-source document filling and signing platform. The base system provides:
-
-- **Document Form Builder**: WYSIWYG PDF form field creation with 12 field types (Signature, Date, File, Checkbox, etc.)
-- **Multi-Submitter Workflows**: Support for multiple signers per document
-- **Authentication & User Management**: Devise-based authentication with 2FA support
-- **Email Automation**: SMTP-based automated email notifications
-- **File Storage**: Flexible storage options (local disk, AWS S3, Google Cloud Storage, Azure Cloud)
-- **PDF Processing**: HexaPDF for PDF generation, manipulation, and signature embedding
-- **API & Webhooks**: RESTful API with webhook support for integrations
-- **Mobile-Optimized UI**: Responsive interface supporting 7 UI languages and signing in 14 languages
-- **Role-Based Access**: User roles and permissions system (via Cancancan)
-- **Tech Stack**: Ruby on Rails 3.4.2, Vue.js 3, TailwindCSS, DaisyUI, Sidekiq for background jobs
-
-## Available Documentation Analysis
-
-**Available Documentation**:
-- ✅ API Documentation (Node.js, Ruby, Python, PHP, Java, Go, C#, TypeScript, JavaScript)
-- ✅ Webhook Documentation (Submission, Form, Template webhooks)
-- ✅ Embedding Documentation (React, Vue, Angular, JavaScript form builders and signing forms)
-- ⚠️ Architecture Documentation (not present - **requires architect review**)
-- ⚠️ Coding Standards (not present - **requires documentation**)
-- ⚠️ Source tree documentation (not present - **requires documentation**)
-- ⚠️ Technical debt documentation (not present - **requires analysis**)
-
-**Recommendation**: Before full implementation, Winston (Architect) should run a document-project task to create comprehensive architecture documentation.
-
-## Enhancement Scope Definition
-
-**Enhancement Type**: ✅ **Major Feature Addition** (3-Portal Cohort Management System)
-
-**Enhancement Description**:
-
-Transform the single-portal DocuSeal platform into a specialized **3-portal cohort management system** for South African private training institutions. The system will manage training cohorts (learnerships, internships, candidacies) through a coordinated workflow involving institution admins, students, and sponsors. Each cohort handles document collection, verification, and multi-party signing for program agreements and supporting documentation.
-
-**Impact Assessment**: ✅ **Significant Impact** (substantial existing code changes)
-
-**Rationale for Impact Level**:
-- New multi-tenant institution architecture required
-- New authentication/authorization model (role-based per institution)
-- New domain models (Cohort, StudentCohortEnrollment, Sponsor, etc.)
-- Complex workflow state management (waiting → in progress → complete)
-- Custom portal interfaces for each role type
-- Integration with existing DocuSeal form builder and signing workflows
-- New notification and reminder systems
-- Dashboard and analytics layer
-
-## Goals and Background Context
-
-**Goals**:
-
-- Enable private training institutions to digitally manage training program cohorts from creation to completion
-- Streamline multi-party document workflows (admin → students → sponsor → finalization)
-- Provide role-based portals tailored to each participant's specific needs and permissions
-- Maintain 100% backward compatibility with core DocuSeal form builder and signing capabilities
-- Reduce document processing time from weeks to days through automated workflows
-- Provide real-time visibility into cohort and student submission status
-- Ensure document compliance through manual verification workflows with audit trail
-
-**Background Context**:
-
-South African private training institutions currently manage learnerships, internships, and candidacy programs through manual, paper-intensive processes. Each program requires collecting student documents (matric certificates, IDs, disability docs, qualifications), getting program agreements filled and signed by multiple parties (student, sponsor, institution), and tracking completion across dozens of students per cohort.
-
-This manual process is time-consuming (taking weeks), error-prone, lacks visibility into status, and requires physical document handling. FloDoc leverages DocuSeal's proven document signing platform to create a specialized workflow that automates this process while maintaining the flexibility and power of DocuSeal's core form builder and signing engine.
-
-The enhancement adds a cohort management layer on top of DocuSeal, creating three specialized portals that work with the existing document infrastructure rather than replacing it. Institutions continue using DocuSeal's form builder to create agreement templates, but now have a structured workflow for managing batches of students through the document submission and signing process.
-
-## Change Log
-
-| Change | Date | Version | Description | Author |
-|--------|------|---------|-------------|--------|
-| Initial PRD Creation | 2025-01-01 | v1.0 | Brownfield enhancement for 3-portal cohort management system | PM Agent |
-
----
diff --git a/docs/prd/requirements.md b/docs/prd/requirements.md
deleted file mode 100644
index cf4784e3..00000000
--- a/docs/prd/requirements.md
+++ /dev/null
@@ -1,83 +0,0 @@
-# Requirements
-
-## Functional Requirements
-
-**FR1**: The system shall support multi-institution architecture where each private training institution can manage multiple training cohorts independently.
-
-**FR2**: The system shall provide three distinct portal interfaces: Admin Portal (for training institution staff), Student Portal (for enrolled students), and Sponsor Portal (for program sponsors).
-
-**FR3**: The system shall support two admin permission levels: Super Admin (institution-level management) and Regular Admin (cohort-level management).
-
-**FR4**: The system shall support three fixed program types: Learnership, Internship, and Candidacy, each with configurable agreement templates uploaded by admins.
-
-**FR5**: The system shall enable admins to create cohorts by specifying: number of students, program type, sponsor email, main agreement template, and additional supporting document templates.
-
-**FR6**: The system shall generate unique invite links or send email invitations to students for cohort enrollment.
-
-**FR7**: The system shall allow students to upload required documents (matric certificate, ID, disability documentation, tertiary qualifications, international certificates) to their enrollment.
-
-**FR8**: The system shall allow students to fill and sign the main program type agreement using DocuSeal's existing form builder capabilities.
-
-**FR9**: The system shall allow students to fill and sign additional supporting documents uploaded by the admin.
-
-**FR10**: The system shall implement a state management system for each student enrollment with states: "Waiting", "In Progress", "Complete".
-
-**FR11**: The system shall prevent sponsor access until all students in a cohort have completed their submissions.
-
-**FR12**: The system shall allow sponsors to review and sign each student's main agreement and supporting documents individually.
-
-**FR13**: The system shall allow sponsors to bulk sign all students or submit individually.
-
-**FR14**: The system shall allow sponsors to view the entire cohort overview and individual student submissions.
-
-**FR15**: The system shall enable admin document verification with manual review and rejection capabilities (with reason provided).
-
-**FR16**: The system shall allow admins to sign the main agreement at the beginning of the process (before student invitations).
-
-**FR17**: The system shall provide real-time dashboard showing cohort completion status for all three portals.
-
-**FR18**: The system shall provide email notifications for: cohort creation, student invites, submission reminders, completion status updates, and sponsor access.
-
-**FR19**: The system shall provide reporting and analytics on document completion times, cohort status, and submission metrics.
-
-**FR20**: The system shall allow admins to download final signed documents for all parties.
-
-**FR21**: The system shall store all documents in DocuSeal's existing document storage infrastructure.
-
-**FR22**: The system shall maintain 100% backward compatibility with existing DocuSeal form builder and signing workflows.
-
-**FR23**: The system shall allow admins to export cohort data to Excel format containing: cohort name, student name, student surname, student age, student race, student city, program type, sponsor company name, disability status, and gender.
-
-## Non-Functional Requirements
-
-**NFR1**: The system must maintain existing performance characteristics and not exceed current memory usage by more than 20%.
-
-**NFR2**: The system must be mobile-optimized and support all existing DocuSeal UI languages.
-
-**NFR3**: The system must leverage existing DocuSeal authentication infrastructure with role-based access control.
-
-**NFR4**: The system must integrate seamlessly with existing DocuSeal email notification system.
-
-**NFR5**: The system must support concurrent cohort management across multiple institutions without data leakage.
-
-**NFR6**: The system must provide audit trails for all document verification actions (rejections, approvals).
-
-**NFR7**: The system must maintain document integrity and signature verification capabilities.
-
-**NFR8**: The system must support background processing for email notifications and document operations via Sidekiq.
-
-**NFR9**: The system must comply with South African electronic document and signature regulations.
-
-**NFR10**: The system must provide comprehensive error handling and user feedback for all portal interactions.
-
-## Compatibility Requirements
-
-**CR1: API Compatibility**: All new endpoints must follow existing DocuSeal API patterns and authentication mechanisms. No breaking changes to existing public APIs.
-
-**CR2: Database Schema Compatibility**: New tables and relationships must not modify existing DocuSeal core schemas. Extensions should use foreign keys and new tables only.
-
-**CR3: UI/UX Consistency**: All three portals must maintain DocuSeal's existing design system (TailwindCSS + DaisyUI), component patterns, and interaction models.
-
-**CR4: Integration Compatibility**: The system must work with existing DocuSeal integrations (webhooks, API, embedded forms) without requiring changes to external systems.
-
----
diff --git a/docs/prd/table-of-contents.md b/docs/prd/table-of-contents.md
deleted file mode 100644
index c7238c0a..00000000
--- a/docs/prd/table-of-contents.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Table of Contents
-1. [Intro Project Analysis and Context](#intro-project-analysis-and-context)
-2. [Requirements](#requirements)
-3. [Technical Constraints and Integration](#technical-constraints-and-integration)
-4. [Epic and Story Structure](#epic-and-story-structure)
-5. [Epic 1: 3-Portal Cohort Management System](#epic-1-3-portal-cohort-management-system)
-
----
diff --git a/docs/prd/technical-constraints-and-integration.md b/docs/prd/technical-constraints-and-integration.md
deleted file mode 100644
index 8aa8e1b2..00000000
--- a/docs/prd/technical-constraints-and-integration.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# Technical Constraints and Integration
-
-## Existing Technology Stack
-
-**Languages**: Ruby 3.4.2, JavaScript, Vue.js 3, HTML, CSS
-**Frameworks**: Rails 7.x, Shakapacker, Vue 3.3.2, TailwindCSS 3.4.17, DaisyUI 3.9.4
-**Database**: SQLite (development), PostgreSQL/MySQL (production)
-**Infrastructure**: Docker, Sidekiq for background jobs, Puma web server
-**External Dependencies**: AWS S3, Google Cloud Storage, Azure Cloud (optional), SMTP for emails
-
-## Integration Approach
-
-**Database Integration Strategy**:
-- Create new tables: `cohorts`, `cohort_enrollments`, `institutions`, `sponsors`, `document_verifications`
-- Use foreign keys to link to existing `users`, `submitters`, `submissions` tables
-- Maintain existing document relationships through `cohort_enrollments` → `submissions` mapping
-
-**API Integration Strategy**:
-- Extend existing DocuSeal API with new endpoints under `/api/v1/cohorts/*`
-- Reuse existing authentication (Devise tokens, JWT)
-- Leverage existing submission and document APIs for core signing workflows
-
-**Frontend Integration Strategy**:
-- Add new Vue components for cohort management
-- Extend existing navigation to support role-based portal switching
-- Reuse existing DocuSeal form builder and signing form components
-- Implement portal-specific dashboards using existing UI patterns
-
-**Testing Integration Strategy**:
-- Extend existing RSpec test suite with new model and integration tests
-- Add feature tests for all three portal workflows
-- Maintain existing test patterns and helpers
-
-## Code Organization and Standards
-
-**File Structure Approach**:
-- `app/models/cohort.rb`, `app/models/cohort_enrollment.rb`, etc. (new models)
-- `app/controllers/api/v1/cohorts_controller.rb` (API endpoints)
-- `app/controllers/cohorts_controller.rb` (web controllers)
-- `app/views/cohorts/*` (cohort management views)
-- `app/views/cohorts/portal/admin/*` (admin portal views)
-- `app/views/cohorts/portal/student/*` (student portal views)
-- `app/views/cohorts/portal/sponsor/*` (sponsor portal views)
-- `app/javascript/cohorts/*` (Vue components for all portals)
-- `app/jobs/cohort_*_job.rb` (background jobs)
-
-**Naming Conventions**:
-- Models: `Cohort`, `CohortEnrollment`, `CohortDocumentVerification`
-- Controllers: `CohortsController`, `Admin::CohortsController`, `Api::V1::CohortsController`
-- Views: `cohorts/index.html.erb`, `cohorts/portal/admin/show.html.erb`
-- Vue components: `CohortDashboard.vue`, `StudentPortal.vue`, `SponsorPortal.vue`
-
-**Coding Standards**:
-- Follow existing RuboCop configuration
-- Follow existing ESLint configuration for Vue components
-- Use Rails conventions (fat models, thin controllers)
-- Use Vue 3 Composition API for new components
-- Maintain existing test coverage patterns
-
-**Documentation Standards**:
-- Document all new models with annotations
-- Add API endpoint documentation following existing patterns
-- Create user guides for each portal
-- Update README with new features
-
-## Deployment and Operations
-
-**Build Process Integration**:
-- No changes required to existing build process
-- New Vue components will be bundled with existing Shakapacker configuration
-- New Ruby code will be processed by existing Rails asset pipeline
-
-**Deployment Strategy**:
-- Deploy as incremental feature addition to existing DocuSeal deployment
-- Use database migrations for new schema
-- No infrastructure changes required beyond existing Docker setup
-
-**Monitoring and Logging**:
-- Extend existing Rails logging with cohort-specific events
-- Add cohort workflow metrics to existing monitoring
-- Use existing Sidekiq monitoring for background jobs
-
-**Configuration Management**:
-- Use existing environment variable system
-- Add new configuration for cohort-specific features (notification templates, etc.)
-
-## Risk Assessment and Mitigation
-
-**Technical Risks**:
-- **Risk**: Performance degradation with large cohorts (100+ students)
- - **Mitigation**: Implement pagination, lazy loading, and background processing
- - **Impact**: Medium | **Likelihood**: Medium
-
-- **Risk**: State management complexity leading to race conditions
- - **Mitigation**: Use database transactions and optimistic locking
- - **Impact**: High | **Likelihood**: Low
-
-- **Risk**: Integration conflicts with existing DocuSeal features
- - **Mitigation**: Thorough testing of existing workflows, maintain feature flags
- - **Impact**: High | **Likelihood**: Medium
-
-**Integration Risks**:
-- **Risk**: Authentication conflicts between portals and existing DocuSeal
- - **Mitigation**: **⚠️ REQUIRES ARCHITECT REVIEW** - See Winston for authentication strategy
- - **Impact**: High | **Likelihood**: Medium
-
-- **Risk**: Document storage capacity with multiple document types per student
- - **Mitigation**: Monitor storage usage, implement retention policies
- - **Impact**: Medium | **Likelihood**: Low
-
-**Deployment Risks**:
-- **Risk**: Database migration failures with large existing datasets
- - **Mitigation**: Test migrations on production-like data, have rollback plan
- - **Impact**: High | **Likelihood**: Low
-
-- **Risk**: User adoption challenges with new portal interfaces
- - **Mitigation**: Comprehensive user training, phased rollout, feedback collection
- - **Impact**: Medium | **Likelihood**: Medium
-
-**Mitigation Strategies**:
-1. **Architect Review**: Winston must review authentication, multi-tenancy, and state machine design
-2. **Phased Rollout**: Implement one portal at a time (Admin → Student → Sponsor)
-3. **Feature Flags**: Allow rollback of individual features without full deployment
-4. **Comprehensive Testing**: Unit, integration, and end-to-end tests for all workflows
-5. **Performance Testing**: Load test with realistic cohort sizes (50-200 students)
-6. **User Acceptance Testing**: Real training institutions testing with actual workflows
-
----
diff --git a/docs/prd/user-interface-enhancement-goals.md b/docs/prd/user-interface-enhancement-goals.md
deleted file mode 100644
index 2a6cf7fb..00000000
--- a/docs/prd/user-interface-enhancement-goals.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# User Interface Enhancement Goals
-
-## Integration with Existing UI
-
-The three portals will use **completely custom UI/UX designs** (not DocuSeal's existing DaisyUI design system). The admin portal will follow provided wireframes as the primary design specification. All portals will maintain mobile-optimized responsive design principles while creating distinct, role-specific user experiences.
-
-The enhancement will leverage DocuSeal's existing form builder and signing form components as embedded interfaces within the custom portal frameworks. This maintains DocuSeal's core document filling and signing capabilities while providing a tailored workflow management layer.
-
-## Modified/New Screens and Views
-
-**Admin Portal:**
-- Institution onboarding wizard (multi-step form)
-- Cohort creation and management dashboard
-- Document verification interface
-- Sponsor coordination panel
-- Analytics and reporting views
-- Excel export interface
-
-**Student Portal:**
-- Cohort welcome/access screen
-- Document upload interface
-- Agreement completion screens (DocuSeal embedded)
-- Status tracking dashboard
-- Re-submission workflow views
-
-**Sponsor Portal:**
-- Cohort overview dashboard
-- Individual student review screens
-- Signing interface (DocuSeal embedded)
-- Bulk signing controls
-
-## UI Consistency Requirements
-
-- All portals will use custom TailwindCSS design system (not DaisyUI)
-- Mobile-first responsive design across all portals
-- Consistent color scheme and branding for FloDoc
-- Accessible UI components (WCAG 2.1 AA compliance)
-- Loading states and error handling patterns consistent across portals
-- Form validation feedback patterns
-- Notification/alert component standardization
-
----