feat: add common utilities and feedback handling scripts

- Introduced common.js for shared functions including API calls, error reporting, and UI helpers.
- Implemented feedback.js for the feedback reporting page, including form handling and displaying feedback status.
- Added layout.js for managing galaxy and section layouts in the visualization.
- Created login.js for user authentication with session management.
- Developed search.js for term searching based on user input and synonyms.
- Implemented signup.js for user registration with validation and immediate login.
This commit is contained in:
jsahn
2026-10-06 23:14:45 +09:00
parent 04158ac442
commit 4e943700fc
62 changed files with 158771 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- 로그인 시 Apple container 런타임과 nursing-atlas 컨테이너를 기동하는 one-shot 에이전트.
__REMOTE_DIR__ 는 deploy-macmini.sh 가 치환한다. -->
<plist version="1.0">
<dict>
<key>Label</key><string>com.nursing-atlas.container</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/usr/local/bin/container system start; /usr/local/bin/container start nursing-atlas</string>
</array>
<key>RunAtLoad</key><true/>
<key>StandardOutPath</key><string>__REMOTE_DIR__/logs/container-boot.log</string>
<key>StandardErrorPath</key><string>__REMOTE_DIR__/logs/container-boot.log</string>
</dict>
</plist>
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# macmini(Apple container)로 배포: 소스 동기화 → 이미지 빌드 → 컨테이너 교체 → 부팅 시 자동 시작 등록.
#
# deploy/deploy-macmini.sh
#
# 저작권: 교재 PDF는 서버로 보내지 않는다 (PDF 추출은 개발 PC에서만).
#
# 환경변수: SSH_HOST(기본 macmini) PORT(기본 8088) REMOTE_DIR(기본 ~/Community_Nursing_Atlas)
set -euo pipefail
SSH_HOST="${SSH_HOST:-macmini}"
PORT="${PORT:-8088}"
NAME="nursing-atlas"
IMAGE="nursing-atlas:latest"
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
REMOTE_HOME="$(ssh "$SSH_HOST" 'echo $HOME')"
REMOTE_DIR="${REMOTE_DIR:-$REMOTE_HOME/Community_Nursing_Atlas}"
C=/usr/local/bin/container
echo "▶ 대상: $SSH_HOST:$REMOTE_DIR (포트 $PORT)"
[[ -f "$ROOT/data/atlas.json" ]] || { echo "data/atlas.json 이 없습니다. 먼저: .venv/bin/python -m pipeline.build"; exit 1; }
ssh "$SSH_HOST" "mkdir -p '$REMOTE_DIR'/{app/data,data,logs}"
echo "▶ 소스 동기화"
rsync -az --delete \
--include='/Dockerfile' --include='/requirements-server.txt' \
--include='/server/***' --include='/web/***' \
--include='/data/' --include='/data/atlas.json' \
--exclude='__pycache__' --exclude='*' \
"$ROOT/" "$SSH_HOST:$REMOTE_DIR/app/"
echo "▶ 이미지 빌드 및 컨테이너 교체"
ssh "$SSH_HOST" bash -s <<REMOTE
set -euo pipefail
$C system status >/dev/null 2>&1 || $C system start
cd "$REMOTE_DIR/app"
$C build -t $IMAGE -f Dockerfile .
$C stop $NAME >/dev/null 2>&1 || true
$C delete $NAME >/dev/null 2>&1 || true
$C run -d --name $NAME \\
-p 0.0.0.0:$PORT:8088 \\
-v "$REMOTE_DIR/data:/app/data" \\
-c 2 -m 1024M \\
$IMAGE
REMOTE
echo "▶ 부팅 시 자동 시작(launchd) 등록"
sed "s#__REMOTE_DIR__#$REMOTE_DIR#g" "$ROOT/deploy/com.nursing-atlas.container.plist" | \
ssh "$SSH_HOST" "cat > ~/Library/LaunchAgents/com.nursing-atlas.container.plist"
ssh "$SSH_HOST" "launchctl bootout gui/\$(id -u)/com.nursing-atlas.container 2>/dev/null; launchctl bootstrap gui/\$(id -u) ~/Library/LaunchAgents/com.nursing-atlas.container.plist 2>/dev/null || true"
echo "▶ 동작 확인"
for i in $(seq 1 30); do
if ssh "$SSH_HOST" "curl -fsS -o /dev/null http://127.0.0.1:$PORT/api/admin/me"; then
echo "✔ 실행 중: http://$SSH_HOST:$PORT"
echo " 교수자 로그인: /login (아이디·비밀번호는 관리 → 설정에서 변경. 처음 만든 계정은 컨테이너 로그에 한 번 표시됨)"
exit 0
fi
sleep 2
done
echo "✘ 응답이 없습니다. 로그: deploy/macmini.sh logs"; exit 1
+26
View File
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# macmini 컨테이너 관리 도우미
# deploy/macmini.sh status | logs | restart | stop | password(처음 만든 교수자 계정)
# deploy/macmini.sh feedback [--all] # 오류 신고 목록 (server.cli)
# deploy/macmini.sh cli show 12 # server.cli 명령 그대로 실행
# deploy/macmini.sh backup # DB를 로컬 backups/ 로 내려받기
set -euo pipefail
SSH_HOST="${SSH_HOST:-macmini}"
NAME="nursing-atlas"
C=/usr/local/bin/container
REMOTE_DIR="${REMOTE_DIR:-\$HOME/Community_Nursing_Atlas}"
cmd="${1:-status}"; shift || true
case "$cmd" in
status) ssh "$SSH_HOST" "$C list --all | grep -E 'ID|$NAME'; curl -fsS -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:\${PORT:-8088}/ || true" ;;
logs) ssh "$SSH_HOST" "$C logs $NAME | tail -n ${1:-100}" ;;
restart) ssh "$SSH_HOST" "$C stop $NAME; $C start $NAME" ;;
stop) ssh "$SSH_HOST" "$C stop $NAME" ;;
password) ssh "$SSH_HOST" "$C logs $NAME | grep -a '교수자 계정' | tail -1; echo '(비밀번호를 바꿨다면 관리 → 설정의 값이 우선합니다)'" ;;
feedback) ssh "$SSH_HOST" "$C exec $NAME python -m server.cli feedback $*" ;;
cli) ssh "$SSH_HOST" "$C exec $NAME python -m server.cli $(printf '%q ' "$@")" ;;
backup)
ts=$(date +%Y%m%d-%H%M%S); mkdir -p backups
ssh "$SSH_HOST" "$C exec $NAME python -c \"import sqlite3; s=sqlite3.connect('/app/data/atlas.db'); d=sqlite3.connect('/app/data/backup.db'); s.backup(d); d.close()\""
ssh "$SSH_HOST" "cat $REMOTE_DIR/data/backup.db && rm $REMOTE_DIR/data/backup.db" > "backups/atlas-$ts.db" && echo "backups/atlas-$ts.db" ;;
*) echo "사용법: $0 {status|logs|restart|stop|password|feedback|cli|backup}"; exit 1 ;;
esac