17 KiB
Deal Room - Architecture Specification
Project: Deal Room - Secure Investment Banking Document Sharing Platform Owner: Misha Muskepo (michael@muskepo.com) Tech Lead: James Architecture Pattern: inou-portal pattern
Executive Summary
Deal Room is a secure, invite-only document sharing platform designed for Investment Banking deal teams. It provides role-based access control, encrypted file storage, AI-powered document analysis, and comprehensive audit trails for sensitive financial transactions.
System Architecture
Core Principles
- Single binary deployment - Zero runtime dependencies
- Data-centric design - All entities stored as typed JSON in unified entries table
- Security-first - Encryption at rest, RBAC, audit logging
- AI-enhanced - Document analysis and embeddings for intelligent search
- Production-grade - Battle-tested patterns from inou-portal
Technology Stack
- Backend: Go 1.22+ (single binary)
- Templates: templ (type-safe HTML generation)
- Frontend: HTMX + Tailwind CSS (CDN)
- Database: SQLite with encryption at rest
- File Storage: Encrypted (AES-256-GCM) + Compressed (zstd)
- AI/ML: K2.5 for document analysis and embeddings
- Authentication: Magic link + session cookies
Database Schema
Core Tables
users
CREATE TABLE users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
role TEXT NOT NULL CHECK (role IN ('admin', 'user')),
avatar_url TEXT,
created_at INTEGER NOT NULL,
last_login INTEGER,
is_active BOOLEAN NOT NULL DEFAULT 1
);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_active ON users(is_active);
entries
Unified data table storing all content types as typed JSON
CREATE TABLE entries (
id TEXT PRIMARY KEY,
parent_id TEXT, -- For threading/hierarchy
deal_room_id TEXT NOT NULL, -- Links to deal room entry
entry_type TEXT NOT NULL CHECK (entry_type IN ('deal_room', 'document', 'note', 'message', 'analysis')),
title TEXT NOT NULL,
content TEXT NOT NULL, -- JSON payload, schema varies by type
file_path TEXT, -- For documents: encrypted file path
file_size INTEGER, -- Original file size
file_hash TEXT, -- SHA-256 of original file
embedding BLOB, -- AI embeddings for search
created_by TEXT NOT NULL,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
FOREIGN KEY (created_by) REFERENCES users(id),
FOREIGN KEY (parent_id) REFERENCES entries(id),
FOREIGN KEY (deal_room_id) REFERENCES entries(id)
);
CREATE INDEX idx_entries_deal_room ON entries(deal_room_id);
CREATE INDEX idx_entries_type ON entries(entry_type);
CREATE INDEX idx_entries_parent ON entries(parent_id);
CREATE INDEX idx_entries_created ON entries(created_at);
CREATE INDEX idx_entries_creator ON entries(created_by);
access
RBAC permissions using bitmask
CREATE TABLE access (
id TEXT PRIMARY KEY,
entry_id TEXT NOT NULL,
user_id TEXT NOT NULL,
permissions INTEGER NOT NULL DEFAULT 1, -- Bitmask: read=1, write=2, delete=4, manage=8
granted_by TEXT NOT NULL,
granted_at INTEGER NOT NULL,
FOREIGN KEY (entry_id) REFERENCES entries(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (granted_by) REFERENCES users(id),
UNIQUE(entry_id, user_id)
);
CREATE INDEX idx_access_entry ON access(entry_id);
CREATE INDEX idx_access_user ON access(user_id);
CREATE INDEX idx_access_permissions ON access(permissions);
sessions
CREATE TABLE sessions (
token TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
expires_at INTEGER NOT NULL,
created_at INTEGER NOT NULL,
last_used INTEGER NOT NULL,
user_agent TEXT,
ip_address TEXT,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX idx_sessions_user ON sessions(user_id);
CREATE INDEX idx_sessions_expires ON sessions(expires_at);
audit_log
CREATE TABLE audit_log (
id TEXT PRIMARY KEY,
user_id TEXT,
entry_id TEXT,
action TEXT NOT NULL, -- view, create, update, delete, download, share
details TEXT, -- JSON with action-specific data
ip_address TEXT,
user_agent TEXT,
created_at INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (entry_id) REFERENCES entries(id)
);
CREATE INDEX idx_audit_user ON audit_log(user_id);
CREATE INDEX idx_audit_entry ON audit_log(entry_id);
CREATE INDEX idx_audit_action ON audit_log(action);
CREATE INDEX idx_audit_created ON audit_log(created_at);
Entry Content Schemas
Deal Room Entry
{
"type": "deal_room",
"description": "Acquisition of TechCorp by PrivateEquity Partners",
"stage": "due_diligence", // sourcing, loi, due_diligence, closing, completed
"target_company": "TechCorp Inc.",
"deal_value": "$50M",
"participants": [
{"name": "John Smith", "role": "Deal Lead", "organization": "PE Partners"},
{"name": "Jane Doe", "role": "Analyst", "organization": "PE Partners"}
],
"key_dates": {
"loi_signed": "2024-01-15",
"dd_start": "2024-02-01",
"close_target": "2024-04-30"
},
"confidentiality_level": "highly_confidential"
}
Document Entry
{
"type": "document",
"category": "financial_model", // nda, cim, financial_model, teaser, legal, dd_report
"mime_type": "application/pdf",
"original_name": "TechCorp_Financial_Model_v3.xlsx",
"version": "3.0",
"analysis": {
"summary": "Financial projections showing 15% EBITDA growth",
"key_metrics": ["Revenue: $100M", "EBITDA: $25M", "Growth: 15%"],
"risk_factors": ["Market volatility", "Regulatory changes"],
"ai_confidence": 0.92
},
"requires_nda": true
}
Note/Message Entry
{
"type": "note",
"body": "Updated financial model reflects Q4 performance...",
"mentions": ["user_id_123"], // @mentions for notifications
"attachments": ["entry_id_456"], // Reference to document entries
"thread_context": "document_discussion" // Helps organize conversations
}
Permission Model (RBAC)
Bitmask Values
- READ (1): View entry and metadata
- WRITE (2): Edit entry, add comments
- DELETE (4): Remove entry
- MANAGE (8): Grant/revoke access, manage permissions
Permission Inheritance
- Deal room permissions cascade to all contained documents
- Explicit document permissions override inherited permissions
- Admins have MANAGE (8) on all entries by default
Common Permission Patterns
- Viewer: READ (1) - Can view documents and notes
- Contributor: READ + WRITE (3) - Can add notes and upload documents
- Manager: READ + WRITE + DELETE (7) - Can manage content
- Admin: All permissions (15) - Full control
API Endpoints
Authentication
POST /auth/login # Magic link login
GET /auth/verify/{token} # Verify magic link
POST /auth/logout # End session
GET /auth/me # Current user info
Deal Rooms
GET /api/deal-rooms # List accessible deal rooms
POST /api/deal-rooms # Create new deal room
GET /api/deal-rooms/{id} # Get deal room details
PUT /api/deal-rooms/{id} # Update deal room
DELETE /api/deal-rooms/{id} # Archive deal room
Entries (Documents, Notes, etc.)
GET /api/entries # List entries (filtered by permissions)
POST /api/entries # Create entry
GET /api/entries/{id} # Get entry details
PUT /api/entries/{id} # Update entry
DELETE /api/entries/{id} # Delete entry
GET /api/entries/{id}/file # Download file (for documents)
Access Management
GET /api/entries/{id}/access # List permissions for entry
POST /api/entries/{id}/access # Grant access
PUT /api/entries/{id}/access/{uid} # Update user permissions
DELETE /api/entries/{id}/access/{uid} # Revoke access
Search & AI
GET /api/search?q={query} # Semantic search across accessible content
POST /api/analyze/{entry_id} # Trigger AI analysis
GET /api/similar/{entry_id} # Find similar documents
Activity & Audit
GET /api/activity/{deal_room_id} # Activity feed for deal room
GET /api/audit/{entry_id} # Audit log for specific entry
Page Routes (Server-Rendered)
GET / # Dashboard - accessible deal rooms
GET /login # Login page
GET /deal-rooms/{id} # Deal room detail view
GET /deal-rooms/{id}/upload # Document upload page
GET /documents/{id} # Document viewer
GET /admin # Admin panel (user/permissions management)
GET /profile # User profile
GET /activity # Global activity feed
File Storage Design
Storage Structure
data/
├── db/
│ └── dealroom.db # SQLite database
├── files/
│ ├── 2024/01/ # Date-based partitioning
│ │ ├── abc123.enc # Encrypted + compressed files
│ │ └── def456.enc
│ └── temp/ # Temporary upload staging
└── backups/ # Automated backups
├── db/
└── files/
Encryption Process
- Upload: File uploaded to
/temp/{uuid} - Compress: Apply zstd compression (level 3)
- Encrypt: AES-256-GCM with random nonce
- Store: Move to date-partitioned directory
- Index: Store metadata + embedding in database
- Cleanup: Remove temp file
File Naming
- Pattern:
{year}/{month}/{entry_id}.enc - Metadata: Stored in database, not filesystem
- Deduplication: SHA-256 hash prevents duplicate storage
AI/Embeddings Pipeline
Document Processing Workflow
- Upload: User uploads document
- Extract: Convert to text (PDF, DOCX, XLSX support)
- Analyze: Send to K2.5 for:
- Content summarization
- Key metrics extraction
- Risk factor identification
- Classification (NDA, CIM, Financial Model, etc.)
- Embed: Generate vector embeddings for semantic search
- Store: Save analysis results in entry content JSON
K2.5 Integration
type DocumentAnalysis struct {
Summary string `json:"summary"`
KeyMetrics []string `json:"key_metrics"`
RiskFactors []string `json:"risk_factors"`
Category string `json:"category"`
Confidence float64 `json:"ai_confidence"`
}
type EmbeddingRequest struct {
Text string `json:"text"`
Model string `json:"model"`
}
Semantic Search
- Vector Storage: SQLite with vector extension
- Similarity: Cosine similarity for document matching
- Hybrid Search: Combine keyword + semantic results
- Access Control: Filter results by user permissions
Security Model
Authentication
- Magic Link: Email-based passwordless login
- Session Management: Secure HTTP-only cookies
- Token Expiry: 24-hour sessions with automatic refresh
- Rate Limiting: Prevent brute force attacks
Authorization
- RBAC: Entry-level permissions with inheritance
- Least Privilege: Users see only what they have access to
- Audit Trail: All actions logged with user attribution
- Admin Controls: User management and permission oversight
Data Protection
- Encryption at Rest: AES-256-GCM for files, encrypted SQLite
- Encryption in Transit: HTTPS only, HSTS headers
- File Access: Direct file serving prevented, all through API
- Backup Encryption: Automated encrypted backups
Compliance Features
- Audit Logging: Comprehensive activity tracking
- Data Retention: Configurable retention policies
- Access Reviews: Periodic permission audits
- Export Controls: Document download tracking
Deployment Architecture
Single Binary Approach
dealroom
├── Static assets embedded (CSS, JS)
├── Templates compiled
├── Database migrations
└── Configuration via environment variables
Configuration
# Database
DB_PATH=/data/db/dealroom.db
DB_KEY=<encryption_key>
# File Storage
FILES_PATH=/data/files
BACKUP_PATH=/data/backups
# AI Service
K25_API_URL=http://k2.5:8080
K25_API_KEY=<api_key>
# Server
PORT=8080
BASE_URL=https://dealroom.company.com
SESSION_SECRET=<random_key>
# Email (for magic links)
SMTP_HOST=smtp.company.com
SMTP_USER=dealroom@company.com
SMTP_PASS=<password>
Docker Deployment
FROM golang:1.22-alpine AS builder
# ... build process
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata
COPY --from=builder /app/dealroom /usr/local/bin/
VOLUME ["/data"]
EXPOSE 8080
CMD ["dealroom"]
Development Workflow
Project Structure
dealroom/
├── cmd/dealroom/main.go # Application entry point
├── internal/
│ ├── db/ # Database layer
│ ├── rbac/ # RBAC engine
│ ├── store/ # File storage
│ ├── ai/ # K2.5 integration
│ ├── handler/ # HTTP handlers
│ └── model/ # Data models
├── templates/ # templ templates
├── static/ # Static assets
├── migrations/ # Database migrations
├── Dockerfile
├── Makefile
└── README.md
Build & Run
make build # Build binary
make run # Run in development mode
make test # Run tests
make migrate # Run database migrations
make docker # Build Docker image
Testing Strategy
- Unit Tests: Core business logic and RBAC
- Integration Tests: Database and file operations
- E2E Tests: Critical user journeys with real browser
- Security Tests: Permission boundaries and file access
- Performance Tests: Large file uploads and search
Scalability Considerations
Current Limits (SQLite-based)
- Concurrent Users: ~100-200 active users
- File Storage: Limited by disk space
- Search Performance: Good up to ~10K documents
- Database Size: Efficient up to ~100GB
Migration Path (Future)
- Database: PostgreSQL for higher concurrency
- File Storage: S3-compatible object storage
- Search: Dedicated vector database (Pinecone, Weaviate)
- Caching: Redis for session and query caching
Success Metrics
Technical Metrics
- Uptime: >99.9% availability
- Response Time: <200ms for page loads
- File Upload: <30s for 100MB files
- Search Latency: <500ms for semantic search
Business Metrics
- User Adoption: Active users per deal room
- Document Velocity: Files uploaded/downloaded per day
- Security Events: Zero unauthorized access incidents
- User Satisfaction: NPS > 8 for ease of use
Risk Assessment
Technical Risks
- Single Point of Failure: SQLite limits high availability
- File Corruption: Encryption key loss = data loss
- AI Dependency: K2.5 service availability required
- Scaling Challenges: May need architecture changes at scale
Mitigation Strategies
- Automated Backups: Hourly encrypted backups to S3
- Key Management: Secure key storage and rotation
- Circuit Breakers: Graceful degradation when AI unavailable
- Monitoring: Comprehensive health checks and alerting
Security Risks
- Data Breach: Highly sensitive financial information
- Insider Threat: Authorized users with malicious intent
- Compliance: Regulatory requirements for financial data
- Access Control: Complex permission inheritance bugs
Security Controls
- Defense in Depth: Multiple security layers
- Principle of Least Privilege: Minimal required permissions
- Comprehensive Auditing: All actions logged and monitored
- Regular Reviews: Periodic security assessments
Implementation Phases
Phase 1: Core Platform (4 weeks)
- Basic authentication and session management
- Deal room creation and management
- Document upload with encryption
- Basic RBAC implementation
Phase 2: Collaboration Features (3 weeks)
- Notes and messaging system
- Activity feeds and notifications
- Advanced permission management
- Search functionality
Phase 3: AI Integration (2 weeks)
- K2.5 document analysis
- Embeddings and semantic search
- Document summarization
- Similar document recommendations
Phase 4: Production Readiness (2 weeks)
- Comprehensive audit logging
- Admin dashboard
- Performance optimization
- Security hardening
Phase 5: Advanced Features (3 weeks)
- Deal stage tracking
- Bulk operations
- API for integrations
- Advanced reporting
Total estimated development time: 14 weeks with dedicated development team.
Conclusion
Deal Room represents a modern, security-first approach to Investment Banking document management. By leveraging the proven inou-portal pattern with Go's performance characteristics and AI-enhanced document analysis, we deliver a solution that meets the demanding requirements of financial services while maintaining operational simplicity through single-binary deployment.
The architecture prioritizes security, auditability, and user experience while providing a clear path for future scalability as the platform grows.