Skip to content

Commit 02835c4

Browse files
authored
Update README.md
1 parent fac3f37 commit 02835c4

1 file changed

Lines changed: 158 additions & 161 deletions

File tree

README.md

Lines changed: 158 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ The key feature of ResCanvas is defined by having all drawings stored persistent
2828
* Real time collaboration using Socket.IO for low latency stroke broadcasting, user notifications, and user activity communication with JWT-protected Socket.IO connections
2929

3030
## Detailed architecture and concepts
31-
This section expands on the high-level overview and documents the key design concepts, data model, and important theory behind ResCanvas.
32-
33-
### Architectural components
3431
Our application consists of several major components.
3532

3633
The first one is the **frontend (React)**, which handles drawing input, local smoothing/coalescing of strokes, UI state (tools, color, thickness), optimistic local rendering, and Socket.IO for real-time updates. Thus the frontend handles the user facing side of ResCanvas and ensures a smooth UX while ensuring communication between this frontend layer and the backend. This layer also handles the storage of auth tokens in `localStorage` and its API wrappers (like `frontend/src/api/`) automatically attach JWT access tokens to all protected requests as well. The most important aspect of this layer in terms of security is that the frontend does not perform authentication or authorization logic - it simply presents credentials and tokens to the backend.
@@ -111,158 +108,6 @@ All protected routes and Socket.IO handlers use the following decorators:
111108
- **Registration**: `POST /auth/register` — Creates new user account with password hashing.
112109
- **Current User**: `GET /auth/me` — Returns authenticated user's profile (requires valid access token).
113110

114-
## Important endpoints
115-
- Create/list rooms: POST/GET `/rooms`
116-
- Room details: GET `/rooms/<roomId>`
117-
- Post stroke: POST `/rooms/<roomId>/strokes` (requires auth and room access)
118-
- Get strokes: GET `/rooms/<roomId>/strokes` (works with or without auth but returns membership-scoped data when authenticated)
119-
- Undo/redo/clear: `/rooms/<roomId>/undo`, `/rooms/<roomId>/redo`, `/rooms/<roomId>/clear`
120-
121-
For secure rooms (type `secure`) strokes must be signed client-side; the backend validates signatures in `submit_room_line.py`.
122-
123-
## API for External Applications
124-
ResCanvas provides a versioned REST API (`/api/v1/*`) for external applications to integrate collaborative drawing functionality. This generalized API layer allows developers to build third-party apps, mobile clients, integrations, and automation tools on top of ResCanvas.
125-
126-
### Canvas API Features
127-
128-
**Canvas API** (`/api/v1/canvases/*`) - Generic, RESTful canvas management
129-
- Decoupled from frontend-specific terminology
130-
- Consolidated endpoint structure (e.g., `/history/*` for undo/redo operations)
131-
- Proper HTTP method semantics (DELETE for clearing, not POST)
132-
- Uses `canvasId` parameter for broader applicability
133-
- **See**: [API_REFERENCE.md](./API_REFERENCE.md) for complete documentation
134-
135-
**Consolidated History Operations**:
136-
- `/api/v1/canvases/{canvasId}/history/undo` - Undo last action
137-
- `/api/v1/canvases/{canvasId}/history/redo` - Redo action
138-
- `/api/v1/canvases/{canvasId}/history/status` - Get undo/redo status
139-
- `/api/v1/canvases/{canvasId}/history/reset` - Reset history
140-
- `DELETE /api/v1/canvases/{canvasId}/strokes` - Clear canvas (RESTful)
141-
142-
**Proper HTTP Method Usage**:
143-
- DELETE for clearing strokes
144-
- PATCH for updates, DELETE for removals
145-
146-
### Versioned API Endpoints
147-
All API v1 endpoints are prefixed with `/api/v1` as shown below.
148-
149-
**Authentication** (`/api/v1/auth/*`):
150-
- `POST /api/v1/auth/register` — Register new user
151-
- `POST /api/v1/auth/login` — Login and obtain JWT token
152-
- `POST /api/v1/auth/refresh` — Refresh access token
153-
- `POST /api/v1/auth/logout` — Logout and invalidate tokens
154-
- `GET /api/v1/auth/me` — Get current user info
155-
- `POST /api/v1/auth/change-password` — Change password
156-
157-
**Canvases** (`/api/v1/canvases/*`) - **RECOMMENDED**:
158-
- `POST /api/v1/canvases` — Create new canvas
159-
- `GET /api/v1/canvases` — List accessible canvases
160-
- `GET /api/v1/canvases/{id}` — Get canvas details
161-
- `PATCH /api/v1/canvases/{id}` — Update canvas settings
162-
- `DELETE /api/v1/canvases/{id}` — Delete canvas
163-
- `POST /api/v1/canvases/{id}/strokes` — Add stroke to canvas
164-
- `GET /api/v1/canvases/{id}/strokes` — Get all canvas strokes
165-
- `DELETE /api/v1/canvases/{id}/strokes` — Clear canvas
166-
- `POST /api/v1/canvases/{id}/history/undo` — Undo last stroke
167-
- `POST /api/v1/canvases/{id}/history/redo` — Redo undone stroke
168-
- `GET /api/v1/canvases/{id}/history/status` — Get undo/redo status
169-
- `POST /api/v1/canvases/{id}/history/reset` — Reset history
170-
- `POST /api/v1/canvases/{id}/share` — Share canvas with users
171-
- `GET /api/v1/canvases/{id}/members` — Get canvas members
172-
- `POST /api/v1/canvases/{id}/leave` — Leave shared canvas
173-
- `POST /api/v1/canvases/{id}/invite` — Invite users to canvas
174-
175-
**Collaboration** (`/api/v1/collaborations/*`):
176-
- `GET /api/v1/collaborations/invitations` — List pending invitations
177-
- `POST /api/v1/collaborations/invitations/{id}/accept` — Accept invitation
178-
- `POST /api/v1/collaborations/invitations/{id}/decline` — Decline invitation
179-
180-
**Notifications** (`/api/v1/notifications/*`):
181-
- `GET /api/v1/notifications` — List notifications
182-
- `POST /api/v1/notifications/{id}/mark-read` — Mark as read
183-
- `DELETE /api/v1/notifications/{id}` — Delete notification
184-
- `DELETE /api/v1/notifications` — Clear all notifications
185-
- `GET /api/v1/notifications/preferences` — Get preferences
186-
- `PATCH /api/v1/notifications/preferences` — Update preferences
187-
188-
**Users** (`/api/v1/users/*`):
189-
- `GET /api/v1/users/search?q={query}` — Search users
190-
- `GET /api/v1/users/suggest` — Get user suggestions
191-
192-
### Testing the API
193-
Comprehensive test suites are available as well:
194-
195-
```bash
196-
# Backend API v1 tests (Canvas API)
197-
cd backend
198-
pytest tests/test_api_v1_canvases.py -v
199-
200-
# All API v1 tests
201-
pytest tests/test_api_v1*.py -v
202-
```
203-
204-
### Quick Example: Canvas API
205-
```bash
206-
# Login
207-
TOKEN=$(curl -X POST http://localhost:10010/api/v1/auth/login \
208-
-H "Content-Type: application/json" \
209-
-d '{"username":"alice","password":"password123"}' \
210-
| jq -r '.token')
211-
212-
# Create canvas
213-
CANVAS_ID=$(curl -X POST http://localhost:10010/api/v1/canvases \
214-
-H "Authorization: Bearer $TOKEN" \
215-
-H "Content-Type: application/json" \
216-
-d '{"name":"My Canvas","type":"public"}' \
217-
| jq -r '.room.id')
218-
219-
# Add stroke
220-
curl -X POST http://localhost:10010/api/v1/canvases/$CANVAS_ID/strokes \
221-
-H "Authorization: Bearer $TOKEN" \
222-
-H "Content-Type: application/json" \
223-
-d '{
224-
"stroke": {
225-
"drawingId": "stroke-123",
226-
"color": "#FF0000",
227-
"lineWidth": 3,
228-
"pathData": [{"x":10,"y":20},{"x":30,"y":40}],
229-
"timestamp": 1704067200000,
230-
"user": "alice"
231-
}
232-
}'
233-
234-
# Get strokes
235-
curl -X GET http://localhost:10010/api/v1/canvases/$CANVAS_ID/strokes \
236-
-H "Authorization: Bearer $TOKEN"
237-
238-
# Undo last action
239-
curl -X POST http://localhost:10010/api/v1/canvases/$CANVAS_ID/history/undo \
240-
-H "Authorization: Bearer $TOKEN" \
241-
-H "Content-Type: application/json" \
242-
-d '{}'
243-
244-
# Clear canvas
245-
curl -X DELETE http://localhost:10010/api/v1/canvases/$CANVAS_ID/strokes \
246-
-H "Authorization: Bearer $TOKEN"
247-
```
248-
249-
### Contributing to the API
250-
251-
We welcome contributions! The API layer is designed to be extended with new endpoints. Please see `CONTRIBUTING.md` for guidelines before you start.
252-
253-
## Key configuration (backend)
254-
See `backend/config.py` and set the following environment variables as appropriate (examples shown in the repository's `.env` usage):
255-
- `MONGO_ATLAS_URI` / `MONGO_URI` — MongoDB connection string
256-
- `JWT_SECRET` — HMAC secret for signing access tokens
257-
- `ACCESS_TOKEN_EXPIRES_SECS`, `REFRESH_TOKEN_EXPIRES_SECS` — token lifetimes
258-
- `REFRESH_TOKEN_COOKIE_NAME`, `REFRESH_TOKEN_COOKIE_SECURE`, `REFRESH_TOKEN_COOKIE_SAMESITE`
259-
- `ROOM_MASTER_KEY_B64` — used to (re)wrap room keys for private/secure rooms
260-
- `SIGNER_PUBLIC_KEY`, `SIGNER_PRIVATE_KEY`, `RECIPIENT_PUBLIC_KEY` — used when committing strokes via the GraphQL service
261-
262-
The code loads environment variables via `python-dotenv` in `backend/config.py`.
263-
264-
---
265-
266111
# ResCanvas Setup Guide
267112
ResCanvas is a decentralized collaborative drawing platform that integrates **ResilientDB**, **MongoDB**, and **Redis** for data consistency, caching, and persistence.
268113
This guide provides complete instructions to deploy ResCanvas locally, including setup for the cache layer, backend, and frontend.
@@ -426,17 +271,169 @@ npm start
426271
427272
---
428273

429-
## Authentication examples (curl):
274+
# Important endpoints
275+
- Create/list rooms: POST/GET `/rooms`
276+
- Room details: GET `/rooms/<roomId>`
277+
- Post stroke: POST `/rooms/<roomId>/strokes` (requires auth and room access)
278+
- Get strokes: GET `/rooms/<roomId>/strokes` (works with or without auth but returns membership-scoped data when authenticated)
279+
- Undo/redo/clear: `/rooms/<roomId>/undo`, `/rooms/<roomId>/redo`, `/rooms/<roomId>/clear`
280+
281+
For secure rooms (type `secure`) strokes must be signed client-side; the backend validates signatures in `submit_room_line.py`.
282+
283+
# API for External Applications
284+
ResCanvas provides a versioned REST API (`/api/v1/*`) for external applications to integrate collaborative drawing functionality. This generalized API layer allows developers to build third-party apps, mobile clients, integrations, and automation tools on top of ResCanvas.
285+
286+
## Canvas API Features
287+
288+
**Canvas API** (`/api/v1/canvases/*`) - Generic, RESTful canvas management
289+
- Decoupled from frontend-specific terminology
290+
- Consolidated endpoint structure (e.g., `/history/*` for undo/redo operations)
291+
- Proper HTTP method semantics (DELETE for clearing, not POST)
292+
- Uses `canvasId` parameter for broader applicability
293+
- **See**: [API_REFERENCE.md](./API_REFERENCE.md) for complete documentation
294+
295+
**Consolidated History Operations**:
296+
- `/api/v1/canvases/{canvasId}/history/undo` - Undo last action
297+
- `/api/v1/canvases/{canvasId}/history/redo` - Redo action
298+
- `/api/v1/canvases/{canvasId}/history/status` - Get undo/redo status
299+
- `/api/v1/canvases/{canvasId}/history/reset` - Reset history
300+
- `DELETE /api/v1/canvases/{canvasId}/strokes` - Clear canvas (RESTful)
301+
302+
**Proper HTTP Method Usage**:
303+
- DELETE for clearing strokes
304+
- PATCH for updates, DELETE for removals
305+
306+
## Versioned API Endpoints
307+
All API v1 endpoints are prefixed with `/api/v1` as shown below.
308+
309+
**Authentication** (`/api/v1/auth/*`):
310+
- `POST /api/v1/auth/register` — Register new user
311+
- `POST /api/v1/auth/login` — Login and obtain JWT token
312+
- `POST /api/v1/auth/refresh` — Refresh access token
313+
- `POST /api/v1/auth/logout` — Logout and invalidate tokens
314+
- `GET /api/v1/auth/me` — Get current user info
315+
- `POST /api/v1/auth/change-password` — Change password
316+
317+
**Canvases** (`/api/v1/canvases/*`) - **RECOMMENDED**:
318+
- `POST /api/v1/canvases` — Create new canvas
319+
- `GET /api/v1/canvases` — List accessible canvases
320+
- `GET /api/v1/canvases/{id}` — Get canvas details
321+
- `PATCH /api/v1/canvases/{id}` — Update canvas settings
322+
- `DELETE /api/v1/canvases/{id}` — Delete canvas
323+
- `POST /api/v1/canvases/{id}/strokes` — Add stroke to canvas
324+
- `GET /api/v1/canvases/{id}/strokes` — Get all canvas strokes
325+
- `DELETE /api/v1/canvases/{id}/strokes` — Clear canvas
326+
- `POST /api/v1/canvases/{id}/history/undo` — Undo last stroke
327+
- `POST /api/v1/canvases/{id}/history/redo` — Redo undone stroke
328+
- `GET /api/v1/canvases/{id}/history/status` — Get undo/redo status
329+
- `POST /api/v1/canvases/{id}/history/reset` — Reset history
330+
- `POST /api/v1/canvases/{id}/share` — Share canvas with users
331+
- `GET /api/v1/canvases/{id}/members` — Get canvas members
332+
- `POST /api/v1/canvases/{id}/leave` — Leave shared canvas
333+
- `POST /api/v1/canvases/{id}/invite` — Invite users to canvas
334+
335+
**Collaboration** (`/api/v1/collaborations/*`):
336+
- `GET /api/v1/collaborations/invitations` — List pending invitations
337+
- `POST /api/v1/collaborations/invitations/{id}/accept` — Accept invitation
338+
- `POST /api/v1/collaborations/invitations/{id}/decline` — Decline invitation
339+
340+
**Notifications** (`/api/v1/notifications/*`):
341+
- `GET /api/v1/notifications` — List notifications
342+
- `POST /api/v1/notifications/{id}/mark-read` — Mark as read
343+
- `DELETE /api/v1/notifications/{id}` — Delete notification
344+
- `DELETE /api/v1/notifications` — Clear all notifications
345+
- `GET /api/v1/notifications/preferences` — Get preferences
346+
- `PATCH /api/v1/notifications/preferences` — Update preferences
347+
348+
**Users** (`/api/v1/users/*`):
349+
- `GET /api/v1/users/search?q={query}` — Search users
350+
- `GET /api/v1/users/suggest` — Get user suggestions
351+
352+
## Testing the API
353+
Comprehensive test suites are available as well:
354+
355+
```bash
356+
# Backend API v1 tests (Canvas API)
357+
cd backend
358+
pytest tests/test_api_v1_canvases.py -v
359+
360+
# All API v1 tests
361+
pytest tests/test_api_v1*.py -v
362+
```
363+
364+
## Quick Example: Canvas API
365+
```bash
366+
# Login
367+
TOKEN=$(curl -X POST http://localhost:10010/api/v1/auth/login \
368+
-H "Content-Type: application/json" \
369+
-d '{"username":"alice","password":"password123"}' \
370+
| jq -r '.token')
371+
372+
# Create canvas
373+
CANVAS_ID=$(curl -X POST http://localhost:10010/api/v1/canvases \
374+
-H "Authorization: Bearer $TOKEN" \
375+
-H "Content-Type: application/json" \
376+
-d '{"name":"My Canvas","type":"public"}' \
377+
| jq -r '.room.id')
378+
379+
# Add stroke
380+
curl -X POST http://localhost:10010/api/v1/canvases/$CANVAS_ID/strokes \
381+
-H "Authorization: Bearer $TOKEN" \
382+
-H "Content-Type: application/json" \
383+
-d '{
384+
"stroke": {
385+
"drawingId": "stroke-123",
386+
"color": "#FF0000",
387+
"lineWidth": 3,
388+
"pathData": [{"x":10,"y":20},{"x":30,"y":40}],
389+
"timestamp": 1704067200000,
390+
"user": "alice"
391+
}
392+
}'
393+
394+
# Get strokes
395+
curl -X GET http://localhost:10010/api/v1/canvases/$CANVAS_ID/strokes \
396+
-H "Authorization: Bearer $TOKEN"
397+
398+
# Undo last action
399+
curl -X POST http://localhost:10010/api/v1/canvases/$CANVAS_ID/history/undo \
400+
-H "Authorization: Bearer $TOKEN" \
401+
-H "Content-Type: application/json" \
402+
-d '{}'
403+
404+
# Clear canvas
405+
curl -X DELETE http://localhost:10010/api/v1/canvases/$CANVAS_ID/strokes \
406+
-H "Authorization: Bearer $TOKEN"
407+
```
408+
409+
## Contributing to the API
410+
411+
We welcome contributions! The API layer is designed to be extended with new endpoints. Please see `CONTRIBUTING.md` for guidelines before you start.
412+
413+
# Key configuration (backend)
414+
See `backend/config.py` and set the following environment variables as appropriate (examples shown in the repository's `.env` usage):
415+
- `MONGO_ATLAS_URI` / `MONGO_URI` — MongoDB connection string
416+
- `JWT_SECRET` — HMAC secret for signing access tokens
417+
- `ACCESS_TOKEN_EXPIRES_SECS`, `REFRESH_TOKEN_EXPIRES_SECS` — token lifetimes
418+
- `REFRESH_TOKEN_COOKIE_NAME`, `REFRESH_TOKEN_COOKIE_SECURE`, `REFRESH_TOKEN_COOKIE_SAMESITE`
419+
- `ROOM_MASTER_KEY_B64` — used to (re)wrap room keys for private/secure rooms
420+
- `SIGNER_PUBLIC_KEY`, `SIGNER_PRIVATE_KEY`, `RECIPIENT_PUBLIC_KEY` — used when committing strokes via the GraphQL service
421+
422+
The code loads environment variables via `python-dotenv` in `backend/config.py`.
423+
424+
---
425+
426+
# Authentication examples (curl):
430427
- Login to obtain access token (also sets refresh cookie):
431428
```
432429
curl -X POST http://127.0.0.1:10010/auth/login -H "Content-Type: application/json" -d '{"username":"testuser","password":"testpass"}'
433430
- Post a stroke (replace `<token>` and `<roomId>`):
434431
```
435432
curl -X POST http://127.0.0.1:10010/rooms/<roomId>/strokes -H "Content-Type: application/json" -H "Authorization: Bearer <token>" -d '{"drawingId":"d1","color":"#000","lineWidth":3,"pathData":[],"timestamp": 1696940000000}'
436433
437-
### Developer workflows and testing
434+
# Developer workflows and testing
438435
439-
#### Quick Start Testing
436+
## Quick Start Testing
440437
441438
ResCanvas has a comprehensive test suite with tests that are covering both the backend and frontend:
442439
@@ -451,7 +448,7 @@ ResCanvas has a comprehensive test suite with tests that are covering both the b
451448
./scripts/run_all_tests_unified.sh
452449
```
453450

454-
#### Test Suite Breakdown
451+
## Test Suite Breakdown
455452

456453
- **Backend Tests** (99 tests):
457454
- Unit tests: `pytest tests/unit/ -v`
@@ -466,7 +463,7 @@ ResCanvas has a comprehensive test suite with tests that are covering both the b
466463
- Playwright: `cd frontend && npx playwright test`
467464
- Tests auth, rooms, collaboration, drawing, error handling
468465

469-
#### CI/CD Integration
466+
## CI/CD Integration
470467

471468
**GitHub Actions workflows** automatically test every push and PR:
472469

@@ -481,7 +478,7 @@ ResCanvas has a comprehensive test suite with tests that are covering both the b
481478
- **Codecov uploads**: If the repository is private, set a `CODECOV_TOKEN` secret in Settings → Secrets → Actions. The workflows skip Codecov upload if the token is not defined.
482479
- **Manual trigger**: Actions → CI - Full Test Suite → Run workflow
483480

484-
## Contributors
481+
# Contributors
485482
* Henry Chou - Team Leader and Full Stack Developer
486483
* Varun Ringnekar - Full Stack Developer
487484
* Chris Ruan - Frontend Developer

0 commit comments

Comments
 (0)