forked from quic-issues/427e7578-d7bf-49c8-aee9-2dd999e25316
feat: add combined codebase
This commit is contained in:
102
PLAN.md
Normal file
102
PLAN.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Plan: Combined P2P Polling App
|
||||
|
||||
## Overview
|
||||
Merge the three subfolder projects into a single TypeScript + Yjs + Vite application at the repo root, combining the best features from each.
|
||||
|
||||
## Technology Choices
|
||||
- **Language:** TypeScript (from project 3) with strict mode
|
||||
- **CRDT:** Yjs + y-webrtc + y-indexeddb (from projects 1 & 3)
|
||||
- **Build:** Vite (shared by all)
|
||||
- **Package manager:** npm
|
||||
|
||||
## Feature Superset
|
||||
From **project 1** (group-efa16e66):
|
||||
- Collaborative title editing via Y.Text (real-time character-level sync)
|
||||
- Delete options
|
||||
- Diff-rendering for poll list (reuse DOM elements)
|
||||
- Peer count display via awareness
|
||||
- Share section with copy-to-clipboard
|
||||
|
||||
From **project 2** (proposal-8835ffc9):
|
||||
- Deadline/timer system (2-minute voting window with countdown)
|
||||
- Duplicate detection (case-insensitive)
|
||||
|
||||
From **project 3** (proposal-88461784):
|
||||
- TypeScript types & strict mode
|
||||
- Modular architecture (state, sync, render, identity, app layers)
|
||||
- IndexedDB persistence (offline support)
|
||||
- Online/offline connection tracking
|
||||
- Input validation (max lengths, empty checks)
|
||||
- HTML escaping for XSS prevention
|
||||
- ViewModel pattern for clean render layer
|
||||
|
||||
## Data Model (Yjs)
|
||||
```
|
||||
Y.Doc
|
||||
├── poll-meta (Y.Map<string>)
|
||||
│ └── title → Y.Text (collaborative editing from project 1)
|
||||
├── poll-options (Y.Map<OptionRecord>)
|
||||
│ └── [optionId] → { id, label, createdAt, createdBy }
|
||||
├── poll-votes (Y.Map<string>)
|
||||
│ └── [userId] → optionId (single vote per user)
|
||||
└── poll-deadline (Y.Map<any>)
|
||||
└── deadline → number | null (timestamp, from project 2)
|
||||
```
|
||||
|
||||
## Architecture & File Structure
|
||||
```
|
||||
/
|
||||
├── index.html
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── vite.config.ts (if needed for any plugins)
|
||||
├── src/
|
||||
│ ├── main.ts (entry: mount app)
|
||||
│ ├── app.ts (orchestrator: init sync, bind events, manage state)
|
||||
│ ├── identity.ts (getUserId with localStorage persistence)
|
||||
│ ├── state.ts (types, pure functions, ViewModel creation)
|
||||
│ ├── sync.ts (Yjs doc, WebRTC provider, IndexedDB, connection status)
|
||||
│ ├── render.ts (DOM rendering with escapeHtml, diff-rendering for options)
|
||||
│ ├── components/
|
||||
│ │ ├── PollTitle.ts (collaborative title input bound to Y.Text)
|
||||
│ │ ├── PollList.ts (diff-rendered option list with sorting)
|
||||
│ │ ├── PollOption.ts (single option: vote bar, vote/delete buttons)
|
||||
│ │ ├── AddOption.ts (input + submit with validation & duplicate check)
|
||||
│ │ ├── StatusBar.ts (connection status + peer count)
|
||||
│ │ ├── ShareSection.ts (copy URL to clipboard)
|
||||
│ │ └── DeadlineTimer.ts (set deadline + countdown display, from project 2)
|
||||
│ └── styles.css (merged: project 1's design tokens + project 3's glassmorphism)
|
||||
```
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Step 1: Scaffold root project
|
||||
- Create `package.json` with dependencies: yjs, y-webrtc, y-indexeddb, vite, typescript
|
||||
- Create `tsconfig.json` (strict, ES2022, bundler resolution)
|
||||
- Create `index.html` entry point
|
||||
- Create `vite.config.ts` if needed
|
||||
|
||||
### Step 2: Core layer — identity.ts, state.ts, sync.ts
|
||||
- `identity.ts`: port from project 3 (getUserId)
|
||||
- `state.ts`: port types from project 3, add deadline types, add ViewModel with deadline/timer info, add vote percentage calculation from project 1
|
||||
- `sync.ts`: port from project 3, add Y.Text for title (from project 1), add poll-deadline map, add awareness tracking for peer count (from project 1)
|
||||
|
||||
### Step 3: App orchestrator — app.ts, main.ts
|
||||
- `app.ts`: port from project 3, add deadline handlers, add delete option handler, wire up all components
|
||||
- `main.ts`: minimal entry that calls initApp
|
||||
|
||||
### Step 4: Components
|
||||
- `PollTitle.ts`: port collaborative Y.Text editing from project 1, add TypeScript types
|
||||
- `AddOption.ts`: merge project 1 (UI/animation) + project 2 (duplicate detection) + project 3 (validation)
|
||||
- `PollOption.ts`: port from project 1 (vote bar, percentage, delete button), add TypeScript
|
||||
- `PollList.ts`: port diff-rendering from project 1, add TypeScript
|
||||
- `StatusBar.ts`: merge project 1 (peer count) + project 3 (online/offline status)
|
||||
- `ShareSection.ts`: port from project 1, add TypeScript
|
||||
- `DeadlineTimer.ts`: new component porting project 2's deadline/countdown logic to Yjs
|
||||
|
||||
### Step 5: Styling
|
||||
- Merge CSS: use project 1's design tokens and typography as base, incorporate project 3's glassmorphism panel effects, add timer-specific styles from project 2
|
||||
|
||||
### Step 6: Cleanup
|
||||
- Remove three subfolders (after confirming with user)
|
||||
- Update root README.md
|
||||
Reference in New Issue
Block a user