Files
DocNest/README.md

241 lines
7.8 KiB
Markdown

# Real-Time Collaboration Platform
A full-stack real-time collaborative application supporting text editing and Kanban boards. Built with React, Go, Yjs CRDTs, and WebSockets.
## Features
- **Collaborative Text Editor**: Real-time document editing with TipTap
- **Collaborative Kanban Boards**: Drag-and-drop task management
- **User Authentication**: OAuth2 login (Google, GitHub)
- **Document Sharing**: Share documents with users or via public links
- **Offline Support**: IndexedDB persistence for offline editing
- **User Presence**: Live cursors and user awareness
## Tech Stack
**Frontend:** React 19, TypeScript, Vite, TipTap, Yjs, y-websocket, y-indexeddb
**Backend:** Go 1.25, Gin, Gorilla WebSocket, PostgreSQL 16
**Infrastructure:** Docker Compose
## Quick Start
### Prerequisites
- Node.js 18+, npm
- Go 1.25+
- Docker & Docker Compose
### Setup
1. **Clone and configure environment**
```bash
git clone <repo-url>
cd realtime-collab
# Setup environment files
cp .env.example .env
cp backend/.env.example backend/.env
# Edit .env files with your configuration
# Minimum required: DATABASE_URL, JWT_SECRET
```
2. **Start infrastructure**
```bash
docker-compose up -d
```
3. **Run backend**
```bash
cd backend
go mod download
go run cmd/server/main.go
# Server runs on http://localhost:8080
```
4. **Run frontend**
```bash
cd frontend
npm install
npm run dev
# App runs on http://localhost:5173
```
## Architecture
### System Overview
```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Browser │◄────────►│ Go Backend │◄────────►│ PostgreSQL │
│ │ │ │ │ │
│ React + Yjs │ WS+HTTP │ Gin + Hub │ SQL │ Documents │
│ TipTap │ │ WebSocket │ │ Users │
│ IndexedDB │ │ REST API │ │ Sessions │
└─────────────┘ └──────────────┘ └─────────────┘
```
### Real-Time Collaboration Flow
```
Client A Backend Hub Client B
│ │ │
│──1. Edit document──────────►│ │
│ (Yjs binary update) │ │
│ │──2. Broadcast update────►│
│ │ │
│ │◄─3. Edit document────────│
│◄─4. Broadcast update───────│ │
│ │ │
▼ ▼ ▼
[Apply CRDT merge] [Relay only] [Apply CRDT merge]
```
### Authentication Flow
```
User OAuth Provider Backend Database
│ │ │ │
│──1. Click login───────►│ │ │
│◄─2. Auth page──────────│ │ │
│──3. Approve───────────►│ │ │
│ │──4. Callback──────►│ │
│ │ │──5. Create user───►│
│ │ │◄──────────────────│
│◄─6. JWT token + cookie─┤◄──────────────────│ │
```
## Project Structure
```
realtime-collab/
├── backend/
│ ├── cmd/server/ # Entry point
│ ├── internal/
│ │ ├── auth/ # JWT & OAuth middleware
│ │ ├── handlers/ # HTTP/WebSocket handlers
│ │ ├── hub/ # WebSocket hub & rooms
│ │ ├── models/ # Domain models
│ │ └── store/ # PostgreSQL data layer
│ └── scripts/init.sql # Database schema
├── frontend/
│ ├── src/
│ │ ├── api/ # REST API client
│ │ ├── components/ # React components
│ │ ├── hooks/ # Custom hooks
│ │ ├── lib/yjs.ts # Yjs setup
│ │ └── pages/ # Page components
└── docker-compose.yml # PostgreSQL & Redis
```
## Key Endpoints
### REST API
- `POST /api/auth/google` - Google OAuth login
- `POST /api/auth/github` - GitHub OAuth login
- `GET /api/auth/me` - Get current user
- `POST /api/auth/logout` - Logout
- `GET /api/documents` - List all documents
- `POST /api/documents` - Create document
- `GET /api/documents/:id` - Get document
- `PUT /api/documents/:id/state` - Update Yjs state
- `DELETE /api/documents/:id` - Delete document
- `POST /api/documents/:id/shares` - Share with user
- `POST /api/documents/:id/share-link` - Create public link
### WebSocket
- `GET /ws/:roomId` - Real-time sync endpoint
## Environment Variables
### Backend (.env)
```bash
PORT=8080
DATABASE_URL=postgres://user:pass@localhost:5432/collaboration?sslmode=disable
JWT_SECRET=your-secret-key-here
FRONTEND_URL=http://localhost:5173
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000
# OAuth (optional)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
```
### Docker (.env in root)
```bash
POSTGRES_USER=collab
POSTGRES_PASSWORD=your-secure-password
POSTGRES_DB=collaboration
```
## Development Commands
### Backend
```bash
cd backend
go run cmd/server/main.go # Run server
go test ./... # Run tests
go test -v ./internal/handlers # Run handler tests
go build -o server cmd/server/main.go # Build binary
```
### Frontend
```bash
cd frontend
npm run dev # Dev server
npm run build # Production build
npm run lint # Lint code
```
### Database
```bash
docker-compose down -v # Reset database
docker-compose up -d # Start fresh
```
## How It Works
### CRDT-Based Collaboration
- **Yjs** provides Conflict-free Replicated Data Types (CRDTs)
- Multiple users edit simultaneously without conflicts
- Changes merge automatically, no manual conflict resolution
- Works offline, syncs when reconnected
### Backend as Message Broker
- Backend doesn't understand Yjs data structure
- Simply broadcasts binary updates to all clients in a room
- All conflict resolution happens client-side via Yjs
- Rooms are isolated by document ID
### Data Flow
1. User edits → Yjs generates binary update
2. Update sent via WebSocket to backend
3. Backend broadcasts to all clients in room
4. Each client's Yjs applies and merges update
5. IndexedDB persists state locally
6. Periodic backup to PostgreSQL (optional)
## Testing
The backend uses `testify/suite` for organized testing:
```bash
go test ./internal/handlers # All handler tests
go test -v ./internal/handlers -run TestDocumentHandler # Specific suite
```
## Database Schema
- **documents**: Document metadata and Yjs state (BYTEA)
- **users**: OAuth user profiles
- **sessions**: JWT tokens with expiration
- **shares**: User-to-user document sharing
- **share_links**: Public shareable links
## License
MIT License
## Acknowledgments
- [Yjs](https://github.com/yjs/yjs) - CRDT framework
- [TipTap](https://tiptap.dev/) - Collaborative editor
- [Gin](https://gin-gonic.com/) - Go web framework