dealroom/LOVABLE-ANALYSIS.md

499 lines
18 KiB
Markdown

# Lovable Prototype Analysis — Dealspace AI
> Generated from source code dump of Misha's 49-iteration Lovable prototype.
> Source: `/home/johan/shared/dealspace-lovable/`
## Data Model (Supabase/PostgreSQL)
### Tables
#### 1. `organizations`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| name | text | |
| slug | text | URL-safe identifier |
| domain | text? | |
| logo_url | text? | |
| settings | jsonb? | |
| created_at | timestamp | |
| updated_at | timestamp | |
#### 2. `profiles`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| user_id | uuid | FK to auth.users |
| email | text? | |
| full_name | text? | |
| title | text? | Job title |
| phone | text? | |
| avatar_url | text? | |
| organization_id | uuid? | FK to organizations |
| onboarding_completed | boolean? | |
| settings | jsonb? | |
| created_at/updated_at | timestamp | |
#### 3. `user_roles`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| user_id | uuid | FK to auth.users |
| organization_id | uuid | FK to organizations |
| role | enum | `owner`, `admin`, `member`, `viewer` |
| created_at | timestamp | |
#### 4. `deals`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| name | text | Deal/project codename |
| description | text? | |
| organization_id | uuid | FK to organizations |
| created_by | uuid? | |
| stage | enum | `pipeline`, `loi`, `initial_review`, `due_diligence`, `final_negotiation`, `closed`, `dead` |
| target_company | text? | |
| deal_size | numeric? | |
| currency | text? | |
| close_probability | numeric? | 0-100 |
| expected_close_date | date? | |
| ioi_date | date? | Indication of Interest date |
| loi_date | date? | Letter of Intent date |
| exclusivity_end_date | date? | |
| is_archived | boolean? | |
| settings | jsonb? | |
| created_at/updated_at | timestamp | |
#### 5. `folders`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| parent_id | uuid? | FK to folders (self-referential tree) |
| name | text | |
| description | text? | |
| sort_order | integer? | |
| created_by | uuid? | |
| ai_summary | text? | Atlas-generated folder summary |
| ai_summary_updated_at | timestamp? | |
| completeness_score | numeric? | 0-100, AI-computed |
| created_at/updated_at | timestamp | |
#### 6. `files`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| folder_id | uuid? | FK to folders |
| name | text | Original filename |
| file_path | text? | Supabase storage path |
| file_size | bigint? | |
| mime_type | text? | |
| uploaded_by | uuid? | |
| status | enum | `uploaded`, `processing`, `reviewed`, `flagged`, `archived` |
| version | integer? | |
| ai_summary | text? | |
| ai_tags | text[]? | |
| is_sensitive | boolean? | |
| download_disabled | boolean? | |
| watermark_enabled | boolean? | |
| created_at/updated_at | timestamp | |
#### 7. `diligence_requests`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| section | text | Category (Financial, Legal, etc.) |
| item_number | text? | e.g., "1.1", "2.3" |
| description | text | What's being requested |
| priority | enum | `high`, `medium`, `low` |
| created_by | uuid? | |
| buyer_group | text? | Which buyer group this request is for |
| buyer_comment | text? | Inline comment from buyer |
| seller_comment | text? | Inline comment from seller |
| linked_file_ids | uuid[]? | Files that fulfill this request |
| atlas_status | enum | `fulfilled`, `partial`, `missing`, `not_applicable` |
| atlas_confidence | numeric? | 0-100 |
| atlas_note | text? | AI explanation |
| atlas_assessed_at | timestamp? | |
| created_at/updated_at | timestamp | |
#### 8. `deal_activity` (Audit Log)
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid? | FK to deals |
| organization_id | uuid? | FK to organizations |
| user_id | uuid? | |
| activity_type | enum | `view`, `download`, `upload`, `edit`, `delete`, `share`, `comment`, `permission_change`, `nda_signed`, `login` |
| resource_type | text? | |
| resource_id | uuid? | |
| resource_name | text? | |
| details | jsonb? | |
| ip_address | inet | |
| user_agent | text? | |
| created_at | timestamp | |
#### 9. `buyer_engagement`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| user_id | uuid? | |
| file_id | uuid? | FK to files |
| folder_id | uuid? | FK to folders |
| event_type | text | |
| dwell_time_seconds | numeric? | |
| page_views | integer? | |
| metadata | jsonb? | |
| created_at | timestamp | |
#### 10. `deal_scores`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| close_probability | numeric | 0-100 |
| risk_tier | text | `low`, `medium`, `high` |
| diligence_completion | numeric? | |
| buyer_engagement_score | numeric? | |
| response_velocity | numeric? | |
| red_flag_count | integer? | |
| recommendations | jsonb? | Array of strings |
| computed_at | timestamp | |
| created_at | timestamp | |
#### 11. `ai_insights`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| insight_type | text | |
| title | text | |
| content | text? | |
| severity | text? | |
| is_dismissed | boolean? | |
| source_file_ids | uuid[]? | |
| created_at | timestamp | |
#### 12. `contacts`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| organization_id | uuid | FK to organizations |
| full_name | text | |
| email | text? | |
| phone | text? | |
| company | text? | |
| title | text? | |
| contact_type | text? | buyer, advisor, internal |
| tags | text[]? | |
| notes | text? | |
| last_activity_at | timestamp? | |
| created_at/updated_at | timestamp | |
#### 13. `ic_memos`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| organization_id | uuid | FK to organizations |
| created_by | uuid? | |
| title | text | |
| content | jsonb | Structured: summary, business_model, financials, key_risks[], diligence_gaps[], valuation_considerations, recommendation, source_documents[] |
| status | text | `draft`, `review`, `final` |
| version | integer | |
| created_at/updated_at | timestamp | |
#### 14. `nda_records`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| deal_id | uuid | FK to deals |
| signer_name | text | |
| signer_email | text | |
| signer_company | text? | |
| user_id | uuid? | |
| status | text? | |
| signed_at | timestamp? | |
| expires_at | timestamp? | |
| nda_document_url | text? | |
| ip_address | inet | |
| created_at | timestamp | |
#### 15. `tasks`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| organization_id | uuid | FK to organizations |
| deal_id | uuid? | FK to deals |
| title | text | |
| description | text? | |
| assigned_to | uuid? | |
| created_by | uuid? | |
| status | text? | |
| priority | enum | `high`, `medium`, `low` |
| due_date | date? | |
| completed_at | timestamp? | |
| created_at/updated_at | timestamp | |
#### 16. `workflow_rules`
| Field | Type | Notes |
|-------|------|-------|
| id | uuid PK | |
| organization_id | uuid | FK to organizations |
| name | text | |
| trigger_type | text | |
| trigger_config | jsonb | |
| action_type | text | |
| action_config | jsonb | |
| is_active | boolean | |
| created_by | uuid? | |
| created_at/updated_at | timestamp | |
### Enums
- **deal_stage:** pipeline, loi, initial_review, due_diligence, final_negotiation, closed, dead
- **file_status:** uploaded, processing, reviewed, flagged, archived
- **request_priority:** high, medium, low
- **request_status:** fulfilled, partial, missing, not_applicable
- **activity_type:** view, download, upload, edit, delete, share, comment, permission_change, nda_signed, login
- **app_role:** owner, admin, member, viewer
### DB Functions
- `has_role(org_id, role, user_id)` → boolean
- `is_org_member(org_id, user_id)` → boolean
---
## Role/Permission Model
From `useUserRole.ts`:
- **Seller view** = `owner` or `admin` role → full platform access
- **Buyer view** = `member` or `viewer` role → restricted access
Key differences:
| Feature | Seller | Buyer |
|---------|--------|-------|
| Create deal rooms | ✅ | ❌ |
| Upload files | ✅ | ❌ |
| Upload CSV request lists | ✅ | ❌ |
| View analytics/engagement | ✅ | ❌ |
| Generate IC memos | ✅ | ❌ |
| View all deals | ✅ | Only deals with their buyer_group |
| View all requests | ✅ | Only requests for their buyer_group |
| Add buyer/seller comments | ✅ | ✅ |
Buyer groups are hardcoded demo values: `["Meridian Capital", "Summit Health Equity"]`
---
## API Operations (from `api.ts`)
| Function | Table | Operation |
|----------|-------|-----------|
| createOrganization | organizations | INSERT |
| getOrganization | organizations | SELECT by id |
| assignRole | user_roles | INSERT |
| getUserOrg | user_roles + organizations | SELECT (join) |
| getProfile | profiles | SELECT by user_id |
| updateProfile | profiles | UPDATE |
| getDeals | deals | SELECT by org_id |
| getDeal | deals | SELECT by id |
| createDeal | deals | INSERT |
| updateDeal | deals | UPDATE |
| getFolders | folders | SELECT by deal_id |
| createFolder | folders | INSERT |
| updateFolder | folders | UPDATE |
| getFiles | files | SELECT by deal_id + folder_id |
| getAllFiles | files | SELECT by deal_id |
| getFileCount | files | COUNT by deal_id |
| createFileRecord | files | INSERT |
| uploadFile | storage + files | Upload to Supabase storage + INSERT |
| getRequests | diligence_requests | SELECT by deal_id |
| getAllRequests | diligence_requests | SELECT all for org (via deals) |
| createRequest | diligence_requests | INSERT |
| bulkCreateRequests | diligence_requests | INSERT (batch) |
| updateRequest | diligence_requests | UPDATE |
| getActivity | deal_activity | SELECT by org_id |
| logActivity | deal_activity | INSERT |
| getContacts | contacts | SELECT by org_id |
| getInsights | ai_insights | SELECT by deal_id (non-dismissed) |
### Supabase Edge Functions (called via fetch, not in api.ts)
- `folder-summary` — POST: generates AI summary for a folder
- `compute-deal-score` — POST: computes deal close probability score
- `generate-ic-memo` — POST: generates IC memo from deal documents
- `demo-login` — POST: creates demo session with seller/buyer role
---
## Feature Inventory by Page
### Routes (from App.tsx)
| Path | Component | Auth Required |
|------|-----------|---------------|
| `/auth` | Auth | No |
| `/` | Dashboard | Yes |
| `/deals` | DealRooms | Yes |
| `/deals/:id` | DealRoom | Yes |
| `/requests` | RequestList | Yes |
| `/analytics` | Analytics | Yes |
| `/ic-memos` | ICMemos | Yes |
| `/audit` | AuditLog | Yes |
| `/contacts` | Contacts | Yes |
| `/settings` | Settings | Yes |
| `/guide` | PlatformGuide | Yes |
| `*` | NotFound | No |
### Dashboard
- **Stats cards:** Active Rooms, Documents, Active Deals, Avg Close Probability
- **Active Deal Rooms list** (top 5) with stage badges, doc counts, links
- **Recent Activity feed** (last 8 events) with timestamps
- All data is LIVE from Supabase
### DealRoom (single deal view)
- **Header:** Deal name, stage badge, doc count, target company, back link
- **Tabs:** Documents | Request List
- **Documents tab:**
- Left sidebar: folder tree (hierarchical, expandable)
- Breadcrumb navigation
- **Atlas Folder Summary** panel (AI-generated, with refresh button and completeness score)
- File table: name, size, modified date, status badge, actions menu
- File upload (multi-file)
- Create folder (inline form, supports nesting under selected folder)
- **Request List tab:** Embedded `DealRequestsPanel` component (missing from dump)
- **Atlas AI sidebar** toggle — passes deal context (dealId, name, stage, docs, folder, completeness, recent files)
### DealRooms (list)
- Table with: Deal name + target company, Stage badge, Size ($M), IOI Date, LOI Date, Exclusivity countdown
- Search/filter
- Create new deal dialog (name, target company, size, stage)
- **Buyer filtering:** buyers only see deals that have diligence requests for their buyer_group
- Exclusivity countdown with color-coded warnings (expired/expiring)
### RequestList (cross-deal view)
- **Atlas Assessment Summary bar:** Total, Fulfilled, Partial, Missing counts
- Grouped by deal room, each expandable
- Per-request table columns: #, Section, Description, Priority, Atlas Status, Confidence bar, Buyer Comment (inline editable), Seller Comment (inline editable), Atlas Note
- **Buyer group tabs** — when requests have buyer_group, shows tab per group + "View All"
- **CSV Upload dialog** — parse CSV → preview → bulk import to selected deal
- **Buyer filtering:** buyers only see requests for their buyer_group
### Analytics
- **KPI row:** Deal Rooms, Total Documents, Engagement Events
- **Deal Close Probability table:** per-deal with diligence %, engagement %, red flags, recommendations, compute button
- **Buyer Engagement timeline:** recent events with event type, dwell time, page views
- Calls Supabase edge function `compute-deal-score` to generate scores
- **Seller-only page** (not explicitly gated in code but designed for sellers)
### ICMemos
- **Left panel:** Generate new memo (select deal → click Generate), List of all memos
- **Right panel:** Memo viewer with structured sections:
- Executive Summary, Business Model, Financial Analysis, Key Risks, Diligence Gaps, Valuation Considerations, Recommendation, Source Documents
- Memo statuses: Draft, In Review, Final
- Version tracking
- Calls Supabase edge function `generate-ic-memo`
### Contacts
- **HARDCODED mock data** — not connected to database
- Table: Name, Company, Email, Type (buyer/advisor/internal), Tags, Last Active
- Search bar (not functional)
- Add Contact button (not functional)
### AuditLog
- Full activity log from `deal_activity` table
- Filterable by action/resource name
- Color-coded action badges (view, upload, download, NDA signed, etc.)
- Shows: Timestamp, Action, Resource, Details
### Settings
- **Sidebar navigation** with sections:
- **Profile** — name, email, title, phone (LIVE from profiles table)
- **Organization** — org name (LIVE)
- **Team Members** — placeholder ("coming soon")
- **Security** — toggle switches for MFA, IP allowlisting, session timeout, download watermarking, view-only mode (MOCK — toggles don't persist)
- **Notifications** — placeholder
- **Integrations** — Salesforce, HubSpot, Affinity, DocuSign, Slack (MOCK — all "not connected", configure buttons non-functional)
- **Workflows** — 4 sample rules with triggers/actions (MOCK — toggles don't persist)
- **Appearance** — placeholder
### Auth
- Email/password login and signup (via Supabase Auth)
- On signup: auto-creates organization and assigns owner role
- On first login without org: auto-creates org
- **Demo login buttons:** Seller Demo / Buyer Demo (calls `demo-login` edge function)
- Right panel: marketing copy about the platform
### PlatformGuide
- Comprehensive documentation page with accordion sections
- Covers: Overview, Dashboard, Deal Rooms, Request Lists, Analytics, IC Memos, Contacts, Atlas AI, Audit Log, Settings, Security
- Table of contents with anchor links
- Role badges (Seller/Buyer/Both) per section
---
## Atlas AI Capabilities
Atlas AI is referenced throughout but the core components (`AtlasSidebar`, `AtlasGlobalChat`) are **missing from the dump**. Based on usage:
1. **Deal Room Sidebar** — Context-aware chat panel receiving:
- dealId, dealName, stage, totalDocs, currentFolder, completeness, recentFiles
2. **Folder Summaries** — via edge function `folder-summary`
3. **Diligence Request Assessment** — auto-status with confidence scores + notes
4. **Deal Score Computation** — via edge function `compute-deal-score`
5. **IC Memo Generation** — via edge function `generate-ic-memo`
6. **AI Insights** — stored in `ai_insights` table, shown on dashboard (code references but UI not fully visible)
7. **Document AI Processing** — files have `ai_summary` and `ai_tags` fields
---
## What's Real vs Mock/Placeholder
### Real (connected to Supabase)
- Authentication (email/password + demo login)
- Organization creation + role assignment
- Deal CRUD (create, read, update)
- Folder CRUD (create, read, tree structure)
- File upload to Supabase storage + metadata
- Diligence request CRUD + bulk CSV import
- Inline buyer/seller comments on requests
- Activity/audit log (read + write)
- Profile management
- AI edge functions (folder summary, deal score, IC memo generation)
- IC Memo CRUD + viewer
### Mock/Placeholder
- **Contacts page** — entirely hardcoded data
- **Settings > Security** — toggle switches don't persist
- **Settings > Integrations** — CRM buttons are non-functional
- **Settings > Workflows** — rules are hardcoded, toggles don't persist
- **Settings > Team Members, Notifications, Appearance** — "coming soon"
- **Buyer engagement tracking** — table exists but no code writing to it
- **NDA records** — table exists but no UI for NDA flow
- **Tasks** — table exists but no dedicated UI
- **Workflow rules** — table exists but no execution engine
- **AI Insights dismissal** — read from DB but no dismiss UI visible
### Missing Components (not in dump)
- `AppLayout` — main layout shell with sidebar navigation
- `AppShell` — possibly alternate layout
- `AtlasGlobalChat` — global AI chat component
- `AtlasSidebar` — deal-scoped AI sidebar
- `DealRequestsPanel` — embedded request list for deal room
- `NavLink` — navigation link component
- `useAuth` hook
- `useOrganization` hook
- All `ui/` shadcn components (Button, Dialog, Tabs, etc.)
---
## Key Architectural Observations
1. **Multi-tenant by design** — everything scoped to `organization_id`
2. **Seller/Buyer distinction** is thin — just role mapping, not separate user types
3. **AI is the differentiator** — Atlas does diligence assessment, folder summarization, deal scoring, IC memo generation
4. **Buyer group concept** — requests can be tagged per buyer group, enabling multi-buyer processes
5. **Deal stages are IB-specific** — pipeline → LOI → initial review → due diligence → final negotiation → closed/dead
6. **File security features designed but not implemented** — watermarking, download disable, sensitivity flags are in the schema but UI is minimal