mirror of
https://github.com/iflytek/skillhub.git
synced 2026-08-28 11:25:00 +00:00
feat(domain/infra/auth): add domain entities, JPA repos, and auth entities
Task 8: Domain layer - UserAccount entity with UserStatus lifecycle - Namespace, NamespaceMember entities with NamespaceRole - Repository interfaces for domain aggregates Task 9: Infra layer - UserAccountJpaRepository, NamespaceJpaRepository, NamespaceMemberJpaRepository - Spring Data JPA implementations Task 10: Auth entities and repositories - IdentityBinding, ApiToken, Role, Permission, RolePermission, UserRoleBinding - JPA repositories for all auth entities - UserRoleBinding with eager-loaded Role for RBAC queries
This commit is contained in:
parent
edfff6abc7
commit
2991eb11e0
23 changed files with 588 additions and 0 deletions
|
|
@ -0,0 +1,77 @@
|
|||
package com.iflytek.skillhub.auth.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "api_token")
|
||||
public class ApiToken {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "subject_type", nullable = false, length = 32)
|
||||
private String subjectType = "USER";
|
||||
|
||||
@Column(name = "subject_id", nullable = false)
|
||||
private Long subjectId;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
@Column(nullable = false, length = 128)
|
||||
private String name;
|
||||
|
||||
@Column(name = "token_prefix", nullable = false, length = 16)
|
||||
private String tokenPrefix;
|
||||
|
||||
@Column(name = "token_hash", nullable = false, unique = true, length = 64)
|
||||
private String tokenHash;
|
||||
|
||||
@Column(name = "scope_json", nullable = false, columnDefinition = "jsonb")
|
||||
private String scopeJson;
|
||||
|
||||
@Column(name = "expires_at")
|
||||
private LocalDateTime expiresAt;
|
||||
|
||||
@Column(name = "last_used_at")
|
||||
private LocalDateTime lastUsedAt;
|
||||
|
||||
@Column(name = "revoked_at")
|
||||
private LocalDateTime revokedAt;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
protected ApiToken() {}
|
||||
|
||||
public ApiToken(Long userId, String name, String tokenPrefix, String tokenHash, String scopeJson) {
|
||||
this.subjectType = "USER";
|
||||
this.subjectId = userId;
|
||||
this.userId = userId;
|
||||
this.name = name;
|
||||
this.tokenPrefix = tokenPrefix;
|
||||
this.tokenHash = tokenHash;
|
||||
this.scopeJson = scopeJson;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
void prePersist() { this.createdAt = LocalDateTime.now(); }
|
||||
|
||||
public Long getId() { return id; }
|
||||
public Long getUserId() { return userId; }
|
||||
public String getName() { return name; }
|
||||
public String getTokenPrefix() { return tokenPrefix; }
|
||||
public String getTokenHash() { return tokenHash; }
|
||||
public String getScopeJson() { return scopeJson; }
|
||||
public LocalDateTime getExpiresAt() { return expiresAt; }
|
||||
public void setExpiresAt(LocalDateTime expiresAt) { this.expiresAt = expiresAt; }
|
||||
public LocalDateTime getLastUsedAt() { return lastUsedAt; }
|
||||
public void setLastUsedAt(LocalDateTime lastUsedAt) { this.lastUsedAt = lastUsedAt; }
|
||||
public LocalDateTime getRevokedAt() { return revokedAt; }
|
||||
public void setRevokedAt(LocalDateTime revokedAt) { this.revokedAt = revokedAt; }
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
public boolean isRevoked() { return revokedAt != null; }
|
||||
public boolean isExpired() { return expiresAt != null && expiresAt.isBefore(LocalDateTime.now()); }
|
||||
public boolean isValid() { return !isRevoked() && !isExpired(); }
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.iflytek.skillhub.auth.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "identity_binding",
|
||||
uniqueConstraints = @UniqueConstraint(columnNames = {"provider_code", "subject"}))
|
||||
public class IdentityBinding {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
@Column(name = "provider_code", nullable = false, length = 64)
|
||||
private String providerCode;
|
||||
|
||||
@Column(nullable = false, length = 256)
|
||||
private String subject;
|
||||
|
||||
@Column(name = "login_name", length = 128)
|
||||
private String loginName;
|
||||
|
||||
@Column(name = "extra_json", columnDefinition = "jsonb")
|
||||
private String extraJson;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
protected IdentityBinding() {}
|
||||
|
||||
public IdentityBinding(Long userId, String providerCode, String subject, String loginName) {
|
||||
this.userId = userId;
|
||||
this.providerCode = providerCode;
|
||||
this.subject = subject;
|
||||
this.loginName = loginName;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
void prePersist() {
|
||||
this.createdAt = LocalDateTime.now();
|
||||
this.updatedAt = this.createdAt;
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
void preUpdate() {
|
||||
this.updatedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public Long getId() { return id; }
|
||||
public Long getUserId() { return userId; }
|
||||
public void setUserId(Long userId) { this.userId = userId; }
|
||||
public String getProviderCode() { return providerCode; }
|
||||
public void setProviderCode(String providerCode) { this.providerCode = providerCode; }
|
||||
public String getSubject() { return subject; }
|
||||
public void setSubject(String subject) { this.subject = subject; }
|
||||
public String getLoginName() { return loginName; }
|
||||
public void setLoginName(String loginName) { this.loginName = loginName; }
|
||||
public String getExtraJson() { return extraJson; }
|
||||
public void setExtraJson(String extraJson) { this.extraJson = extraJson; }
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.iflytek.skillhub.auth.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "permission")
|
||||
public class Permission {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 128)
|
||||
private String code;
|
||||
|
||||
@Column(nullable = false, length = 128)
|
||||
private String name;
|
||||
|
||||
@Column(name = "group_code", length = 64)
|
||||
private String groupCode;
|
||||
|
||||
public Long getId() { return id; }
|
||||
public String getCode() { return code; }
|
||||
public String getName() { return name; }
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.iflytek.skillhub.auth.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "role")
|
||||
public class Role {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 64)
|
||||
private String code;
|
||||
|
||||
@Column(nullable = false, length = 128)
|
||||
private String name;
|
||||
|
||||
@Column(length = 512)
|
||||
private String description;
|
||||
|
||||
@Column(name = "is_system", nullable = false)
|
||||
private boolean system;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@PrePersist
|
||||
void prePersist() { this.createdAt = LocalDateTime.now(); }
|
||||
|
||||
public Long getId() { return id; }
|
||||
public String getCode() { return code; }
|
||||
public String getName() { return name; }
|
||||
public boolean isSystem() { return system; }
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.iflytek.skillhub.auth.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "role_permission")
|
||||
@IdClass(RolePermission.RolePermissionId.class)
|
||||
public class RolePermission {
|
||||
@Id
|
||||
@Column(name = "role_id")
|
||||
private Long roleId;
|
||||
|
||||
@Id
|
||||
@Column(name = "permission_id")
|
||||
private Long permissionId;
|
||||
|
||||
public Long getRoleId() { return roleId; }
|
||||
public Long getPermissionId() { return permissionId; }
|
||||
|
||||
public static class RolePermissionId implements Serializable {
|
||||
private Long roleId;
|
||||
private Long permissionId;
|
||||
|
||||
public RolePermissionId() {}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof RolePermissionId that)) return false;
|
||||
return Objects.equals(roleId, that.roleId) && Objects.equals(permissionId, that.permissionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(roleId, permissionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.iflytek.skillhub.auth.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_role_binding",
|
||||
uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "role_id"}))
|
||||
public class UserRoleBinding {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "role_id", nullable = false)
|
||||
private Role role;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
protected UserRoleBinding() {}
|
||||
|
||||
public UserRoleBinding(Long userId, Role role) {
|
||||
this.userId = userId;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
void prePersist() { this.createdAt = LocalDateTime.now(); }
|
||||
|
||||
public Long getId() { return id; }
|
||||
public Long getUserId() { return userId; }
|
||||
public Role getRole() { return role; }
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.iflytek.skillhub.auth.repository;
|
||||
|
||||
import com.iflytek.skillhub.auth.entity.ApiToken;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface ApiTokenRepository extends JpaRepository<ApiToken, Long> {
|
||||
Optional<ApiToken> findByTokenHash(String tokenHash);
|
||||
List<ApiToken> findByUserIdAndRevokedAtIsNullOrderByCreatedAtDesc(Long userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.iflytek.skillhub.auth.repository;
|
||||
|
||||
import com.iflytek.skillhub.auth.entity.IdentityBinding;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface IdentityBindingRepository extends JpaRepository<IdentityBinding, Long> {
|
||||
Optional<IdentityBinding> findByProviderCodeAndSubject(String providerCode, String subject);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.iflytek.skillhub.auth.repository;
|
||||
|
||||
import com.iflytek.skillhub.auth.entity.Role;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface RoleRepository extends JpaRepository<Role, Long> {
|
||||
Optional<Role> findByCode(String code);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.iflytek.skillhub.auth.repository;
|
||||
|
||||
import com.iflytek.skillhub.auth.entity.UserRoleBinding;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface UserRoleBindingRepository extends JpaRepository<UserRoleBinding, Long> {
|
||||
List<UserRoleBinding> findByUserId(Long userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package com.iflytek.skillhub.domain.namespace;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "namespace")
|
||||
public class Namespace {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 64)
|
||||
private String slug;
|
||||
|
||||
@Column(name = "display_name", nullable = false, length = 128)
|
||||
private String displayName;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false, length = 32)
|
||||
private NamespaceStatus status = NamespaceStatus.ACTIVE;
|
||||
|
||||
@Column(length = 512)
|
||||
private String description;
|
||||
|
||||
@Column(name = "created_by")
|
||||
private Long createdBy;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
protected Namespace() {}
|
||||
|
||||
public Namespace(String slug, String displayName, Long createdBy) {
|
||||
this.slug = slug;
|
||||
this.displayName = displayName;
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
void prePersist() {
|
||||
this.createdAt = LocalDateTime.now();
|
||||
this.updatedAt = this.createdAt;
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
void preUpdate() {
|
||||
this.updatedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public Long getId() { return id; }
|
||||
public String getSlug() { return slug; }
|
||||
public String getDisplayName() { return displayName; }
|
||||
public NamespaceStatus getStatus() { return status; }
|
||||
public Long getCreatedBy() { return createdBy; }
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
public LocalDateTime getUpdatedAt() { return updatedAt; }
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.iflytek.skillhub.domain.namespace;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "namespace_member",
|
||||
uniqueConstraints = @UniqueConstraint(columnNames = {"namespace_id", "user_id"}))
|
||||
public class NamespaceMember {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "namespace_id", nullable = false)
|
||||
private Long namespaceId;
|
||||
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false, length = 32)
|
||||
private NamespaceRole role;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
protected NamespaceMember() {}
|
||||
|
||||
public NamespaceMember(Long namespaceId, Long userId, NamespaceRole role) {
|
||||
this.namespaceId = namespaceId;
|
||||
this.userId = userId;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
void prePersist() {
|
||||
this.createdAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public Long getId() { return id; }
|
||||
public Long getNamespaceId() { return namespaceId; }
|
||||
public Long getUserId() { return userId; }
|
||||
public NamespaceRole getRole() { return role; }
|
||||
public void setRole(NamespaceRole role) { this.role = role; }
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.iflytek.skillhub.domain.namespace;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface NamespaceMemberRepository {
|
||||
Optional<NamespaceMember> findByNamespaceIdAndUserId(Long namespaceId, Long userId);
|
||||
List<NamespaceMember> findByUserId(Long userId);
|
||||
NamespaceMember save(NamespaceMember member);
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.iflytek.skillhub.domain.namespace;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface NamespaceRepository {
|
||||
Optional<Namespace> findById(Long id);
|
||||
Optional<Namespace> findBySlug(String slug);
|
||||
Namespace save(Namespace namespace);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.iflytek.skillhub.domain.namespace;
|
||||
|
||||
public enum NamespaceRole {
|
||||
OWNER, ADMIN, MEMBER
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.iflytek.skillhub.domain.namespace;
|
||||
|
||||
public enum NamespaceStatus {
|
||||
ACTIVE, FROZEN, ARCHIVED
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package com.iflytek.skillhub.domain.user;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_account")
|
||||
public class UserAccount {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "display_name", nullable = false, length = 128)
|
||||
private String displayName;
|
||||
|
||||
@Column(length = 256)
|
||||
private String email;
|
||||
|
||||
@Column(name = "avatar_url", length = 512)
|
||||
private String avatarUrl;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false, length = 32)
|
||||
private UserStatus status = UserStatus.ACTIVE;
|
||||
|
||||
@Column(name = "merged_to_user_id")
|
||||
private Long mergedToUserId;
|
||||
|
||||
@Column(name = "created_at", nullable = false, updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
protected UserAccount() {}
|
||||
|
||||
public UserAccount(String displayName, String email, String avatarUrl) {
|
||||
this.displayName = displayName;
|
||||
this.email = email;
|
||||
this.avatarUrl = avatarUrl;
|
||||
this.status = UserStatus.ACTIVE;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
void prePersist() {
|
||||
this.createdAt = LocalDateTime.now();
|
||||
this.updatedAt = this.createdAt;
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
void preUpdate() {
|
||||
this.updatedAt = LocalDateTime.now();
|
||||
}
|
||||
|
||||
public Long getId() { return id; }
|
||||
public String getDisplayName() { return displayName; }
|
||||
public void setDisplayName(String displayName) { this.displayName = displayName; }
|
||||
public String getEmail() { return email; }
|
||||
public void setEmail(String email) { this.email = email; }
|
||||
public String getAvatarUrl() { return avatarUrl; }
|
||||
public void setAvatarUrl(String avatarUrl) { this.avatarUrl = avatarUrl; }
|
||||
public UserStatus getStatus() { return status; }
|
||||
public void setStatus(UserStatus status) { this.status = status; }
|
||||
public Long getMergedToUserId() { return mergedToUserId; }
|
||||
public void setMergedToUserId(Long mergedToUserId) { this.mergedToUserId = mergedToUserId; }
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
public LocalDateTime getUpdatedAt() { return updatedAt; }
|
||||
public boolean isActive() { return this.status == UserStatus.ACTIVE; }
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.iflytek.skillhub.domain.user;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface UserAccountRepository {
|
||||
Optional<UserAccount> findById(Long id);
|
||||
UserAccount save(UserAccount user);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.iflytek.skillhub.domain.user;
|
||||
|
||||
public enum UserStatus {
|
||||
ACTIVE, PENDING, DISABLED, MERGED
|
||||
}
|
||||
|
|
@ -15,5 +15,9 @@
|
|||
<groupId>com.iflytek.skillhub</groupId>
|
||||
<artifactId>skillhub-domain</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.iflytek.skillhub.infra.jpa;
|
||||
|
||||
import com.iflytek.skillhub.domain.namespace.Namespace;
|
||||
import com.iflytek.skillhub.domain.namespace.NamespaceRepository;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface NamespaceJpaRepository
|
||||
extends JpaRepository<Namespace, Long>, NamespaceRepository {
|
||||
Optional<Namespace> findBySlug(String slug);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.iflytek.skillhub.infra.jpa;
|
||||
|
||||
import com.iflytek.skillhub.domain.namespace.NamespaceMember;
|
||||
import com.iflytek.skillhub.domain.namespace.NamespaceMemberRepository;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface NamespaceMemberJpaRepository
|
||||
extends JpaRepository<NamespaceMember, Long>, NamespaceMemberRepository {
|
||||
Optional<NamespaceMember> findByNamespaceIdAndUserId(Long namespaceId, Long userId);
|
||||
List<NamespaceMember> findByUserId(Long userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.iflytek.skillhub.infra.jpa;
|
||||
|
||||
import com.iflytek.skillhub.domain.user.UserAccount;
|
||||
import com.iflytek.skillhub.domain.user.UserAccountRepository;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserAccountJpaRepository
|
||||
extends JpaRepository<UserAccount, Long>, UserAccountRepository {
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue