feat: add identity persistence scaffold

master
chenyuan 4 weeks ago
parent 3a13cfb34b
commit e6381ebd22

@ -57,6 +57,11 @@
<artifactId>mybatis-plus-spring-boot4-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>

@ -0,0 +1,13 @@
package com.yau.digitalrmb.identity.infrastructure.persistence.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yau.digitalrmb.shared.infrastructure.persistence.AuditableEntity;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@TableName("sys_role")
public class RoleEntity extends AuditableEntity {
private String name;
}

@ -0,0 +1,19 @@
package com.yau.digitalrmb.identity.infrastructure.persistence.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yau.digitalrmb.shared.infrastructure.persistence.AuditableEntity;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@TableName("sys_user")
public class UserEntity extends AuditableEntity {
private String username;
@TableField("password_hash")
private String passwordHash;
private Boolean enabled;
}

@ -0,0 +1,9 @@
package com.yau.digitalrmb.identity.infrastructure.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yau.digitalrmb.identity.infrastructure.persistence.entity.RoleEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface RoleMapper extends BaseMapper<RoleEntity> {
}

@ -0,0 +1,9 @@
package com.yau.digitalrmb.identity.infrastructure.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yau.digitalrmb.identity.infrastructure.persistence.entity.UserEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<UserEntity> {
}

@ -0,0 +1,50 @@
package com.yau.digitalrmb.shared.config;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.annotation.DbType;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import java.time.LocalDateTime;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public MetaObjectHandler metaObjectHandler() {
return new MetaObjectHandler() {
@Override
public void insertFill(MetaObject metaObject) {
LocalDateTime now = LocalDateTime.now();
String actor = currentActor();
strictInsertFill(metaObject, "createdAt", LocalDateTime.class, now);
strictInsertFill(metaObject, "updatedAt", LocalDateTime.class, now);
strictInsertFill(metaObject, "createdBy", String.class, actor);
strictInsertFill(metaObject, "updatedBy", String.class, actor);
}
@Override
public void updateFill(MetaObject metaObject) {
strictUpdateFill(metaObject, "updatedAt", LocalDateTime.class, LocalDateTime.now());
strictUpdateFill(metaObject, "updatedBy", String.class, currentActor());
}
};
}
private static String currentActor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return authentication == null || !authentication.isAuthenticated() ? "SYSTEM" : authentication.getName();
}
}

@ -0,0 +1,33 @@
package com.yau.digitalrmb.shared.infrastructure.persistence;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
public abstract class AuditableEntity {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
@TableField(value = "created_at", fill = FieldFill.INSERT)
private LocalDateTime createdAt;
@TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedAt;
@TableField(value = "created_by", fill = FieldFill.INSERT)
private String createdBy;
@TableField(value = "updated_by", fill = FieldFill.INSERT_UPDATE)
private String updatedBy;
@TableLogic
private Boolean deleted;
}

@ -0,0 +1,29 @@
CREATE TABLE sys_user (
id BIGINT PRIMARY KEY,
username VARCHAR(64) NOT NULL UNIQUE,
password_hash VARCHAR(100) NOT NULL,
enabled BOOLEAN NOT NULL,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
created_by VARCHAR(64) NOT NULL,
updated_by VARCHAR(64) NOT NULL,
deleted BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE TABLE sys_role (
id BIGINT PRIMARY KEY,
name VARCHAR(64) NOT NULL UNIQUE,
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
created_by VARCHAR(64) NOT NULL,
updated_by VARCHAR(64) NOT NULL,
deleted BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE TABLE sys_user_role (
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
PRIMARY KEY (user_id, role_id),
CONSTRAINT fk_user_role_user FOREIGN KEY (user_id) REFERENCES sys_user(id),
CONSTRAINT fk_user_role_role FOREIGN KEY (role_id) REFERENCES sys_role(id)
);

@ -17,6 +17,8 @@ class ApplicationContextTest {
@Test
void baselineMigrationIsApplied() {
assertThat(flyway.info().applied()).hasSize(1);
assertThat(flyway.info().applied())
.extracting(migration -> migration.getVersion().getVersion())
.contains("0");
}
}

@ -0,0 +1,32 @@
package com.yau.digitalrmb.identity;
import com.yau.digitalrmb.identity.infrastructure.persistence.entity.UserEntity;
import com.yau.digitalrmb.identity.infrastructure.persistence.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
@ActiveProfiles("test")
class IdentityPersistenceTest {
@Autowired
private UserMapper userMapper;
@Test
void mapperPersistsAuditedUser() {
UserEntity user = new UserEntity();
user.setUsername("operator");
user.setPasswordHash("hash");
user.setEnabled(true);
userMapper.insert(user);
assertThat(user.getId()).isNotNull();
assertThat(userMapper.selectById(user.getId()).getUsername()).isEqualTo("operator");
assertThat(user.getCreatedAt()).isNotNull();
assertThat(user.getCreatedBy()).isEqualTo("SYSTEM");
}
}
Loading…
Cancel
Save