Compare commits

11 Commits

14 changed files with 308 additions and 179 deletions

View File

@@ -130,6 +130,69 @@ begin
)'); )');
create_if_missing('create sequence sg_permission_seq start with 1 increment by 1 nocache'); create_if_missing('create sequence sg_permission_seq start with 1 increment by 1 nocache');
create_if_missing('create sequence sg_permission_rule_seq start with 1 increment by 1 nocache'); create_if_missing('create sequence sg_permission_rule_seq start with 1 increment by 1 nocache');
create_if_missing('create table sg_vpd_policy_note (
object_owner varchar2(128) not null,
object_name varchar2(128) not null,
policy_name varchar2(128) not null,
description varchar2(2000),
updated_at timestamp default systimestamp not null,
constraint sg_vpd_policy_note_pk primary key (object_owner, object_name, policy_name)
)');
create_if_missing('create table sg_vpd_filter_note (
function_owner varchar2(128) not null,
function_name varchar2(128) not null,
description varchar2(2000),
updated_at timestamp default systimestamp not null,
constraint sg_vpd_filter_note_pk primary key (function_owner, function_name)
)');
create_if_missing('create table sg_masking_rule (
rule_id number primary key,
rule_code varchar2(100) not null unique,
rule_name varchar2(200) not null,
template_code varchar2(100) not null,
description varchar2(2000),
enabled_yn char(1) default ''Y'' not null,
created_at timestamp default systimestamp not null,
updated_at timestamp default systimestamp not null,
constraint sg_masking_rule_enabled_ck check (enabled_yn in (''Y'', ''N''))
)');
create_if_missing('create table sg_access_bearer_token (
key_id number primary key, user_id number not null, key_prefix varchar2(100) not null,
key_hash varchar2(256) not null unique, expires_at timestamp not null, revoked_at timestamp,
description varchar2(500), created_at timestamp default systimestamp not null,
constraint sg_access_bearer_token_user_fk foreign key (user_id) references sg_app_user(user_id)
)');
create_if_missing('create table sg_backoffice_setting (
setting_key varchar2(200) primary key, setting_value varchar2(4000),
updated_at timestamp default systimestamp not null
)');
create_if_missing('create table sg_vector_document_chunk (
chunk_id number primary key, document_id varchar2(200) not null, chunk_no number not null,
content clob not null, embedding vector(1536, float32), created_at timestamp default systimestamp not null
)');
create_if_missing('create table sg_vector_document_tag (
chunk_id number not null, tech_tag varchar2(200) not null,
constraint sg_vector_document_tag_pk primary key (chunk_id, tech_tag),
constraint sg_vector_document_tag_chunk_fk foreign key (chunk_id) references sg_vector_document_chunk(chunk_id)
)');
create_if_missing('create sequence sg_vector_chunk_seq start with 1 increment by 1 nocache');
create_if_missing('create table sg_column_masking_rule (
column_id number primary key,
rule_id number not null,
updated_at timestamp default systimestamp not null,
constraint sg_column_masking_rule_column_fk foreign key (column_id) references sg_protected_column(column_id),
constraint sg_column_masking_rule_rule_fk foreign key (rule_id) references sg_masking_rule(rule_id)
)');
create_if_missing('create table sg_user_masking_rule (
user_id number not null,
column_id number not null,
decision varchar2(30) not null,
active_yn char(1) default ''Y'' not null,
updated_at timestamp default systimestamp not null,
constraint sg_user_masking_rule_pk primary key (user_id, column_id),
constraint sg_user_masking_rule_user_fk foreign key (user_id) references sg_app_user(user_id),
constraint sg_user_masking_rule_column_fk foreign key (column_id) references sg_protected_column(column_id)
)');
end; end;
/ /
@@ -168,3 +231,99 @@ merge into sg_group_role t using (select 2001 group_id, 3002 role_id from dual)
on (t.group_id=s.group_id and t.role_id=s.role_id) when not matched then insert (group_id, role_id) values (s.group_id, s.role_id); on (t.group_id=s.group_id and t.role_id=s.role_id) when not matched then insert (group_id, role_id) values (s.group_id, s.role_id);
commit; commit;
-- Compatibility layer for remaining backoffice modules. The data is stored
-- only in SG_* tables; these views prevent older controller paths from
-- querying non-existent CB_* physical tables during the Smilegate transition.
create or replace view cb_app_user as
select user_id, user_name, employee_no, dept_code, can_read_contents, active from sg_app_user;
create or replace view cb_app_group as
select group_id, group_code, group_name, description, active_yn from sg_app_group;
create or replace view cb_app_role as
select role_id, role_name, max_sensitivity_level from sg_app_role;
create or replace view cb_user_role as select user_id, role_id from sg_user_role;
create or replace view cb_user_group as select group_id, user_id from sg_user_group;
create or replace view cb_group_role as select group_id, role_id from sg_group_role;
create or replace view cb_protected_object as
select object_id, owner, object_name, ords_path, enabled_yn, description from sg_protected_object;
create or replace view cb_protected_column as
select column_id, object_id, column_name, sensitive_yn, visible_role_id, sensitivity_level, redaction_method from sg_protected_column;
create or replace view cb_permission as
select perm_id, role_id, target_name, action_name, permission_effect from sg_permission;
create or replace view cb_permission_rule as
select rule_id, perm_id, rule_column, rule_type, rule_value from sg_permission_rule;
create or replace view cb_permission_column as
select permission_id, column_name from sg_permission_column;
create or replace view cb_vpd_policy_note as
select object_owner, object_name, policy_name, description, updated_at from sg_vpd_policy_note;
create or replace view cb_vpd_filter_note as
select function_owner, function_name, description, updated_at from sg_vpd_filter_note;
create or replace view cb_masking_rule as
select rule_id, rule_code, rule_name, template_code, description, enabled_yn from sg_masking_rule;
create or replace view cb_column_masking_rule as
select column_id, rule_id, updated_at from sg_column_masking_rule;
create or replace view cb_user_masking_rule as
select user_id, column_id, decision, active_yn, updated_at from sg_user_masking_rule;
create or replace view cb_ords_probe_audit as
select audit_id, event_type, key_id, object_id, status, row_count, error_code, message, created_at from sg_audit_event;
create or replace view cb_backoffice_setting as
select setting_key, setting_value, updated_at from sg_backoffice_setting;
-- PoC administrator access: both demo operators can manage and query every
-- Smilegate game-data object registered in SGMP_POC.
merge into sg_app_role t
using (select 3099 role_id, 'DATA_AI_POC_ADMIN' role_name,
'Full access to all Smilegate PoC game-data objects' description,
'RESTRICTED' max_sensitivity_level from dual) s
on (t.role_id = s.role_id)
when matched then update set t.role_name=s.role_name, t.description=s.description,
t.max_sensitivity_level=s.max_sensitivity_level, t.updated_at=systimestamp
when not matched then insert (role_id, role_name, description, max_sensitivity_level)
values (s.role_id, s.role_name, s.description, s.max_sensitivity_level);
merge into sg_user_role t
using (select 1001 user_id, 3099 role_id from dual union all select 1002, 3099 from dual) s
on (t.user_id=s.user_id and t.role_id=s.role_id)
when not matched then insert (user_id, role_id) values (s.user_id, s.role_id);
declare
l_object_id number;
l_permission_id number;
begin
for source_object in (
select table_name
from all_tables
where owner = 'SGMP_POC'
and table_name not in ('SEMANTIC_METADATA_CHANGE_LOG', 'SGMP_TERM_CONTEXT_CACHE',
'SGMP_TERM_DICTIONARY', 'SGMP_TERM_SEARCH_LOG', 'SGMP_TERM_SYNONYM')
order by table_name
) loop
begin
select object_id into l_object_id
from sg_protected_object
where owner = 'SGMP_POC' and object_name = source_object.table_name;
exception
when no_data_found then
select nvl(max(object_id), 0) + 1 into l_object_id from sg_protected_object;
insert into sg_protected_object (object_id, owner, object_name, ords_path, enabled_yn, description)
values (l_object_id, 'SGMP_POC', source_object.table_name,
'/sgmp-poc/' || lower(source_object.table_name), 'Y',
'Smilegate PoC game-data object');
end;
begin
select perm_id into l_permission_id
from sg_permission
where role_id = 3099 and target_name = source_object.table_name;
exception
when no_data_found then
l_permission_id := sg_permission_seq.nextval;
insert into sg_permission (perm_id, role_id, target_name, action_name, permission_effect)
values (l_permission_id, 3099, source_object.table_name, 'SELECT', 'ALLOW');
insert into sg_permission_rule (rule_id, perm_id, rule_column, rule_type, rule_value)
values (sg_permission_rule_seq.nextval, l_permission_id, null, 'ALL', null);
end;
end loop;
commit;
end;
/

View File

@@ -37,7 +37,7 @@ public class SecurityConfig {
.rememberMeCookieName("VPD_REMEMBER_ME") .rememberMeCookieName("VPD_REMEMBER_ME")
.tokenValiditySeconds(security.rememberMeValiditySeconds()) .tokenValiditySeconds(security.rememberMeValiditySeconds())
.useSecureCookie(true) .useSecureCookie(true)
.alwaysRemember(false)); .alwaysRemember(true));
} }
return http return http

View File

@@ -18,7 +18,7 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class SchemaMetadataService { public class SchemaMetadataService {
private static final String OWNER = "POC_2"; private static final String OWNER = "SGMP_POC";
private static final int MAX_COMMENT_LENGTH = 4000; private static final int MAX_COMMENT_LENGTH = 4000;
private static final int MAX_ANNOTATION_VALUE_LENGTH = 4000; private static final int MAX_ANNOTATION_VALUE_LENGTH = 4000;
private static final Pattern ORACLE_SIMPLE_NAME = Pattern.compile("[A-Z][A-Z0-9_$#]{0,127}"); private static final Pattern ORACLE_SIMPLE_NAME = Pattern.compile("[A-Z][A-Z0-9_$#]{0,127}");

View File

@@ -11,16 +11,16 @@ import org.springframework.stereotype.Service;
@Service @Service
public class StructuredDataService { public class StructuredDataService {
private static final String OWNER = "POC_2"; private static final String OWNER = "SGMP_POC";
private static final int ROW_LIMIT = 50; private static final int ROW_LIMIT = 50;
private static final List<StructuredDataTable> TABLES = List.of( private static final List<StructuredDataTable> TABLES = List.of(
new StructuredDataTable("customers", "KB_CUSTOMERS", "고객원장", "고객 기본정보"), new StructuredDataTable("game-users", "CZN_COMN_USER_MST", "게임 사용자", "카제나 게임 사용자 마스터"),
new StructuredDataTable("products", "KB_PRODUCTS", "상품원장", "보험상품 마스터"), new StructuredDataTable("characters", "CZN_COMN_CHARACTER_MST", "캐릭터", "카제나 캐릭터 마스터"),
new StructuredDataTable("contracts", "KB_CONTRACTS", "계약원장", "보험계약 정보"), new StructuredDataTable("sales", "COMN_SALES_TXN", "판매 거래", "게임 상품 판매 거래"),
new StructuredDataTable("coverages", "KB_COVERAGES", "담보원장", "보장·특약 정보"), new StructuredDataTable("refunds", "COMN_REFUND_TXN", "환불 거래", "게임 상품 환불 거래"),
new StructuredDataTable("claims", "KB_CLAIMS", "청구원장", "보험금 청구·지급 정보"), new StructuredDataTable("products", "COMN_SALES_PRODUCT_DISP_BAS", "상품", "판매 상품 전시 기준"),
new StructuredDataTable("external-holdings", "KB_EXTERNAL_HOLDINGS", "외부보유정보 원장", "타사·외부 가입·보유 정보"), new StructuredDataTable("game-servers", "COMN_GAME_SERVER_BAS", "게임 서버", "게임 서버 기준 정보"),
new StructuredDataTable("stakeholders", "KB_STAKEHOLDERS", "이해관계자 원장", "역할·담당자 매핑")); new StructuredDataTable("game-aliases", "COMN_GAME_ALIAS_BAS", "게임 별칭", "게임명·별칭·prefix 매핑"));
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
@@ -63,7 +63,7 @@ public class StructuredDataService {
previewSql(table), ROW_LIMIT); previewSql(table), ROW_LIMIT);
return new StructuredDataPreview(table, columns, rows, ROW_LIMIT); return new StructuredDataPreview(table, columns, rows, ROW_LIMIT);
} catch (DataAccessException exception) { } catch (DataAccessException exception) {
throw new AppException("정형 데이터를 조회할 수 없습니다. POC_2 조회 권한과 대상 테이블 상태를 확인하세요."); throw new AppException("게임 데이터를 조회할 수 없습니다. SGMP_POC 조회 권한과 대상 테이블 상태를 확인하세요.");
} }
} }
@@ -73,13 +73,13 @@ public class StructuredDataService {
*/ */
private String previewSql(StructuredDataTable table) { private String previewSql(StructuredDataTable table) {
return switch (table.key()) { return switch (table.key()) {
case "customers" -> "SELECT * FROM POC_2.KB_CUSTOMERS WHERE ROWNUM <= ?"; case "game-users" -> "SELECT * FROM SGMP_POC.CZN_COMN_USER_MST WHERE ROWNUM <= ?";
case "products" -> "SELECT * FROM POC_2.KB_PRODUCTS WHERE ROWNUM <= ?"; case "characters" -> "SELECT * FROM SGMP_POC.CZN_COMN_CHARACTER_MST WHERE ROWNUM <= ?";
case "contracts" -> "SELECT * FROM POC_2.KB_CONTRACTS WHERE ROWNUM <= ?"; case "sales" -> "SELECT * FROM SGMP_POC.COMN_SALES_TXN WHERE ROWNUM <= ?";
case "coverages" -> "SELECT * FROM POC_2.KB_COVERAGES WHERE ROWNUM <= ?"; case "refunds" -> "SELECT * FROM SGMP_POC.COMN_REFUND_TXN WHERE ROWNUM <= ?";
case "claims" -> "SELECT * FROM POC_2.KB_CLAIMS WHERE ROWNUM <= ?"; case "products" -> "SELECT * FROM SGMP_POC.COMN_SALES_PRODUCT_DISP_BAS WHERE ROWNUM <= ?";
case "external-holdings" -> "SELECT * FROM POC_2.KB_EXTERNAL_HOLDINGS WHERE ROWNUM <= ?"; case "game-servers" -> "SELECT * FROM SGMP_POC.COMN_GAME_SERVER_BAS WHERE ROWNUM <= ?";
case "stakeholders" -> "SELECT * FROM POC_2.KB_STAKEHOLDERS WHERE ROWNUM <= ?"; case "game-aliases" -> "SELECT * FROM SGMP_POC.COMN_GAME_ALIAS_BAS WHERE ROWNUM <= ?";
default -> throw new AppException("선택할 수 없는 정형 데이터 테이블입니다."); default -> throw new AppException("선택할 수 없는 정형 데이터 테이블입니다.");
}; };
} }

View File

@@ -56,9 +56,9 @@ public class VectorKnowledgeService {
} }
public VectorKnowledgeSummary summary() { public VectorKnowledgeSummary summary() {
int documents = count("SELECT COUNT(DISTINCT document_id) FROM cb_vector_document_chunk"); int documents = count("SELECT COUNT(DISTINCT document_id) FROM sg_vector_document_chunk");
int chunks = count("SELECT COUNT(*) FROM cb_vector_document_chunk"); int chunks = count("SELECT COUNT(*) FROM sg_vector_document_chunk");
int tags = count("SELECT COUNT(*) FROM cb_vector_document_tag"); int tags = count("SELECT COUNT(*) FROM sg_vector_document_tag");
boolean registered = protectedObjectService.findEnabled().stream() boolean registered = protectedObjectService.findEnabled().stream()
.anyMatch(object -> VECTOR_OBJECT.equalsIgnoreCase(object.objectName())); .anyMatch(object -> VECTOR_OBJECT.equalsIgnoreCase(object.objectName()));
return new VectorKnowledgeSummary( return new VectorKnowledgeSummary(
@@ -107,13 +107,13 @@ public class VectorKnowledgeService {
String embeddingJson = json(embedding); String embeddingJson = json(embedding);
long chunkId = nextChunkId++; long chunkId = nextChunkId++;
jdbcTemplate.update(""" jdbcTemplate.update("""
INSERT INTO cb_vector_document_chunk INSERT INTO sg_vector_document_chunk
(chunk_id, document_id, chunk_no, title, chunk_text, source_uri, embedding) (chunk_id, document_id, chunk_no, title, chunk_text, source_uri, embedding)
VALUES (?, ?, ?, ?, ?, ?, TO_VECTOR(?)) VALUES (?, ?, ?, ?, ?, ?, TO_VECTOR(?))
""", chunkId, documentId, chunk.chunkNo(), title, chunk.text(), sourceUri, embeddingJson); """, chunkId, documentId, chunk.chunkNo(), title, chunk.text(), sourceUri, embeddingJson);
for (String tag : tags) { for (String tag : tags) {
jdbcTemplate.update(""" jdbcTemplate.update("""
INSERT INTO cb_vector_document_tag (chunk_id, tech_tag) INSERT INTO sg_vector_document_tag (chunk_id, tech_tag)
VALUES (?, ?) VALUES (?, ?)
""", chunkId, tag); """, chunkId, tag);
tagCount++; tagCount++;
@@ -143,18 +143,18 @@ public class VectorKnowledgeService {
private void replaceDocument(String documentId) { private void replaceDocument(String documentId) {
jdbcTemplate.update(""" jdbcTemplate.update("""
DELETE FROM cb_vector_document_tag DELETE FROM sg_vector_document_tag
WHERE chunk_id IN ( WHERE chunk_id IN (
SELECT chunk_id FROM cb_vector_document_chunk WHERE document_id = ? SELECT chunk_id FROM sg_vector_document_chunk WHERE document_id = ?
) )
""", documentId); """, documentId);
jdbcTemplate.update("DELETE FROM cb_vector_document_chunk WHERE document_id = ?", documentId); jdbcTemplate.update("DELETE FROM sg_vector_document_chunk WHERE document_id = ?", documentId);
} }
private long nextChunkId(int chunkCount) { private long nextChunkId(int chunkCount) {
try { try {
Long sequenceValue = jdbcTemplate.queryForObject( Long sequenceValue = jdbcTemplate.queryForObject(
"SELECT cb_vector_chunk_seq.NEXTVAL FROM dual", Long.class); "SELECT sg_vector_chunk_seq.NEXTVAL FROM dual", Long.class);
if (sequenceValue != null) { if (sequenceValue != null) {
return sequenceValue; return sequenceValue;
} }
@@ -163,7 +163,7 @@ public class VectorKnowledgeService {
// fallback keeps the demonstration usable; the setup SQL creates it. // fallback keeps the demonstration usable; the setup SQL creates it.
} }
Long max = jdbcTemplate.queryForObject( Long max = jdbcTemplate.queryForObject(
"SELECT NVL(MAX(chunk_id), 28000) FROM cb_vector_document_chunk", Long.class); "SELECT NVL(MAX(chunk_id), 28000) FROM sg_vector_document_chunk", Long.class);
return (max == null ? 28000 : max) + 1; return (max == null ? 28000 : max) + 1;
} }

View File

@@ -3,47 +3,44 @@
"https://mybatis.org/dtd/mybatis-3-mapper.dtd"> "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cloudhandson.vpdbackoffice.mapper.BearerTokenMapper"> <mapper namespace="com.cloudhandson.vpdbackoffice.mapper.BearerTokenMapper">
<select id="findAll" resultType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord"> <select id="findAll" resultType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord">
SELECT k.key_id, k.employee_id AS user_id, u.full_name AS username, SELECT k.key_id, k.user_id, u.user_name AS username,
CAST(NULL AS VARCHAR2(100)) AS stakeholder_user_id, CAST(NULL AS VARCHAR2(100)) AS stakeholder_user_id,
CAST(NULL AS VARCHAR2(100)) AS stakeholder_role, CAST(NULL AS VARCHAR2(100)) AS stakeholder_channel, CAST(NULL AS VARCHAR2(100)) AS stakeholder_role, CAST(NULL AS VARCHAR2(100)) AS stakeholder_channel,
k.key_prefix, k.key_hash, k.key_prefix, k.key_hash,
k.expires_at, k.revoked_at, k.description k.expires_at, k.revoked_at, k.description
FROM hmm_access_bearer_tokens k FROM sg_access_bearer_token k JOIN sg_app_user u ON u.user_id = k.user_id
JOIN hmm_hr_employees u ON u.employee_id = k.employee_id
WHERE #{includeInactive} = 1 WHERE #{includeInactive} = 1
OR (k.revoked_at IS NULL AND k.expires_at > SYSTIMESTAMP) OR (k.revoked_at IS NULL AND k.expires_at > SYSTIMESTAMP)
ORDER BY k.key_id DESC ORDER BY k.key_id DESC
</select> </select>
<select id="findById" resultType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord"> <select id="findById" resultType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord">
SELECT k.key_id, k.employee_id AS user_id, u.full_name AS username, SELECT k.key_id, k.user_id, u.user_name AS username,
CAST(NULL AS VARCHAR2(100)) AS stakeholder_user_id, CAST(NULL AS VARCHAR2(100)) AS stakeholder_user_id,
CAST(NULL AS VARCHAR2(100)) AS stakeholder_role, CAST(NULL AS VARCHAR2(100)) AS stakeholder_channel, CAST(NULL AS VARCHAR2(100)) AS stakeholder_role, CAST(NULL AS VARCHAR2(100)) AS stakeholder_channel,
k.key_prefix, k.key_hash, k.key_prefix, k.key_hash,
k.expires_at, k.revoked_at, k.description k.expires_at, k.revoked_at, k.description
FROM hmm_access_bearer_tokens k FROM sg_access_bearer_token k JOIN sg_app_user u ON u.user_id = k.user_id
JOIN hmm_hr_employees u ON u.employee_id = k.employee_id
WHERE k.key_id = #{keyId} WHERE k.key_id = #{keyId}
</select> </select>
<select id="findByHash" resultType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord"> <select id="findByHash" resultType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord">
SELECT k.key_id, k.employee_id AS user_id, u.full_name AS username, SELECT k.key_id, k.user_id, u.user_name AS username,
CAST(NULL AS VARCHAR2(100)) AS stakeholder_user_id, CAST(NULL AS VARCHAR2(100)) AS stakeholder_user_id,
CAST(NULL AS VARCHAR2(100)) AS stakeholder_role, CAST(NULL AS VARCHAR2(100)) AS stakeholder_channel, CAST(NULL AS VARCHAR2(100)) AS stakeholder_role, CAST(NULL AS VARCHAR2(100)) AS stakeholder_channel,
k.key_prefix, k.key_hash, k.key_prefix, k.key_hash,
k.expires_at, k.revoked_at, k.description k.expires_at, k.revoked_at, k.description
FROM hmm_access_bearer_tokens k FROM sg_access_bearer_token k JOIN sg_app_user u ON u.user_id = k.user_id
JOIN hmm_hr_employees u ON u.employee_id = k.employee_id
WHERE k.key_hash = #{keyHash,jdbcType=VARCHAR} WHERE k.key_hash = #{keyHash,jdbcType=VARCHAR}
</select> </select>
<select id="nextKeyId" resultType="long"> <select id="nextKeyId" resultType="long">
SELECT NVL(MAX(key_id), 0) + 1 FROM hmm_access_bearer_tokens SELECT NVL(MAX(key_id), 0) + 1 FROM sg_access_bearer_token
</select> </select>
<insert id="insertToken" parameterType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord"> <insert id="insertToken" parameterType="com.cloudhandson.vpdbackoffice.domain.token.BearerTokenRecord">
INSERT INTO hmm_access_bearer_tokens ( INSERT INTO sg_access_bearer_token (
key_id, employee_id, key_prefix, key_hash, expires_at, revoked_at, description key_id, user_id, key_prefix, key_hash, expires_at, revoked_at, description
) VALUES ( ) VALUES (
#{keyId,jdbcType=NUMERIC}, #{keyId,jdbcType=NUMERIC},
#{userId,jdbcType=NUMERIC}, #{userId,jdbcType=NUMERIC},
@@ -56,7 +53,7 @@
</insert> </insert>
<update id="revokeToken"> <update id="revokeToken">
UPDATE hmm_access_bearer_tokens UPDATE sg_access_bearer_token
SET revoked_at = #{revokedAt,jdbcType=TIMESTAMP}, SET revoked_at = #{revokedAt,jdbcType=TIMESTAMP},
description = CASE description = CASE
WHEN #{reason,jdbcType=VARCHAR} IS NULL THEN description WHEN #{reason,jdbcType=VARCHAR} IS NULL THEN description

View File

@@ -8,7 +8,7 @@
group_name, group_name,
description, description,
active_yn active_yn
FROM hmm_access_groups FROM sg_app_group
ORDER BY group_code ORDER BY group_code
</select> </select>
@@ -16,12 +16,12 @@
SELECT g.group_id, SELECT g.group_id,
g.group_code, g.group_code,
g.group_name, g.group_name,
u.employee_id AS user_id, u.user_id,
u.full_name AS username u.user_name AS username
FROM hmm_access_group_members ug FROM sg_user_group ug
JOIN hmm_access_groups g ON g.group_id = ug.group_id JOIN sg_app_group g ON g.group_id = ug.group_id
JOIN hmm_hr_employees u ON u.employee_id = ug.employee_id JOIN sg_app_user u ON u.user_id = ug.user_id
ORDER BY g.group_code, u.full_name ORDER BY g.group_code, u.user_name
</select> </select>
<select id="findGroupRoles" resultType="com.cloudhandson.vpdbackoffice.domain.group.GroupRoleView"> <select id="findGroupRoles" resultType="com.cloudhandson.vpdbackoffice.domain.group.GroupRoleView">
@@ -30,18 +30,18 @@
g.group_name, g.group_name,
r.role_id, r.role_id,
r.role_name r.role_name
FROM hmm_group_access_roles gr FROM sg_group_role gr
JOIN hmm_access_groups g ON g.group_id = gr.group_id JOIN sg_app_group g ON g.group_id = gr.group_id
JOIN hmm_access_roles r ON r.role_id = gr.role_id JOIN sg_app_role r ON r.role_id = gr.role_id
ORDER BY g.group_code, r.role_name ORDER BY g.group_code, r.role_name
</select> </select>
<select id="nextGroupId" resultType="long"> <select id="nextGroupId" resultType="long">
SELECT NVL(MAX(group_id), 0) + 1 FROM hmm_access_groups SELECT NVL(MAX(group_id), 0) + 1 FROM sg_app_group
</select> </select>
<insert id="insertGroup"> <insert id="insertGroup">
INSERT INTO hmm_access_groups ( INSERT INTO sg_app_group (
group_id, group_code, group_name, description, active_yn group_id, group_code, group_name, description, active_yn
) VALUES ( ) VALUES (
#{groupId,jdbcType=NUMERIC}, #{groupId,jdbcType=NUMERIC},
@@ -53,29 +53,29 @@
</insert> </insert>
<update id="updateActive"> <update id="updateActive">
UPDATE hmm_access_groups UPDATE sg_app_group
SET active_yn = #{activeYn,jdbcType=VARCHAR} SET active_yn = #{activeYn,jdbcType=VARCHAR}
WHERE group_id = #{groupId,jdbcType=NUMERIC} WHERE group_id = #{groupId,jdbcType=NUMERIC}
</update> </update>
<insert id="insertGroupUser"> <insert id="insertGroupUser">
INSERT INTO hmm_access_group_members (group_id, employee_id) INSERT INTO sg_user_group (group_id, user_id)
VALUES (#{groupId,jdbcType=NUMERIC}, #{userId,jdbcType=NUMERIC}) VALUES (#{groupId,jdbcType=NUMERIC}, #{userId,jdbcType=NUMERIC})
</insert> </insert>
<delete id="deleteGroupUser"> <delete id="deleteGroupUser">
DELETE FROM hmm_access_group_members DELETE FROM sg_user_group
WHERE group_id = #{groupId,jdbcType=NUMERIC} WHERE group_id = #{groupId,jdbcType=NUMERIC}
AND employee_id = #{userId,jdbcType=NUMERIC} AND user_id = #{userId,jdbcType=NUMERIC}
</delete> </delete>
<insert id="insertGroupRole"> <insert id="insertGroupRole">
INSERT INTO hmm_group_access_roles (group_id, role_id) INSERT INTO sg_group_role (group_id, role_id)
VALUES (#{groupId,jdbcType=NUMERIC}, #{roleId,jdbcType=NUMERIC}) VALUES (#{groupId,jdbcType=NUMERIC}, #{roleId,jdbcType=NUMERIC})
</insert> </insert>
<delete id="deleteGroupRole"> <delete id="deleteGroupRole">
DELETE FROM hmm_group_access_roles DELETE FROM sg_group_role
WHERE group_id = #{groupId,jdbcType=NUMERIC} WHERE group_id = #{groupId,jdbcType=NUMERIC}
AND role_id = #{roleId,jdbcType=NUMERIC} AND role_id = #{roleId,jdbcType=NUMERIC}
</delete> </delete>

View File

@@ -4,41 +4,41 @@
<mapper namespace="com.cloudhandson.vpdbackoffice.mapper.MaskingRuleMapper"> <mapper namespace="com.cloudhandson.vpdbackoffice.mapper.MaskingRuleMapper">
<select id="findAllRules" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule"> <select id="findAllRules" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule">
SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn
FROM cb_masking_rule FROM sg_masking_rule
ORDER BY enabled_yn DESC, rule_name, rule_id ORDER BY enabled_yn DESC, rule_name, rule_id
</select> </select>
<select id="findEnabledRules" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule"> <select id="findEnabledRules" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule">
SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn
FROM cb_masking_rule FROM sg_masking_rule
WHERE enabled_yn = 'Y' WHERE enabled_yn = 'Y'
ORDER BY rule_name, rule_id ORDER BY rule_name, rule_id
</select> </select>
<select id="findRuleById" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule"> <select id="findRuleById" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule">
SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn
FROM cb_masking_rule FROM sg_masking_rule
WHERE rule_id = #{ruleId} WHERE rule_id = #{ruleId}
</select> </select>
<select id="findRuleByCode" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule"> <select id="findRuleByCode" resultType="com.cloudhandson.vpdbackoffice.domain.masking.MaskingRule">
SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn SELECT rule_id, rule_code, rule_name, template_code, description, enabled_yn
FROM cb_masking_rule FROM sg_masking_rule
WHERE rule_code = #{ruleCode} WHERE rule_code = #{ruleCode}
</select> </select>
<select id="nextRuleId" resultType="long"> <select id="nextRuleId" resultType="long">
SELECT NVL(MAX(rule_id), 0) + 1 FROM cb_masking_rule SELECT NVL(MAX(rule_id), 0) + 1 FROM sg_masking_rule
</select> </select>
<insert id="insertRule"> <insert id="insertRule">
INSERT INTO cb_masking_rule (rule_id, rule_code, rule_name, template_code, description, enabled_yn) INSERT INTO sg_masking_rule (rule_id, rule_code, rule_name, template_code, description, enabled_yn)
VALUES (#{ruleId}, #{command.ruleCode}, #{command.ruleName}, #{command.templateCode}, VALUES (#{ruleId}, #{command.ruleCode}, #{command.ruleName}, #{command.templateCode},
#{command.description}, 'Y') #{command.description}, 'Y')
</insert> </insert>
<update id="updateRuleActive"> <update id="updateRuleActive">
UPDATE cb_masking_rule UPDATE sg_masking_rule
SET enabled_yn = #{enabledYn} SET enabled_yn = #{enabledYn}
WHERE rule_id = #{ruleId} WHERE rule_id = #{ruleId}
</update> </update>
@@ -54,10 +54,10 @@
r.rule_name, r.rule_name,
r.template_code, r.template_code,
r.enabled_yn AS rule_enabled_yn r.enabled_yn AS rule_enabled_yn
FROM cb_column_masking_rule link FROM sg_column_masking_rule link
JOIN cb_protected_column c ON c.column_id = link.column_id JOIN sg_protected_column c ON c.column_id = link.column_id
JOIN cb_protected_object o ON o.object_id = c.object_id JOIN sg_protected_object o ON o.object_id = c.object_id
JOIN cb_masking_rule r ON r.rule_id = link.rule_id JOIN sg_masking_rule r ON r.rule_id = link.rule_id
ORDER BY o.owner, o.object_name, c.column_name ORDER BY o.owner, o.object_name, c.column_name
</select> </select>
@@ -76,10 +76,10 @@
configured AS ( configured AS (
SELECT protected_object.object_name, SELECT protected_object.object_name,
COUNT(*) AS configured_column_count COUNT(*) AS configured_column_count
FROM cb_column_masking_rule link FROM sg_column_masking_rule link
JOIN cb_masking_rule rule ON rule.rule_id = link.rule_id JOIN sg_masking_rule rule ON rule.rule_id = link.rule_id
JOIN cb_protected_column protected_column ON protected_column.column_id = link.column_id JOIN sg_protected_column protected_column ON protected_column.column_id = link.column_id
JOIN cb_protected_object protected_object ON protected_object.object_id = protected_column.object_id JOIN sg_protected_object protected_object ON protected_object.object_id = protected_column.object_id
WHERE protected_object.owner = 'POC_2' WHERE protected_object.owner = 'POC_2'
AND rule.enabled_yn = 'Y' AND rule.enabled_yn = 'Y'
GROUP BY protected_object.object_name GROUP BY protected_object.object_name
@@ -102,10 +102,10 @@
missing_columns AS ( missing_columns AS (
SELECT protected_object.object_name, SELECT protected_object.object_name,
COUNT(*) AS missing_column_count COUNT(*) AS missing_column_count
FROM cb_column_masking_rule link FROM sg_column_masking_rule link
JOIN cb_masking_rule rule ON rule.rule_id = link.rule_id JOIN sg_masking_rule rule ON rule.rule_id = link.rule_id
JOIN cb_protected_column protected_column ON protected_column.column_id = link.column_id JOIN sg_protected_column protected_column ON protected_column.column_id = link.column_id
JOIN cb_protected_object protected_object ON protected_object.object_id = protected_column.object_id JOIN sg_protected_object protected_object ON protected_object.object_id = protected_column.object_id
LEFT JOIN redaction_columns policy_column LEFT JOIN redaction_columns policy_column
ON policy_column.object_owner = protected_object.owner ON policy_column.object_owner = protected_object.owner
AND policy_column.object_name = protected_object.object_name AND policy_column.object_name = protected_object.object_name
@@ -123,10 +123,10 @@
WHERE policy_column.object_owner = 'POC_2' WHERE policy_column.object_owner = 'POC_2'
AND NOT EXISTS ( AND NOT EXISTS (
SELECT 1 SELECT 1
FROM cb_column_masking_rule link FROM sg_column_masking_rule link
JOIN cb_masking_rule rule ON rule.rule_id = link.rule_id JOIN sg_masking_rule rule ON rule.rule_id = link.rule_id
JOIN cb_protected_column protected_column ON protected_column.column_id = link.column_id JOIN sg_protected_column protected_column ON protected_column.column_id = link.column_id
JOIN cb_protected_object protected_object ON protected_object.object_id = protected_column.object_id JOIN sg_protected_object protected_object ON protected_object.object_id = protected_column.object_id
WHERE protected_object.owner = 'POC_2' WHERE protected_object.owner = 'POC_2'
AND protected_object.object_name = policy_column.object_name AND protected_object.object_name = policy_column.object_name
AND protected_column.column_name = policy_column.column_name AND protected_column.column_name = policy_column.column_name
@@ -180,15 +180,15 @@
r.rule_name, r.rule_name,
r.template_code, r.template_code,
r.enabled_yn AS rule_enabled_yn r.enabled_yn AS rule_enabled_yn
FROM cb_column_masking_rule link FROM sg_column_masking_rule link
JOIN cb_protected_column c ON c.column_id = link.column_id JOIN sg_protected_column c ON c.column_id = link.column_id
JOIN cb_protected_object o ON o.object_id = c.object_id JOIN sg_protected_object o ON o.object_id = c.object_id
JOIN cb_masking_rule r ON r.rule_id = link.rule_id JOIN sg_masking_rule r ON r.rule_id = link.rule_id
WHERE c.column_id = #{columnId} WHERE c.column_id = #{columnId}
</select> </select>
<insert id="upsertColumnRule"> <insert id="upsertColumnRule">
MERGE INTO cb_column_masking_rule dst MERGE INTO sg_column_masking_rule dst
USING (SELECT #{columnId} column_id, #{ruleId} rule_id FROM dual) src USING (SELECT #{columnId} column_id, #{ruleId} rule_id FROM dual) src
ON (dst.column_id = src.column_id) ON (dst.column_id = src.column_id)
WHEN MATCHED THEN UPDATE SET dst.rule_id = src.rule_id, dst.updated_at = SYSTIMESTAMP WHEN MATCHED THEN UPDATE SET dst.rule_id = src.rule_id, dst.updated_at = SYSTIMESTAMP
@@ -197,12 +197,12 @@
</insert> </insert>
<delete id="deleteColumnRule"> <delete id="deleteColumnRule">
DELETE FROM cb_column_masking_rule DELETE FROM sg_column_masking_rule
WHERE column_id = #{columnId} WHERE column_id = #{columnId}
</delete> </delete>
<delete id="deleteUserRulesForColumn"> <delete id="deleteUserRulesForColumn">
DELETE FROM cb_user_masking_rule DELETE FROM sg_user_masking_rule
WHERE column_id = #{columnId} WHERE column_id = #{columnId}
</delete> </delete>
@@ -217,12 +217,12 @@
r.template_code, r.template_code,
assignment.decision, assignment.decision,
assignment.active_yn assignment.active_yn
FROM cb_user_masking_rule assignment FROM sg_user_masking_rule assignment
JOIN cb_app_user u ON u.user_id = assignment.user_id JOIN sg_app_user u ON u.user_id = assignment.user_id
JOIN cb_protected_column c ON c.column_id = assignment.column_id JOIN sg_protected_column c ON c.column_id = assignment.column_id
JOIN cb_protected_object o ON o.object_id = c.object_id JOIN sg_protected_object o ON o.object_id = c.object_id
JOIN cb_column_masking_rule link ON link.column_id = c.column_id JOIN sg_column_masking_rule link ON link.column_id = c.column_id
JOIN cb_masking_rule r ON r.rule_id = link.rule_id JOIN sg_masking_rule r ON r.rule_id = link.rule_id
ORDER BY u.user_name, o.owner, o.object_name, c.column_name ORDER BY u.user_name, o.owner, o.object_name, c.column_name
</select> </select>
@@ -237,18 +237,18 @@
r.template_code, r.template_code,
assignment.decision, assignment.decision,
assignment.active_yn assignment.active_yn
FROM cb_user_masking_rule assignment FROM sg_user_masking_rule assignment
JOIN cb_app_user u ON u.user_id = assignment.user_id JOIN sg_app_user u ON u.user_id = assignment.user_id
JOIN cb_protected_column c ON c.column_id = assignment.column_id JOIN sg_protected_column c ON c.column_id = assignment.column_id
JOIN cb_protected_object o ON o.object_id = c.object_id JOIN sg_protected_object o ON o.object_id = c.object_id
JOIN cb_column_masking_rule link ON link.column_id = c.column_id JOIN sg_column_masking_rule link ON link.column_id = c.column_id
JOIN cb_masking_rule r ON r.rule_id = link.rule_id JOIN sg_masking_rule r ON r.rule_id = link.rule_id
WHERE assignment.user_id = #{userId} WHERE assignment.user_id = #{userId}
AND assignment.column_id = #{columnId} AND assignment.column_id = #{columnId}
</select> </select>
<insert id="upsertUserRule"> <insert id="upsertUserRule">
MERGE INTO cb_user_masking_rule dst MERGE INTO sg_user_masking_rule dst
USING (SELECT #{userId} user_id, #{columnId} column_id, #{decision} decision FROM dual) src USING (SELECT #{userId} user_id, #{columnId} column_id, #{decision} decision FROM dual) src
ON (dst.user_id = src.user_id AND dst.column_id = src.column_id) ON (dst.user_id = src.user_id AND dst.column_id = src.column_id)
WHEN MATCHED THEN UPDATE SET dst.decision = src.decision, dst.active_yn = 'Y', dst.updated_at = SYSTIMESTAMP WHEN MATCHED THEN UPDATE SET dst.decision = src.decision, dst.active_yn = 'Y', dst.updated_at = SYSTIMESTAMP
@@ -257,7 +257,7 @@
</insert> </insert>
<delete id="deleteUserRule"> <delete id="deleteUserRule">
DELETE FROM cb_user_masking_rule DELETE FROM sg_user_masking_rule
WHERE user_id = #{userId} WHERE user_id = #{userId}
AND column_id = #{columnId} AND column_id = #{columnId}
</delete> </delete>

View File

@@ -7,8 +7,7 @@
role_name, role_name,
description, description,
max_sensitivity_level max_sensitivity_level
FROM hmm_access_roles FROM sg_app_role
WHERE active_yn = 'Y'
ORDER BY role_name ORDER BY role_name
</select> </select>
@@ -17,45 +16,44 @@
role_name, role_name,
description, description,
max_sensitivity_level max_sensitivity_level
FROM hmm_access_roles FROM sg_app_role
WHERE role_id = #{roleId} WHERE role_id = #{roleId}
</select> </select>
<select id="nextRoleId" resultType="long"> <select id="nextRoleId" resultType="long">
SELECT NVL(MAX(role_id), 0) + 1 FROM hmm_access_roles SELECT NVL(MAX(role_id), 0) + 1 FROM sg_app_role
</select> </select>
<insert id="insertRole"> <insert id="insertRole">
INSERT INTO hmm_access_roles (role_id, role_name, description, max_sensitivity_level, active_yn) INSERT INTO sg_app_role (role_id, role_name, description, max_sensitivity_level)
VALUES ( VALUES (
#{roleId,jdbcType=NUMERIC}, #{roleId,jdbcType=NUMERIC},
UPPER(#{roleName,jdbcType=VARCHAR}), UPPER(#{roleName,jdbcType=VARCHAR}),
#{description,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
#{maxSensitivityLevel,jdbcType=VARCHAR}, #{maxSensitivityLevel,jdbcType=VARCHAR}
'Y'
) )
</insert> </insert>
<update id="updateRoleMaxSensitivity"> <update id="updateRoleMaxSensitivity">
UPDATE hmm_access_roles UPDATE sg_app_role
SET max_sensitivity_level = #{maxSensitivityLevel,jdbcType=VARCHAR} SET max_sensitivity_level = #{maxSensitivityLevel,jdbcType=VARCHAR}
WHERE role_id = #{roleId,jdbcType=NUMERIC} WHERE role_id = #{roleId,jdbcType=NUMERIC}
</update> </update>
<delete id="deleteRole"> <delete id="deleteRole">
DELETE FROM hmm_access_roles DELETE FROM sg_app_role
WHERE role_id = #{roleId,jdbcType=NUMERIC} WHERE role_id = #{roleId,jdbcType=NUMERIC}
</delete> </delete>
<select id="countUserRolesByRoleId" resultType="int"> <select id="countUserRolesByRoleId" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
FROM hmm_employee_access_roles FROM sg_user_role
WHERE role_id = #{roleId,jdbcType=NUMERIC} WHERE role_id = #{roleId,jdbcType=NUMERIC}
</select> </select>
<select id="countGroupRolesByRoleId" resultType="int"> <select id="countGroupRolesByRoleId" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
FROM hmm_group_access_roles FROM sg_group_role
WHERE role_id = #{roleId,jdbcType=NUMERIC} WHERE role_id = #{roleId,jdbcType=NUMERIC}
</select> </select>

View File

@@ -4,12 +4,12 @@
<mapper namespace="com.cloudhandson.vpdbackoffice.mapper.SettingMapper"> <mapper namespace="com.cloudhandson.vpdbackoffice.mapper.SettingMapper">
<select id="findByKey" resultType="com.cloudhandson.vpdbackoffice.domain.setting.BackofficeSetting"> <select id="findByKey" resultType="com.cloudhandson.vpdbackoffice.domain.setting.BackofficeSetting">
SELECT setting_key, setting_value SELECT setting_key, setting_value
FROM cb_backoffice_setting FROM sg_backoffice_setting
WHERE setting_key = #{settingKey,jdbcType=VARCHAR} WHERE setting_key = #{settingKey,jdbcType=VARCHAR}
</select> </select>
<update id="upsert"> <update id="upsert">
MERGE INTO cb_backoffice_setting dst MERGE INTO sg_backoffice_setting dst
USING ( USING (
SELECT #{settingKey,jdbcType=VARCHAR} setting_key, SELECT #{settingKey,jdbcType=VARCHAR} setting_key,
#{settingValue,jdbcType=VARCHAR} setting_value #{settingValue,jdbcType=VARCHAR} setting_value

View File

@@ -3,27 +3,16 @@
"https://mybatis.org/dtd/mybatis-3-mapper.dtd"> "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cloudhandson.vpdbackoffice.mapper.UserMapper"> <mapper namespace="com.cloudhandson.vpdbackoffice.mapper.UserMapper">
<select id="findAll" resultType="com.cloudhandson.vpdbackoffice.domain.user.AppUser"> <select id="findAll" resultType="com.cloudhandson.vpdbackoffice.domain.user.AppUser">
SELECT e.employee_id AS user_id, SELECT user_id, user_name AS username, employee_no AS emp_no, dept_code,
e.full_name AS username, can_read_contents, active AS active_yn
e.employee_code AS emp_no, FROM sg_app_user
t.team_code AS dept_code,
'N' AS can_read_contents,
CASE WHEN e.employment_status = 'ACTIVE' THEN 'Y' ELSE 'N' END AS active_yn
FROM hmm_hr_employees e
JOIN hmm_org_teams t ON t.team_id = e.team_id
ORDER BY username ORDER BY username
</select> </select>
<select id="findById" resultType="com.cloudhandson.vpdbackoffice.domain.user.AppUser"> <select id="findById" resultType="com.cloudhandson.vpdbackoffice.domain.user.AppUser">
SELECT e.employee_id AS user_id, SELECT user_id, user_name AS username, employee_no AS emp_no, dept_code,
e.full_name AS username, can_read_contents, active AS active_yn
e.employee_code AS emp_no, FROM sg_app_user WHERE user_id = #{userId}
t.team_code AS dept_code,
'N' AS can_read_contents,
CASE WHEN e.employment_status = 'ACTIVE' THEN 'Y' ELSE 'N' END AS active_yn
FROM hmm_hr_employees e
JOIN hmm_org_teams t ON t.team_id = e.team_id
WHERE e.employee_id = #{userId}
</select> </select>
<select id="findUserRoles" resultType="com.cloudhandson.vpdbackoffice.domain.user.UserRoleView"> <select id="findUserRoles" resultType="com.cloudhandson.vpdbackoffice.domain.user.UserRoleView">
@@ -31,46 +20,32 @@
u.user_name AS username, u.user_name AS username,
r.role_id, r.role_id,
r.role_name r.role_name
FROM hmm_employee_access_roles ur FROM sg_user_role ur
JOIN hmm_hr_employees u ON u.employee_id = ur.employee_id JOIN sg_app_user u ON u.user_id = ur.user_id
JOIN hmm_access_roles r ON r.role_id = ur.role_id JOIN sg_app_role r ON r.role_id = ur.role_id
ORDER BY u.full_name, r.role_name ORDER BY u.user_name, r.role_name
</select> </select>
<select id="nextUserId" resultType="long"> <select id="nextUserId" resultType="long">
SELECT NVL(MAX(employee_id), 0) + 1 FROM hmm_hr_employees SELECT NVL(MAX(user_id), 0) + 1 FROM sg_app_user
</select> </select>
<insert id="insertUser"> <insert id="insertUser">
INSERT INTO hmm_hr_employees ( INSERT INTO sg_app_user (user_id, login_id, user_name, employee_no, dept_code, can_read_contents, active)
employee_id, employee_code, full_name, email, job_title, team_id, hire_date, employment_status VALUES (#{userId}, LOWER(#{command.empNo}), #{command.username}, #{command.empNo},
) #{command.deptCode}, 'N', 'Y')
SELECT #{userId},
#{command.empNo},
#{command.username},
LOWER(#{command.empNo}) || '@example.test',
'HMM Demo Employee',
t.team_id,
TRUNC(SYSDATE),
'ACTIVE'
FROM hmm_org_teams t
WHERE t.team_code = #{command.deptCode}
</insert> </insert>
<update id="updateActive"> <update id="updateActive">
UPDATE hmm_hr_employees UPDATE sg_app_user SET active = #{activeYn} WHERE user_id = #{userId}
SET employment_status = CASE WHEN #{activeYn} = 'Y' THEN 'ACTIVE' ELSE 'INACTIVE' END
WHERE employee_id = #{userId}
</update> </update>
<insert id="insertUserRole"> <insert id="insertUserRole">
INSERT INTO hmm_employee_access_roles (employee_id, role_id) INSERT INTO sg_user_role (user_id, role_id) VALUES (#{userId}, #{roleId})
VALUES (#{userId}, #{roleId})
</insert> </insert>
<delete id="deleteUserRole"> <delete id="deleteUserRole">
DELETE FROM hmm_employee_access_roles DELETE FROM sg_user_role WHERE user_id = #{userId}
WHERE employee_id = #{userId}
AND role_id = #{roleId} AND role_id = #{roleId}
</delete> </delete>
</mapper> </mapper>

View File

@@ -11,7 +11,7 @@
<p>업무 사용자와 데이터 접근 기준을 관리하고, DB가 적용한 결과까지 확인합니다.</p> <p>업무 사용자와 데이터 접근 기준을 관리하고, DB가 적용한 결과까지 확인합니다.</p>
</div> </div>
<div class="dashboard-hero-actions" aria-label="주요 작업"> <div class="dashboard-hero-actions" aria-label="주요 작업">
<a class="btn rw-btn-primary" href="/probe">접근 검증</a> <a class="btn rw-btn-primary" href="/users">사용자 관리</a>
<a class="btn rw-btn-secondary" href="/permissions">행 접근 규칙</a> <a class="btn rw-btn-secondary" href="/permissions">행 접근 규칙</a>
</div> </div>
<details class="explanation-details dashboard-explanation"> <details class="explanation-details dashboard-explanation">
@@ -152,10 +152,10 @@
<h2 id="menu-flow-title">설정은 접근 제어에서, 적용 확인은 접근 검증에서</h2> <h2 id="menu-flow-title">설정은 접근 제어에서, 적용 확인은 접근 검증에서</h2>
</div> </div>
<div class="dashboard-flow-grid"> <div class="dashboard-flow-grid">
<a class="dashboard-flow-card" href="/permissions"><strong>행 접근 규칙</strong><span>역할별 객체·행 조건</span></a> <a class="dashboard-flow-card" href="/users"><strong>사용자 관리</strong><span>PoC 운영 사용자를 관리</span></a>
<a class="dashboard-flow-card" href="/vpd-policies"><strong>보호·검증</strong><span>보호 연결·검증 세션·접근 확인</span></a> <a class="dashboard-flow-card" href="/groups"><strong>그룹 관리</strong><span>Data &amp; AI TF 구성</span></a>
<a class="dashboard-flow-card" href="/objects"><strong>연동 도구</strong><span>조회 대상·지식 검색·MCP 연동</span></a> <a class="dashboard-flow-card" href="/roles"><strong>역할 관리</strong><span>운영 역할을 관리</span></a>
<a class="dashboard-flow-card" href="/operation-status"><strong>운영</strong><span>상태와 실행 결과 확인</span></a> <a class="dashboard-flow-card" href="/permissions"><strong>행 접근 규칙</strong><span>게임 데이터 객체별 접근 규칙</span></a>
</div> </div>
</section> </section>

View File

@@ -10,7 +10,7 @@
<details class="explanation-details"> <details class="explanation-details">
<summary>도움말</summary> <summary>도움말</summary>
<p> <p>
<code>POC_2</code> KB 업무 테이블의 table/column comment와 Oracle annotation을 조회·수정합니다. <code>SGMP_POC</code> 게임 데이터 테이블의 table/column comment와 Oracle annotation을 조회·수정합니다.
Select AI profile의 <code>comments=true</code>, <code>annotations=true</code> 설정에서는 이 값들이 SQL 생성 근거로 들어갑니다. Select AI profile의 <code>comments=true</code>, <code>annotations=true</code> 설정에서는 이 값들이 SQL 생성 근거로 들어갑니다.
</p> </p>
<p class="mb-0">임의 스키마나 임의 테이블은 수정하지 않고, 백오피스가 승인한 7개 업무 테이블만 대상으로 합니다.</p> <p class="mb-0">임의 스키마나 임의 테이블은 수정하지 않고, 백오피스가 승인한 7개 업무 테이블만 대상으로 합니다.</p>
@@ -24,7 +24,7 @@
<div class="section-heading"> <div class="section-heading">
<div> <div>
<h2>테이블 선택</h2> <h2>테이블 선택</h2>
<p class="section-subtitle">정형 MCP/Select AI가 참조하는 KB 업무 원장 7개만 표시합니다.</p> <p class="section-subtitle">정형 MCP/Select AI가 참조하는 게임 데이터 테이블만 표시합니다.</p>
</div> </div>
<span class="badge text-bg-secondary" th:text="${#lists.size(tables)}">7</span> <span class="badge text-bg-secondary" th:text="${#lists.size(tables)}">7</span>
</div> </div>
@@ -33,9 +33,9 @@
class="structured-table-card" class="structured-table-card"
th:classappend="${entry.key() == selectedKey} ? ' is-selected'" th:classappend="${entry.key() == selectedKey} ? ' is-selected'"
th:href="@{/schema-metadata(table=${entry.key()})}"> th:href="@{/schema-metadata(table=${entry.key()})}">
<strong th:text="${entry.businessName()}">고객원장</strong> <strong th:text="${entry.businessName()}">게임 사용자</strong>
<code th:text="${entry.tableName()}">KB_CUSTOMERS</code> <code th:text="${entry.tableName()}">CZN_COMN_USER_MST</code>
<small th:text="${entry.description()}">고객 기본정보</small> <small th:text="${entry.description()}">게임 사용자 마스터</small>
</a> </a>
</div> </div>
</section> </section>
@@ -44,9 +44,9 @@
<div class="section-heading"> <div class="section-heading">
<div> <div>
<span class="badge text-bg-secondary">TABLE</span> <span class="badge text-bg-secondary">TABLE</span>
<h2 class="mt-2" th:text="${metadata.table().businessName()}">계약원장</h2> <h2 class="mt-2" th:text="${metadata.table().businessName()}">게임 데이터</h2>
<p class="section-subtitle"> <p class="section-subtitle">
<code th:text="${'POC_2.' + metadata.table().tableName()}">POC_2.KB_CONTRACTS</code> <code th:text="${'SGMP_POC.' + metadata.table().tableName()}">SGMP_POC.CZN_COMN_USER_MST</code>
<span th:text="${' · ' + metadata.table().description()}"> · 설명</span> <span th:text="${' · ' + metadata.table().description()}"> · 설명</span>
</p> </p>
</div> </div>

View File

@@ -8,19 +8,19 @@
<h1>정형 데이터 조회</h1> <h1>정형 데이터 조회</h1>
<details class="explanation-details"> <details class="explanation-details">
<summary>도움말</summary> <summary>도움말</summary>
<p>보험 원장 7개만 읽기 전용으로 조회합니다. 임의 SQL이나 수정 기능은 제공하지 않으며, 한 번에 최대 50건까지만 표시합니다.</p> <p>스마일게이트 게임 데이터 테이블을 읽기 전용으로 조회합니다. 임의 SQL이나 수정 기능은 제공하지 않으며, 한 번에 최대 50건까지만 표시합니다.</p>
</details> </details>
</div> </div>
<div class="alert alert-warning"> <div class="alert alert-warning">
이 화면은 관리자용 원장 미리보기입니다. 사용자별 행 접근 적용 결과는 <a href="/probe">접근 검증</a>에서 확인하세요. 이 화면은 관리자용 게임 데이터 미리보기입니다. 사용자별 행 접근 적용 결과는 <a href="/probe">접근 검증</a>에서 확인하세요.
</div> </div>
<section class="content-band"> <section class="content-band">
<div class="section-heading"> <div class="section-heading">
<div> <div>
<h2>조회할 원장 선택</h2> <h2>조회할 게임 데이터 선택</h2>
<p class="section-subtitle">KBAIPOC의 <code>POC_2</code> 스키마에서 승인된 정형 테이블만 표시합니다.</p> <p class="section-subtitle"><code>SGMP_POC</code> 스키마에서 PoC 대상으로 등록한 게임 데이터 테이블만 표시합니다.</p>
</div> </div>
</div> </div>
<div class="structured-table-grid"> <div class="structured-table-grid">
@@ -28,9 +28,9 @@
class="structured-table-card" class="structured-table-card"
th:classappend="${entry.key() == selectedKey} ? ' is-selected'" th:classappend="${entry.key() == selectedKey} ? ' is-selected'"
th:href="@{/structured-data(table=${entry.key()})}"> th:href="@{/structured-data(table=${entry.key()})}">
<strong th:text="${entry.businessName()}">고객원장</strong> <strong th:text="${entry.businessName()}">게임 사용자</strong>
<code th:text="${entry.tableName()}">KB_CUSTOMERS</code> <code th:text="${entry.tableName()}">CZN_COMN_USER_MST</code>
<small th:text="${entry.description()}">고객 기본정보</small> <small th:text="${entry.description()}">게임 사용자 마스터</small>
</a> </a>
</div> </div>
</section> </section>
@@ -40,9 +40,9 @@
<section class="content-band" th:if="${preview}"> <section class="content-band" th:if="${preview}">
<div class="section-heading"> <div class="section-heading">
<div> <div>
<h2 th:text="${preview.table().businessName()}">고객원장</h2> <h2 th:text="${preview.table().businessName()}">게임 사용자</h2>
<p class="section-subtitle"> <p class="section-subtitle">
<code th:text="${'POC_2.' + preview.table().tableName()}">POC_2.KB_CUSTOMERS</code> <code th:text="${'SGMP_POC.' + preview.table().tableName()}">SGMP_POC.CZN_COMN_USER_MST</code>
<span th:text="${' · 최대 ' + preview.rowLimit() + '건'}"> · 최대 50건</span> <span th:text="${' · 최대 ' + preview.rowLimit() + '건'}"> · 최대 50건</span>
</p> </p>
</div> </div>