VS Code dark theme처럼 보이는 익명 커뮤니티 PWA입니다. Next.js App Router, Tailwind CSS, Supabase PostgreSQL을 사용합니다.
- Node.js 20 이상
- npm 10 이상
- Supabase 프로젝트
- Vercel 계정
npm install
cp .env.example .env.local
npm run devSupabase SQL Editor에서 supabase/schema.sql을 먼저 실행한 뒤 .env.local에 값을 채우세요.
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-public-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
SERVER_HASH_SALT=replace-with-long-random-string
FORBIDDEN_WORDS=blocked-token
ADMIN_SECRET_KEY=replace-with-admin-secret현재 PC의 Node가 오래된 경우 Next.js가 실행되지 않을 수 있습니다. 화면만 보고 싶다면 preview.html을 브라우저에서 직접 열면 됩니다.
Explorer의 src/boards 아래 카테고리는 다음과 같습니다.
ALL: 전체 게시글Notice:src/notice아래의 관리자 공지Stared: Star 10개 이상 게시글GeneralHumorCJavaPython
각 폴더를 클릭하면 해당 카테고리 게시글만 조회합니다. ALL은 서버에서 board 필터를 생략해 전체 게시글을 가져옵니다.
게시글 목록은 10개 단위로 페이지 이동합니다. 성능을 위해 전체 개수 count는 하지 않고, 다음 페이지 존재 여부만 확인합니다.
게시글 상단의 const thread 정보 아래에 Star 섹션이 있습니다. Star 버튼은 FingerprintJS hash 기준으로 1명당 1회만 적용됩니다.
Star가 10개 이상인 글은 src/stared의 Stared 목록에서도 볼 수 있습니다.
- Explorer의
+ New File을 누릅니다. - Chrome prompt가 뜨지 않고 Explorer 안에 새 파일명이 생깁니다.
- VS Code에서 F2로 이름을 바꾸듯 Explorer의 파일명 입력칸에서 이름을 바꿉니다.
- 파일명이 공백이면 Commit이 막힙니다.
- 우측 에디터의 주석 블록 안에 내용을 작성합니다.
- 하단 Terminal의
Commit버튼을 누르면git add,git commit로그가 출력되고 Supabase DB에 저장됩니다.
내가 쓴 글은 아래 경로에서 확인할 수 있습니다.
/me
FingerprintJS visitor id 기준으로 현재 브라우저에서 작성한 글만 보여줍니다.
댓글의 reply 버튼을 누르면 터미널 입력이 대댓글 모드로 바뀝니다. 내 댓글에 대댓글이 달리면 우측 하단에 VS Code 알림창처럼 표시됩니다.
좌측 Activity Bar의 기존 EX 텍스트는 Explorer 이미지 아이콘으로 교체했습니다. 기능 없는 Search/Source Control 버튼은 제거했습니다. 아이콘 파일 위치는 아래입니다.
public/icons/explorer.svg
아이콘을 바꾸고 싶으면 같은 경로의 SVG를 교체하면 됩니다.
금칙어는 세 가지 방식으로 관리할 수 있습니다.
.env.local의FORBIDDEN_WORDS- 프로젝트 루트의
forbidden-words.txt - 관리자 페이지의 DB 금칙어 라이브러리
파일로 관리하려면 프로젝트 루트에 forbidden-words.txt를 만들고 한 줄에 하나씩 쓰면 됩니다.
blocked-token
spam-keyword기본 파일명 대신 다른 경로를 쓰고 싶다면 .env.local에 FORBIDDEN_WORDS_FILE을 지정하세요.
FORBIDDEN_WORDS_FILE=./config/forbidden-words.txt관리자 페이지는 아래 경로입니다.
/admin/internal-terminal
접근 제어는 ADMIN_SECRET_KEY 환경변수와 화면에서 입력한 Secret Key를 비교합니다.
관리자 페이지에서 할 수 있는 일:
- 모든 게시글의
report_count확인 src/notice공지사항 작성- 신고 수와 무관하게 강제 주석 처리
- DB 조회 목록에서 숨김 처리
- 숨김/주석 처리 복구
- 실시간에 가까운 Output 로그 모니터링
- Fingerprint hash 또는 IP hash 차단/해제
- DB 기반 금칙어 추가/활성화/비활성화
- 게시글, 댓글, 신고 수 및 런타임 상태 확인
로그 모니터링은 별도 Supabase Realtime 설정 없이 3.5초 간격 폴링으로 동작합니다.
- Supabase에서 새 프로젝트를 만듭니다.
SQL Editor를 열고supabase/schema.sql전체를 실행합니다.Project Settings > API에서 아래 값을 확인합니다.Project URLservice_role key
service_role key는 서버에서만 써야 합니다. 브라우저 코드에 직접 노출하면 안 됩니다.
이미 기존 테이블을 만든 상태라면 schema.sql의 새 컬럼/테이블 부분도 다시 실행하세요. if not exists 위주라 반복 실행해도 안전하게 구성했습니다.
git init
git add .
git commit -m "Initial code camouflage community"
git branch -M main
git remote add origin https://github.com/your-name/your-repo.git
git push -u origin mainnode_modules, .next, .env.local은 .gitignore에 포함되어 있으므로 올리지 않습니다.
- Vercel에서
Add New Project를 누릅니다. - GitHub 저장소를 선택합니다.
- Framework Preset은
Next.js로 둡니다. - Environment Variables에 아래 값을 추가합니다.
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-public-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
SERVER_HASH_SALT=long-random-production-salt
FORBIDDEN_WORDS=blocked-token
ADMIN_SECRET_KEY=long-random-admin-secretDeploy를 누릅니다.
- Explorer에서
General,Humor,C,Java,Python,ALL필터가 동작하는지 확인합니다. + New File로 탭 생성 후 TerminalCommit저장이 되는지 확인합니다.- 같은 브라우저에서 3분 안에 다시 작성하면
Build Timeout이 뜨는지 확인합니다. Debug를 5회 누적하면 글 본문이 투명도 0.1로 soft-delete 되는지 확인합니다./admin/internal-terminal에서 Secret Key 입력 후 게시글/로그/차단/금칙어 관리가 되는지 확인합니다.- 모바일/데스크톱 브라우저에서 앱 설치 후 standalone PWA로 열리는지 확인합니다.
public/manifest.json은 display: "standalone"으로 설정되어 있습니다. 앱 설치 후 실행하면 브라우저 주소창 없이 독립 실행형 앱처럼 열립니다.