| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- // 仓储接口(Service 层依赖抽象,供纯 mock 单测——不连 DB 也能覆盖 AuthService 逻辑)。
- //
- // 设计决策(依赖倒置 + 零返工):
- // - Service 只依赖这 3 个**接口**(不 import 具体结构体);
- // 生产装配时注入具体实现(NewUserRepo(db) 等),单测时注入 mock。
- // - 接口签名与具体仓储方法**逐一对齐**(入参/出参/error 语义完全一致),
- // 生产装配时具体结构体隐式满足接口——若后续改方法签名,main 装配处编译期即暴露。
- //
- // 命名约定:接口名带 "…Repository"(UserRepository/IdentityRepository/MembershipRepository),
- // 与本包内具体结构体(UserRepo/IdentityRepo/MembershipRepo)区分,避免同名冲突。
- //
- // 为什么在 repository 包内定义(而非 service 包):
- // - 接口的"自然归属"是数据访问层(描述"能取哪些数据");
- // - service 包 import repository 包取接口(service → repository,方向正确);
- // - 若接口放 service 包,repository 包要 import service 包实现它 → 反向依赖,违反铁律。
- //
- // 平台级访问(同 user_repo.go 包注释):这 3 个接口的实现不继承 scope.BaseRepo——
- // 登录/用户/成员关系是平台级全局查询,多租户防线在后续业务域 Repository 才启动。
- package repository
- import (
- "context"
- "yuansiwei/unified-backend/internal/identity/model"
- orgmodel "yuansiwei/unified-backend/internal/org/model"
- )
- // UserRepository 用户主表数据访问接口(*UserRepo 隐式满足)。
- type UserRepository interface {
- // GetByCanonicalUserID 按 canonical_user_id(ULID)取单个用户(含密码三列——仅登录链路在内存消费)。
- GetByCanonicalUserID(ctx context.Context, uid string) (*model.User, error)
- // UpdatePasswordLazyUpgrade 惰性升级写回(argon2 重哈希 + salt 置 NULL + hash_version='argon2')。
- UpdatePasswordLazyUpgrade(ctx context.Context, uid, newHash string) error
- }
- // IdentityRepository 登录身份数据访问接口(*IdentityRepo 隐式满足)。
- type IdentityRepository interface {
- // GetByTypeIdentifier 按 (type, identifier) 唯一键取登录身份记录。
- GetByTypeIdentifier(ctx context.Context, typ, identifier string) (*model.Identity, error)
- }
- // MembershipRepository 成员关系数据访问接口(*MembershipRepo 隐式满足)。
- type MembershipRepository interface {
- // ListByCanonicalUserID 取某用户全部成员关系(登录第一步返回机构/校区选择列表用;空时返非 nil 空切片)。
- ListByCanonicalUserID(ctx context.Context, uid string) ([]orgmodel.Membership, error)
- // GetByUserInstitutionCampus 按 (canonical_user_id, institution_id, campus_id) 取唯一 membership
- // (登录第二步 /auth/issue 选定作用域后取 role;同作用域多角色取 created_at 最新)。
- GetByUserInstitutionCampus(ctx context.Context, uid string, institutionID, campusID int64) (*orgmodel.Membership, error)
- }
- // 编译期接口断言:具体仓储结构体须满足对应接口(防止"接口与实现签名漂移"——
- // 改任一侧方法签名时,main 装配处把具体实现当接口传参会编译失败,此处再显式兜一层)。
- var (
- _ UserRepository = (*UserRepo)(nil)
- _ IdentityRepository = (*IdentityRepo)(nil)
- _ MembershipRepository = (*MembershipRepo)(nil)
- )
|