# 1. Intro Project Analysis and Context
## 1.1 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 for South African private training institutions.
**Enhancement Complexity Analysis:**
- **Type**: Major Feature Addition (3-Portal Cohort Management)
- **Impact**: Significant Impact (substantial existing code changes required)
- **Timeline**: Multiple development cycles
- **Risk Level**: High (touches core DocuSeal workflows)
**Why This Requires Full PRD Process:**
This is NOT a simple feature addition. The enhancement requires:
- New multi-tenant institution architecture
- Complex 3-party signature workflows (TP → Students → Sponsor → TP Review)
- Three separate portal interfaces with custom UI/UX
- State management across multiple entities
- Integration with existing DocuSeal form builder and signing infrastructure
- Bulk operations and email management rules
---
## 1.2 EXISTING PROJECT OVERVIEW
**Analysis Source**: IDE-based analysis + User requirements clarification
**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 3.4.17, DaisyUI 3.9.4, Sidekiq for background jobs
**Key Existing Architecture for FloDoc Integration:**
- **Templates** = Document templates with form fields
- **Submissions** = Document workflows with multiple signers
- **Submitters** = Individual participants who sign documents
- **Completed Documents** = Final signed PDFs
---
## 1.3 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 (docs/current-app-sitemap.md - comprehensive analysis)
- ✅ Existing PRD (v1.0) - being replaced by this version
- ⚠️ Coding Standards (not present - **requires documentation**)
- ⚠️ Technical Debt Analysis (not present - **requires analysis**)
**Recommendation**: This PRD will serve as the comprehensive planning document. Architecture analysis already completed in separate document.
---
## 1.4 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 (Training Providers). The system manages cohorts through a **3-party signature workflow**: TP → Students → Sponsor → TP Review.
**Core Architecture**:
- **Templates = Cohorts**: Each cohort is a DocuSeal template containing all documents and signatory mappings
- **Submissions = Students**: Each student within a cohort is a submission with their own document workflow
**Complete Workflow**:
1. **Training Provider (TP) Onboarding**: TP creates account with name, surname, email
2. **Cohort Creation** (5-step multi-form):
- Step 1: Cohort name
- Step 2: Program type (learnership/internship/candidacy)
- Step 3: Student emails (manual entry or bulk upload)
- Step 4: Sponsor email (required - single email for all cohort documents)
- Step 5: Upload main SETA agreement + additional supporting docs + specify required student uploads (ID, Matric, Tertiary Qualifications)
3. **Document Mapping Phase**: TP maps signatories (Learner, Sponsor, TP) to document sections using DocuSeal's existing mapping with tweaks
4. **TP Signing Phase**: TP signs first student → system auto-fills/signs remaining students
5. **Student Enrollment**: Bulk invite emails sent → students complete assigned docs + upload required files
6. **Sponsor Review**: Single sponsor link (one email regardless of multiple assignments) → 3-panel portal (student list | document viewer | student info) → individual or bulk completion
7. **TP Review**: TP reviews all completed documents from students and sponsor → finalizes 3-party agreements
8. **Download**: Bulk ZIP with structure: Cohort_Name/Student_Name/All_Docs.pdf + Audit_Trail.pdf
**Key System Behaviors**:
- **Single Email Rule**: Sponsor receives ONE email per cohort, regardless of how many students they're assigned to
- **TP Initiates Signing**: TP starts the signing workflow BEFORE students and sponsor
- **Bulk Operations**: TP can fill once and replicate for all students
**Impact Assessment**: ✅ **Significant Impact** (substantial existing code changes)
**Rationale for Impact Level**:
- **Single Institution Model**: One training institution manages multiple cohorts (NOT multi-tenant)
- **Ad-hoc Access**: Students and sponsors access via email links without creating accounts
- **New Domain Models**: Cohort, CohortEnrollment, Institution (single), Sponsor (ad-hoc)
- **Complex Workflow State Management**: TP → Students → Sponsor → TP Review with state tracking
- **Three Portal Interfaces**: Custom portals for TP (admin), Students, and Sponsor
- **Integration with DocuSeal**: Leverages existing form builder and signing infrastructure
- **Email Management Rules**: Single email per sponsor (no duplicates), bulk operations
- **Dashboard & Analytics**: Real-time cohort status tracking
---
## 1.5 GOALS AND BACKGROUND CONTEXT
**Goals**:
- Enable private training institutions to digitally manage training program cohorts from creation to completion
- Streamline multi-party document workflows (TP → Students → Sponsor → TP Review)
- 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
- Implement single-email rule for sponsors (no duplicate emails)
- Enable bulk operations for TP and Sponsor to reduce repetitive work
**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.
**Critical Requirements from User Clarification**:
- Templates represent cohorts, submissions represent students
- TP initiates signing BEFORE students and sponsor
- Sponsor receives ONE email per cohort (no duplicates)
- TP Review phase after sponsor completion (not TP Finalization)
- Bulk operations: fill once, replicate for all students
---
## 1.6 CHANGE LOG
| Change | Date | Version | Description | Author |
|--------|------|---------|-------------|--------|
| Initial PRD Creation | 2025-01-01 | v1.0 | Brownfield enhancement for 3-portal cohort management | PM Agent |
| **PRD v2.0 - Fresh Start** | 2026-01-10 | v2.0 | Complete rewrite with clarified workflow requirements | User + PM |
| **Section 1 Complete** | 2026-01-10 | v2.0 | Intro Analysis with validated understanding | PM |
| **PO Validation Fixes** | 2026-01-14 | v2.1 | Addressed 3 blocking issues, added scope declaration | PO/PM |
---
## 1.7 SCOPE BOUNDARIES & DEPLOYMENT STRATEGY
**Deployment Decision:** ✅ **Local Docker MVP Only** (Option A)
**Rationale:**
- Management wants to validate FloDoc system locally first
- Defers production infrastructure investment until MVP proven
- Fastest path to working demo
- No cloud costs during validation phase
---
### In Scope (MVP - Local Docker)
**Core Functionality:**
- ✅ Local Docker development environment (PostgreSQL, Redis, Minio, MailHog)
- ✅ 3-portal cohort management workflow
- ✅ Single institution support
- ✅ All 21 implementation stories (Epics 1-7)
- ✅ Demo validation with sample data (Story 8.0.1)
**Technical:**
- ✅ Database schema for 3 new tables
- ✅ RESTful API with `/api/v1/flodoc/` namespace
- ✅ Vue.js 3 portals with TailwindCSS
- ✅ Email notifications (via MailHog)
- ✅ PDF generation and signing (HexaPDF)
- ✅ Excel export (rubyXL)
- ✅ Background jobs (Sidekiq)
**Testing:**
- ✅ End-to-end workflow testing
- ✅ Mobile responsiveness testing
- ✅ Performance testing (50+ students)
- ✅ Security audit (with enhanced checklist)
- ✅ User acceptance testing
---
### Out of Scope (Post-MVP - Deferred)
**Production Infrastructure (Stories 8.1-8.4 - Deferred):**
- ❌ Production CI/CD pipeline
- ❌ Cloud infrastructure (AWS/GCP/Azure)
- ❌ Infrastructure as Code (Terraform)
- ❌ DNS/domain registration
- ❌ CDN/static asset hosting
- ❌ Production monitoring (Sentry, New Relic)
- ❌ Analytics and user tracking
- ❌ Blue-green deployment
- ❌ Production backup strategy
**User Documentation & Operations (Stories 8.5-8.7 - Deferred):**
- ⚠️ **Story 8.5**: User Communication & Training Materials (blocking - must be created before dev)
- ❌ **Story 8.6**: In-app help system
- ❌ **Story 8.7**: Knowledge transfer plan & operations runbook
- ❌ Migration announcement emails
- ❌ User training materials
- ❌ FAQ and tutorials
- ❌ Support team training
- ❌ Incident response procedures
**Future Enhancements:**
- ❌ Multi-institution support
- ❌ Advanced analytics dashboard
- ❌ Custom branding
- ❌ Additional portal features
---
### Production Path Forward
**After Local Validation Success:**
1. Decision point: Proceed to production or iterate on MVP
2. If proceeding: Create Stories 8.1-8.4 (production infrastructure)
3. Implement Stories 8.5-8.7 (documentation & KT)
4. Deploy to production environment
**Note:** Production deployment is **NOT** part of current scope. All production-related work is deferred pending successful local validation.
---
### Scope Acknowledgment
**Current State:** Local Docker MVP ready for development
**Target State:** Working demo with 3-portal workflow
**Production Readiness:** Deferred to post-MVP phase
This scope declaration addresses PO Validation Issue #1 (Production Deployment Strategy Undefined).
---
## 1.8 EXTENSIBILITY PATTERNS (Optional Enhancement)
**Status**: Draft - Reference Documentation
**Priority**: Medium (Post-MVP)
**Purpose**: Guide future development and customization
This section documents how to extend the FloDoc system for future enhancements.
---
### 1.8.1 Adding New Portal Types
**Current Pattern**: 3 portals (TP, Student, Sponsor) with ad-hoc token authentication
**Extension Steps:**
1. **Create Portal Controller** (app/controllers/flodoc/portals/):
```ruby
# app/controllers/flodoc/portals/new_portal_controller.rb
class Flodoc::Portals::NewPortalController < ApplicationController
before_action :authenticate_token!
def dashboard
# Uses token-based auth like Student/Sponsor portals
@data = NewPortalService.load_data(@token)
end
end
```
2. **Add Token Model** (if new token type needed):
```ruby
# app/models/flodoc/new_portal_token.rb
class Flodoc::NewPortalToken < ApplicationRecord
belongs_to :cohort
has_secure_token :token
validates :email, presence: true, uniqueness: { scope: :cohort_id }
end
```
3. **Add Vue Portal** (app/javascript/new_portal/):
```typescript
// app/javascript/new_portal/application.js
import { createApp } from 'vue'
import NewPortalApp from './NewPortalApp.vue'
createApp(NewPortalApp).mount('#app')
```
4. **Update Routes** (config/routes.rb):
```ruby
namespace :new_portal do
get 'dashboard', to: 'dashboard#index'
post 'submit', to: 'submissions#create'
end
```
---
### 1.8.2 Extending Cohort State Machine
**Current States**: `draft` → `active` → `completed` → `finalized`
**Adding New State:**
1. **Update State Enum** (app/models/flodoc/cohort.rb):
```ruby
class Flodoc::Cohort < ApplicationRecord
STATES = %w[draft active completed finalized under_review].freeze
enum status: STATES.index_with(&:to_s)
end
```
2. **Add State Transition Logic**:
```ruby
# app/models/flodoc/cohort.rb
def can_under_review?
completed? && all_sponsors_signed?
end
def under_review!
update!(status: 'under_review')
Flodoc::CohortMailer.under_review_notification(self).deliver_later
end
```
3. **Update Portal UI** (app/javascript/tp_portal/views/CohortDetail.vue):
```vue
```
---
### 1.8.3 Adding New Document Types
**Current**: PDF documents with form fields
**Extension Pattern:**
1. **Create Document Type Model**:
```ruby
# app/models/flodoc/document_type.rb
class Flodoc::DocumentType < ApplicationRecord
validates :name, presence: true
validates :handler, presence: true
# handler values: 'pdf', 'docx', 'spreadsheet', 'custom'
end
```
2. **Register Handler**:
```ruby
# config/initializers/flodoc_document_types.rb
Flodoc::DocumentType.register_handler('spreadsheet', Flodoc::SpreadsheetHandler)
```
3. **Implement Handler**:
```ruby
# app/services/flodoc/handlers/spreadsheet_handler.rb
module Flodoc
module Handlers
class SpreadsheetHandler
def self.generate(cohort, data)
# Custom generation logic
end
def self.validate(file)
# Custom validation logic
end
end
end
end
```
---
### 1.8.4 Extending the API
**Current**: `/api/v1/flodoc/` namespace
**Adding New Endpoint:**
1. **Create API Controller**:
```ruby
# app/controllers/api/v1/flodoc/new_feature_controller.rb
class Api::V1::Flodoc::NewFeatureController < Api::V1::BaseController
def index
# Uses JWT authentication from base controller
render json: { data: 'example' }
end
end
```
2. **Add Route**:
```ruby
# config/routes.rb
namespace :api do
namespace :v1 do
namespace :flodoc do
get 'new_feature', to: 'new_feature#index'
end
end
end
```
3. **Update API Documentation**:
```markdown
### GET /api/v1/flodoc/new_feature
**Authentication**: Bearer JWT token
**Response**:
```json
{
"data": "example"
}
```
---
### 1.8.5 Adding New Authentication Providers
**Current**: Email-based ad-hoc tokens for students/sponsors
**Adding OAuth Provider:**
1. **Add OmniAuth Strategy** (Gemfile):
```ruby
gem 'omniauth-google-oauth2'
gem 'omniauth-saml' # For enterprise SSO
```
2. **Configure Provider** (config/initializers/omniauth.rb):
```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
provider :saml,
issuer: 'flodoc',
idp_sso_target_url: ENV['SAML_SSO_URL']
end
```
3. **Create Authentication Handler**:
```ruby
# app/services/flodoc/auth/oauth_handler.rb
module Flodoc
module Auth
class OAuthHandler
def self.authenticate(provider, auth_hash)
user = User.find_or_create_by(email: auth_hash.info.email) do |u|
u.password = SecureRandom.hex(16)
u.name = auth_hash.info.name
end
# Generate portal-specific token
Flodoc::PortalToken.create!(user: user, provider: provider)
end
end
end
end
```
---
### 1.8.6 Customizing UI Components
**Current**: Vue 3 + TailwindCSS 3.4.17 + DaisyUI 3.9.4
**Customization Pattern:**
1. **Override Design Tokens** (app/javascript/design-system/tailwind.config.js):
```javascript
module.exports = {
theme: {
extend: {
colors: {
flodoc: {
primary: '#1e3a8a', // Custom blue
accent: '#f59e0b', // Custom amber
}
}
}
}
}
```
2. **Create Custom Component**:
```vue
```
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.
---