TOAU 729 프로젝트 매니저(project.crowny.org:9730)에 4대 협업 기능 완성.
서버 테이블 추가:
teams (id, name, ownerId, members[{userId,role,joinedAt}], wallet, contact)shares (id, projectId, targetId, targetType, permission, sharedBy, at)messages (id, from, to, toType, projectId, text, type, read, at)GET/POST /api/teams, GET/PUT/DELETE /api/teams/:id, /members, /role, /projectsPOST /api/projects/:id/share, /unshare, GET /api/shared-projectsPOST /api/projects/:id/transfer (복사/소유권 모드)POST/GET /api/messages, /read, /thread/:userIdGET /api/projects/:id/contacts, POST /api/projects/:id/tip-messageprojectPermission(pj, uname) → owner | admin | write | read | null
hasPermission() 확장 — 멤버 역할 + 공유 권한 폴백으로 모든 기존 write 엔드포인트 자동 적용:
myPermission 응답 추가auth(token) 검증 (쿼리 ?token= 또는 Authorization 헤더)userId 바인딩onlineUsers: Map<username, Set<client>> 프레즌스 추적notify() → DB 저장 + 해당 사용자 WS 실시간 푸시wsPushUser(userId, event) 헬퍼/api/projects/:id/contacts: online: onlineUsers.has(uname), lastSeen 포함/api/presence 신규 — 현재 온라인 유저 목록handleWSEvent — presence/message/notification 타입 분기사이드바 툴바: 전체/내 것/팀/공유 필터 + 이름/생성일 정렬 토글
[1] 공유 전 user2 접근 → HTTP 403 ✅
[2] read 권한 공유 → share id 반환 ✅
[3] 공유 후 user2 접근 → myPermission=read ✅
[4] user2 PATCH (read) → HTTP 403 "관리자 이상" ✅
[5] admin 권한 업그레이드 → ok ✅
[6] user2 PATCH 재시도 → HTTP 200 ✅
[7] /api/presence → {"online":[]} ✅
/Users/ef/crowny-project/server.js (4200+ 줄)projectPermission(), permAtLeast(), canReadProject() — 427 부근hasPermission() 확장 — 1162 부근/api/projects/:id GET 권한 체크 — 3267 부근notify() + wsPushUser() — 4214 부근/Users/ef/crowny-project/public/js/app.js (2300+ 줄)loadProjects() 필터/정렬 툴바 — 213 부근connectWS() 토큰 포함 — 427 부근handleWSEvent() presence/message/notification — 461 부근ws npm 모듈 미설치로 브라우저 수동 테스트 필요/api/presence 온라인 목록: HTTP 테스트 시 WS 미연결로 빈 배열 — 프론트 통합 후 검증 필요CROWNY_VERSIONS.md에 자동 반영 예정canReadProject(pj, uname) / hasPermission(pj, uname, role) — 모든 새 엔드포인트에 적용할 것wsPushUser(userId, event) 사용onlineUsers.has(username) 로 조회