feat: 구매/안전 시스템 전면 개편 — tkpurchase 개편 + tksafety 신규 + 권한 보강
Phase 1: tkuser 협력업체 CRUD 이관 (읽기전용 → 전체 CRUD) Phase 2: tkpurchase 개편 — 일용공 신청/확정, 작업일정, 업무현황, 계정관리, 협력업체 포털 Phase 3: tksafety 신규 시스템 — 방문관리 + 안전교육 신고 Phase 4: SSO 인증 보강 (partner_company_id JWT, 만료일 체크), 권한 테이블 기반 접근 제어 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -61,8 +61,21 @@ const SYSTEM3_PAGES = {
|
||||
|
||||
const TKPURCHASE_PAGES = {
|
||||
'구매 관리': [
|
||||
{ key: 'purchasing_visit', title: '방문 관리', icon: 'fa-door-open', def: false },
|
||||
{ key: 'purchasing_partner', title: '협력업체 관리', icon: 'fa-building', def: false },
|
||||
{ key: 'purchasing_daylabor', title: '일용공 관리', icon: 'fa-hard-hat', def: false },
|
||||
{ key: 'purchasing_schedule', title: '작업일정 관리', icon: 'fa-calendar-alt', def: false },
|
||||
{ key: 'purchasing_workreport', title: '업무현황 관리', icon: 'fa-clipboard-list', def: false },
|
||||
{ key: 'purchasing_accounts', title: '협력업체 계정', icon: 'fa-user-shield', def: false },
|
||||
],
|
||||
'협력업체': [
|
||||
{ key: 'purchasing_partner_portal', title: '협력업체 포털', icon: 'fa-building', def: false },
|
||||
{ key: 'purchasing_partner_checkin', title: '협력업체 체크인', icon: 'fa-check-circle', def: false },
|
||||
]
|
||||
};
|
||||
|
||||
const TKSAFETY_PAGES = {
|
||||
'안전 관리': [
|
||||
{ key: 'safety_visit', title: '방문 관리', icon: 'fa-door-open', def: false },
|
||||
{ key: 'safety_education', title: '안전교육 관리', icon: 'fa-graduation-cap', def: false },
|
||||
]
|
||||
};
|
||||
|
||||
@@ -191,7 +204,7 @@ document.getElementById('permissionUserSelect').addEventListener('change', async
|
||||
async function loadUserPermissions(userId) {
|
||||
currentPermissions = {};
|
||||
currentPermSources = {};
|
||||
const allDefs = { ...SYSTEM1_PAGES, ...SYSTEM3_PAGES, ...TKPURCHASE_PAGES };
|
||||
const allDefs = { ...SYSTEM1_PAGES, ...SYSTEM3_PAGES, ...TKPURCHASE_PAGES, ...TKSAFETY_PAGES };
|
||||
Object.values(allDefs).flat().forEach(p => { currentPermissions[p.key] = p.def; currentPermSources[p.key] = 'default'; });
|
||||
try {
|
||||
const result = await api(`/permissions/users/${userId}/effective-permissions`);
|
||||
@@ -208,6 +221,7 @@ function renderPermissionGrid() {
|
||||
renderSystemPerms('s1-perms', SYSTEM1_PAGES, 'blue');
|
||||
renderSystemPerms('s3-perms', SYSTEM3_PAGES, 'purple');
|
||||
renderSystemPerms('tkpurchase-perms', TKPURCHASE_PAGES, 'green');
|
||||
renderSystemPerms('tksafety-perms', TKSAFETY_PAGES, 'orange');
|
||||
}
|
||||
|
||||
function sourceLabel(src) {
|
||||
@@ -303,7 +317,7 @@ document.getElementById('savePermissionsBtn').addEventListener('click', async ()
|
||||
btn.disabled = true; btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>저장 중...';
|
||||
|
||||
try {
|
||||
const allPages = [...Object.values(SYSTEM1_PAGES).flat(), ...Object.values(SYSTEM3_PAGES).flat(), ...Object.values(TKPURCHASE_PAGES).flat()];
|
||||
const allPages = [...Object.values(SYSTEM1_PAGES).flat(), ...Object.values(SYSTEM3_PAGES).flat(), ...Object.values(TKPURCHASE_PAGES).flat(), ...Object.values(TKSAFETY_PAGES).flat()];
|
||||
const permissions = allPages.map(p => {
|
||||
const cb = document.getElementById('perm_' + p.key);
|
||||
return { page_name: p.key, can_access: cb ? cb.checked : false };
|
||||
@@ -351,7 +365,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
async function loadDeptPermissions(deptId) {
|
||||
deptPermissions = {};
|
||||
const allDefs = { ...SYSTEM1_PAGES, ...SYSTEM3_PAGES, ...TKPURCHASE_PAGES };
|
||||
const allDefs = { ...SYSTEM1_PAGES, ...SYSTEM3_PAGES, ...TKPURCHASE_PAGES, ...TKSAFETY_PAGES };
|
||||
Object.values(allDefs).flat().forEach(p => { deptPermissions[p.key] = p.def; });
|
||||
try {
|
||||
const result = await api(`/permissions/departments/${deptId}/permissions`);
|
||||
@@ -363,6 +377,7 @@ function renderDeptPermissionGrid() {
|
||||
renderDeptSystemPerms('dept-s1-perms', SYSTEM1_PAGES, 'blue');
|
||||
renderDeptSystemPerms('dept-s3-perms', SYSTEM3_PAGES, 'purple');
|
||||
renderDeptSystemPerms('dept-tkpurchase-perms', TKPURCHASE_PAGES, 'green');
|
||||
renderDeptSystemPerms('dept-tksafety-perms', TKSAFETY_PAGES, 'orange');
|
||||
}
|
||||
|
||||
function renderDeptSystemPerms(containerId, pageDef, color) {
|
||||
@@ -441,7 +456,7 @@ async function saveDeptPermissions() {
|
||||
btn.disabled = true; btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>저장 중...';
|
||||
|
||||
try {
|
||||
const allPages = [...Object.values(SYSTEM1_PAGES).flat(), ...Object.values(SYSTEM3_PAGES).flat(), ...Object.values(TKPURCHASE_PAGES).flat()];
|
||||
const allPages = [...Object.values(SYSTEM1_PAGES).flat(), ...Object.values(SYSTEM3_PAGES).flat(), ...Object.values(TKPURCHASE_PAGES).flat(), ...Object.values(TKSAFETY_PAGES).flat()];
|
||||
const permissions = allPages.map(p => {
|
||||
const cb = document.getElementById('dperm_' + p.key);
|
||||
return { page_name: p.key, can_access: cb ? cb.checked : false };
|
||||
|
||||
Reference in New Issue
Block a user