보안 감사 결과 CRITICAL 2건, HIGH 5건 발견 → 수정 완료 + 자동화 구축. [보안 수정] - issue-view.js: 하드코딩 비밀번호 → crypto.getRandomValues() 랜덤 생성 - pushSubscriptionController.js: ntfy 비밀번호 → process.env.NTFY_SUB_PASSWORD - DEPLOY-GUIDE.md/PROGRESS.md/migration SQL: 평문 비밀번호 → placeholder - docker-compose.yml/.env.example: NTFY_SUB_PASSWORD 환경변수 추가 [보안 강제 시스템 - 신규] - scripts/security-scan.sh: 8개 규칙 (CRITICAL 2, HIGH 4, MEDIUM 2) 3모드(staged/all/diff), severity, .securityignore, MEDIUM 임계값 - .githooks/pre-commit: 로컬 빠른 피드백 - .githooks/pre-receive-server.sh: Gitea 서버 최종 차단 bypass 거버넌스([SECURITY-BYPASS: 사유] + 사용자 제한 + 로그) - SECURITY-CHECKLIST.md: 10개 카테고리 자동/수동 구분 - docs/SECURITY-GUIDE.md: 운영자 가이드 (워크플로우, bypass, FAQ) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
71 lines
2.4 KiB
JavaScript
71 lines
2.4 KiB
JavaScript
// /js/daily-issue-api.js
|
|
import { apiGet, apiPost } from './api-helper.js';
|
|
|
|
/**
|
|
* 이슈 보고서 작성을 위해 필요한 초기 데이터(프로젝트, 이슈 유형)를 가져옵니다.
|
|
* @returns {Promise<{projects: Array, issueTypes: Array}>}
|
|
*/
|
|
export async function getInitialData() {
|
|
try {
|
|
const [projects, issueTypes] = await Promise.all([
|
|
apiGet('/projects'),
|
|
apiGet('/issue-types')
|
|
]);
|
|
return { projects, issueTypes };
|
|
} catch (error) {
|
|
console.error('이슈 보고서 초기 데이터 로딩 실패:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 특정 날짜에 근무한 작업자 목록을 가져옵니다.
|
|
* @param {string} date - 조회할 날짜 (YYYY-MM-DD)
|
|
* @returns {Promise<Array>} - 작업자 목록
|
|
*/
|
|
export async function getWorkersByDate(date) {
|
|
try {
|
|
// 백엔드에 해당 날짜의 작업자 목록을 요청하는 API가 있다고 가정합니다.
|
|
// (예: /api/workers?work_date=YYYY-MM-DD)
|
|
// 현재는 기존 로직을 최대한 활용하여 구현합니다.
|
|
let workers = [];
|
|
const reports = await apiGet(`/daily-work-reports?date=${date}`);
|
|
|
|
if (reports && reports.length > 0) {
|
|
const workerMap = new Map();
|
|
reports.forEach(r => {
|
|
if (!workerMap.has(r.user_id)) {
|
|
workerMap.set(r.user_id, { user_id: r.user_id, worker_name: r.worker_name });
|
|
}
|
|
});
|
|
workers = Array.from(workerMap.values());
|
|
} else {
|
|
// 보고서가 없으면 전체 작업자 목록을 가져옵니다.
|
|
const allWorkers = await apiGet('/workers');
|
|
|
|
// 활성화된 작업자만 필터링
|
|
workers = allWorkers.filter(worker => {
|
|
return worker.status === 'active' || worker.is_active === 1 || worker.is_active === true;
|
|
});
|
|
}
|
|
return workers.sort((a, b) => a.worker_name.localeCompare(b.worker_name));
|
|
} catch (error) {
|
|
console.error(`${date}의 작업자 목록 로딩 실패:`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 작성된 이슈 보고서 데이터를 서버에 전송합니다.
|
|
* @param {object} issueData - 전송할 이슈 데이터
|
|
* @returns {Promise<object>} - 서버 응답 결과
|
|
*/
|
|
export async function createIssueReport(issueData) {
|
|
try {
|
|
const result = await apiPost('/issue-reports', issueData);
|
|
return result;
|
|
} catch (error) {
|
|
console.error('이슈 보고서 생성 요청 실패:', error);
|
|
throw error;
|
|
}
|
|
}
|