You've already forked agentic-coding-workflow
62 lines
2.8 KiB
Go
62 lines
2.8 KiB
Go
// Package user 定义用户与会话的领域类型,以及 user 模块对外暴露的 Service 接口契约。
|
|
//
|
|
// 本文件仅做类型声明,不包含任何业务实现;Login/Logout/ResolveSession 等
|
|
// 方法在后续步骤(E6 等)实装。Service 接口的方法集刻意覆盖了
|
|
// transport/http/middleware.SessionResolver 的方法签名,因此 Service 的
|
|
// 任意实现都可直接作为 SessionResolver 注入到 Auth 中间件,避免在装配层
|
|
// 再写一层适配。
|
|
package user
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// User 表示一个本地账号。字段与 sqlc 生成的行模型一一对应,但使用领域语义
|
|
// 类型(uuid.UUID / time.Time)而非 pgtype.*,便于上层逻辑直接使用而无需
|
|
// 关心驱动层的可空封装。
|
|
type User struct {
|
|
ID uuid.UUID
|
|
Email string
|
|
DisplayName string
|
|
IsAdmin bool
|
|
PasswordHash string
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
// Session 表示一条已颁发但尚未失效的登录会话。TokenHash 存放原始 token 的
|
|
// SHA-256 摘要,原文仅在登录响应时返回一次;服务端不持久化明文 token,
|
|
// 因此校验时必须重新计算摘要再比对。LastSeenAt 为可空字段(首次创建后
|
|
// 尚未被使用过时为 nil)。
|
|
type Session struct {
|
|
ID uuid.UUID
|
|
UserID uuid.UUID
|
|
TokenHash []byte // sha256(token)
|
|
ExpiresAt time.Time
|
|
LastSeenAt *time.Time
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// Service 是 user 模块对外暴露的应用服务契约。它同时满足
|
|
// transport/http/middleware.SessionResolver 接口(参见 ResolveSession 方法),
|
|
// 因此可以直接被 Auth 中间件复用。
|
|
type Service interface {
|
|
// Login 校验邮箱密码,成功后签发新会话;返回的 token 为原文,仅此一次可见。
|
|
Login(ctx context.Context, email, password, ip string) (token string, user *User, err error)
|
|
// Logout 注销给定 token 对应的会话;token 未知或已过期时返回 nil(幂等)。
|
|
Logout(ctx context.Context, token string) error
|
|
// ResolveSession 将 bearer token 解析为已认证的用户 ID,实现
|
|
// middleware.SessionResolver 接口契约:合法且未过期返回 (uid,true,nil);
|
|
// 语法合法但未知/过期返回 (uuid.Nil,false,nil);底层故障返回非 nil error。
|
|
ResolveSession(ctx context.Context, token string) (uuid.UUID, bool, error)
|
|
// Get 按主键加载用户,未找到时返回 errs.NotFound(在 E6 实装时确定)。
|
|
Get(ctx context.Context, id uuid.UUID) (*User, error)
|
|
// Bootstrap 在系统首次启动时创建初始管理员账号,已存在同邮箱用户时为幂等。
|
|
Bootstrap(ctx context.Context, email, password string) (*User, error)
|
|
// ListAdmins 返回所有管理员用户,供内部模块(如 jobs runner)使用。
|
|
ListAdmins(ctx context.Context) ([]*User, error)
|
|
}
|