Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI Privacy System

AI 기반 프라이버시 관리 시스템 백엔드 인프라입니다.

프로젝트 구조

ai-privacy-system/
  backend/
    collaboration-server/
      src/
        config/           # 환경변수 관리
        routes/           # API 라우트 (status, masking)
        db/               # PostgreSQL 연결
        storage/          # MinIO 스토리지 연결
        middlewares/      # HTTP 로거, JWT 인증
        services/         # 마스킹 서비스
        websocket/        # Socket.io 협업 처리
      .env.example        # 환경변수 템플릿
  docker-compose.yml      # 인프라 컨테이너 설정

기술 스택

분류 기술
Runtime Node.js + TypeScript
Framework Express v5
WebSocket Socket.io v4
Database PostgreSQL 16
Object Storage MinIO (S3 호환)
Cache Redis 7
Container Docker

시스템 구성 (3-way 통합)

서버 역할 주소
Django 메인 백엔드 (인증, 파일 업로드) localhost:8000
collaboration-server 실시간 협업, 마스킹 localhost:4000
React FE 프론트엔드 localhost:5173

시작하기

1. 환경변수 설정

cp backend/collaboration-server/.env.example backend/collaboration-server/.env

.env 파일을 열어 JWT_SECRET 등 값을 채워넣어.

2. 인프라 실행 (Docker 필요)

docker-compose up -d
서비스 주소
PostgreSQL localhost:5560
MinIO API localhost:9000
MinIO 콘솔 http://localhost:9001
Redis localhost:6379

MinIO 기본 계정: minioadmin / minioadmin

3. 서버 실행

cd backend/collaboration-server
npm install
npm run dev

4. 동작 확인

GET http://localhost:4000/status

응답:

{ "ok": true, "message": "collaboration-server is running" }

환경변수

변수 설명 기본값
PORT 서버 포트 4000
NODE_ENV 실행 환경 development
PG_HOST PostgreSQL 호스트 localhost
PG_PORT PostgreSQL 포트 5432
PG_USER PostgreSQL 유저 postgres
PG_PASSWORD PostgreSQL 비밀번호 postgres123
PG_DATABASE PostgreSQL DB명 ai_privacy
MINIO_ENDPOINT MinIO 호스트 localhost
MINIO_PORT MinIO 포트 9000
MINIO_ACCESS_KEY MinIO 액세스 키 minioadmin
MINIO_SECRET_KEY MinIO 시크릿 키 minioadmin
MINIO_BUCKET 기본 버킷 이름 documents
REDIS_HOST Redis 호스트 localhost
REDIS_PORT Redis 포트 6379
JWT_SECRET JWT 서명 키 (Django와 동일) -

주의: JWT_SECRET은 Django 서버와 동일한 값으로 설정해야 합니다.


사용 가이드

1. 개발 환경 시작

인프라 올리기

cd C:\dev\ai-privacy-system
docker-compose up -d
docker ps
# ai-postgres, ai-minio, ai-redis 세 컨테이너가 Up 상태여야 함

서버 실행

cd backend/collaboration-server
npm install          # 최초 1회
npm run dev          # ts-node-dev로 핫리로드 실행

서버가 http://localhost:4000 에서 시작됩니다.


2. HTTP API 사용법

파일 업로드/다운로드는 Django 서버(:8000)에서 처리합니다.

서버 상태 확인

curl http://localhost:4000/status
# { "ok": true, "message": "collaboration-server is running" }

텍스트 마스킹

curl -X POST http://localhost:4000/masking/text \
  -H "Content-Type: application/json" \
  -d '{"text": "홍길동 010-1234-5678 주민번호 901010-1234567"}'

응답:

{
  "original": "홍길동 010-1234-5678 주민번호 901010-1234567",
  "masked": "홍길동 010-****-**** 주민번호 901010-*******",
  "detections": [
    { "type": "전화번호", "original": "010-1234-5678", "masked": "010-****-****", "index": 4 },
    { "type": "주민등록번호", "original": "901010-1234567", "masked": "901010-*******", "index": 16 }
  ]
}

PII 탐지만 (마스킹 없이)

curl -X POST http://localhost:4000/masking/detect \
  -H "Content-Type: application/json" \
  -d '{"text": "이메일: user@example.com"}'

파일 마스킹

curl -X POST http://localhost:4000/masking/file \
  -F "file=@/path/to/document.txt"
# 마스킹된 파일 반환

지원 PII 유형: 주민등록번호, 전화번호, 이메일, 카드번호, 계좌번호, 여권번호, 운전면허번호, IP 주소


3. WebSocket 협업 사용법

Socket.io 클라이언트 기준 예시입니다.

JWT 인증 연결

WebSocket 연결 시 Django에서 발급한 JWT 토큰을 반드시 전달해야 합니다.

import { io } from "socket.io-client";

const socket = io("http://localhost:4000", {
  auth: { token: "Bearer eyJ..." }  // Django accessToken
});

socket.on("connect_error", (err) => {
  console.error("인증 실패:", err.message);
});

룸 입장

userIduserName은 JWT에서 자동으로 추출되므로 클라이언트가 보낼 필요 없습니다.

// 룸 입장
socket.emit("room:join", {
  roomId: "project-room-1",
  sessionToken: null  // 재연결 시 이전 sessionToken 전달
});

// 입장 확인 수신
socket.on("room:joined", ({ users, sessionToken, isReconnect }) => {
  console.log("현재 룸 유저:", users);
  localStorage.setItem("sessionToken", sessionToken); // 재연결용 보관
});

프레즌스 업데이트

// 내가 어느 영역에서 작업 중인지 알리기
socket.emit("presence:update", {
  roomId: "project-room-1",
  activeArea: "section-2",
  status: "active"  // "active" | "idle"
});

// 다른 유저 프레즌스 변경 수신
socket.on("presence:updated", (presence) => {
  console.log(`${presence.userName}${presence.activeArea} 작업 중`);
});

커서 동기화

// 커서 위치 전송
socket.emit("cursor:move", {
  roomId: "project-room-1",
  x: 120,
  y: 350,
  areaId: "section-2"
});

// 다른 유저 커서 수신
socket.on("cursor:moved", ({ userId, userName, x, y, areaId }) => {
  // 커서 렌더링
});

영역 잠금 & 편집

// 영역 잠금 요청
socket.emit("area:lock", {
  roomId: "project-room-1",
  areaId: "section-2"
});

// 잠금 결과 수신
socket.on("area:locked", ({ areaId, lock, denied }) => {
  if (denied) {
    console.log("이미 다른 사람이 편집 중");
  } else {
    // 잠금 성공 → 편집 가능
    socket.emit("area:change", {
      roomId: "project-room-1",
      areaId: "section-2",
      changes: { content: "수정된 내용" }
    });
  }
});

// 편집 완료 후 잠금 해제
socket.emit("area:unlock", {
  roomId: "project-room-1",
  areaId: "section-2"
});

재연결 처리

socket.on("connect", () => {
  const token = localStorage.getItem("sessionToken");
  if (token) {
    socket.emit("room:join", {
      roomId: "project-room-1",
      sessionToken: token  // 세션 복원 (10초 이내 재연결 시 상태 유지)
    });
  }
});

4. WebSocket 이벤트 전체 목록

Room

방향 이벤트 페이로드
C→S room:join { roomId, sessionToken? }
C→S room:leave { roomId }
S→C room:joined { users, sessionToken, isReconnect }
S→Room room:user-joined { user }
S→Room room:user-left { user }
S→Room room:reconnected { user }

Presence + Cursor

방향 이벤트 페이로드
C→S presence:update { roomId, activeArea, status }
C→S cursor:move { roomId, x, y, areaId }
S→C presence:sync 전체 프레즌스 맵
S→Room presence:updated presence 객체
S→Room cursor:moved { userId, userName, x, y, areaId }

Area

방향 이벤트 페이로드
C→S area:lock { roomId, areaId }
C→S area:unlock { roomId, areaId }
C→S area:change { roomId, areaId, changes }
S→C area:state-sync 전체 영역 상태
S→Room area:locked { areaId, lock, denied? }
S→Room area:unlocked { areaId }
S→Room area:changed { areaId, changes, userId }

5. MinIO 콘솔 (관리 UI)

브라우저에서 http://localhost:9001 접속

  • ID: minioadmin
  • PW: minioadmin

마스킹된 파일은 documents 버킷의 masked/{document_id}/{uuid}/ 경로에 저장됩니다.


6. 자주 쓰는 개발 시나리오

상황 해결
DB 테이블 확인 docker exec -it ai-postgres psql -U postgres -d ai_privacy -c "\dt"
PostgreSQL 직접 접속 psql -h localhost -p 5560 -U postgres -d ai_privacy
MinIO 버킷 초기화 안 됨 서버 재시작 (index.ts에서 자동 생성)
서버 재시작 후 룸 상태 사라짐 정상 동작 (인메모리, Redis 미연동)
WebSocket 인증 오류 JWT_SECRET이 Django와 동일한지 확인
포트 충돌 .env에서 PORT 변경

Releases

Packages

Contributors

Languages