| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- // Package port academic 域跨域只读接口(**academic 定义,org 侧实现/注入**)。
- //
- // 依据:unified/03-migration/academic-domain-design.md §1.3(包结构与依赖方向)/ §1.6(跨库跨域收敛)。
- //
- // 依赖方向铁律:
- // - academic → org(单向):本包只定义接口,实现放 port/orgadapter.go(只读转发)+ 装配层注入;
- // - org **不得**反向依赖 academic;
- // - 禁止跨库 SQL(`yuansiwei.xxx` 前缀)与跨域 JOIN——取数一律经本包接口 + 同事务查询。
- //
- // 为什么需要 port:
- // - 旧 SP `custom_refund` / `cleared_balance` 跨库读 `yuansiwei.t_school_campus.self_support`,
- // `cancel_recharge_activity` 读 `school_id`;目标态校区数据归 org 域 `t_campus`(§11.1 拍板 A
- // 补 `self_support`),academic 只能通过接口读,不得直接 import org 的仓储做业务判断。
- package port
- import (
- "context"
- "gorm.io/gorm"
- )
- // CampusInfo 校区只读视图(跨域取数的唯一载体,字段裁剪到 academic 所需最小集)。
- //
- // 字段:
- // - CampusID int64:校区 ID(→ t_campus.campus_id)。
- // - SchoolID int64:所属机构 ID(旧口径名 schoolid,即 t_campus.institution_id;作用域列取值源)。
- // - SelfSupport bool:是否自营校区(t_campus.self_support:1 自营 / 0 加盟);
- // 决定 custom_refund / cleared_balance 的活动失效范围(`campus_id IN (x,0)` vs `= x`,设计 §11-2)。
- // - Status string:校区状态(active/disabled;disabled 校区禁止发起资金操作)。
- type CampusInfo struct {
- CampusID int64
- SchoolID int64
- SelfSupport bool
- Status string
- }
- // InstitutionID 机构 ID 的规范命名访问器(SchoolID 为旧口径字段名,语义等同 institution_id)。
- //
- // 出参:int64——机构 ID(与 t_campus.institution_id 同值)。
- func (c *CampusInfo) InstitutionID() int64 {
- if c == nil {
- return 0
- }
- return c.SchoolID
- }
- // IsActive 校区是否可用(status=active)。
- func (c *CampusInfo) IsActive() bool {
- return c != nil && c.Status == "active"
- }
- // CampusReader 校区只读读取器(academic 定义;实现见 OrgCampusReader,可 mock 单测)。
- //
- // 契约:
- // - 校区不存在 → `*infraerrors.AppError{Code: 3104}`(apperr.ErrCampusNotFound),不返回 gorm 原错;
- // - 只读,不写 org 表;
- // - 同一事务内只读的强一致场景(如退费事务里判自营),用可选的 TxCampusReader 扩展接口。
- type CampusReader interface {
- // GetByID 按校区 ID 取校区只读视图。
- //
- // 入参:ctx 请求上下文;campusID 校区 ID(<=0 视为业务参数错 3140)。
- // 出参:*CampusInfo(命中);error——apperr.ErrCampusNotFound(3104) / infraerrors.ErrDBError(5002)。
- GetByID(ctx context.Context, campusID int64) (*CampusInfo, error)
- // GetSchoolID 按校区 ID 取所属机构 ID(旧 SP 的 `SchoolCampusHelper::getInfo($campusid)->school_id`)。
- //
- // 入参:ctx 请求上下文;campusID 校区 ID。
- // 出参:int64 机构 ID;error——apperr.ErrCampusNotFound(3104) / infraerrors.ErrDBError(5002)。
- GetSchoolID(ctx context.Context, campusID int64) (int64, error)
- // IsSelfSupport 校区是否自营(决定活动失效范围的判据,设计 §1.6 / §11-2)。
- //
- // 入参:ctx 请求上下文;campusID 校区 ID。
- // 出参:bool 自营=true;error——apperr.ErrCampusNotFound(3104) / infraerrors.ErrDBError(5002)。
- IsSelfSupport(ctx context.Context, campusID int64) (bool, error)
- }
- // TxCampusReader 同事务只读扩展接口(可选实现)。
- //
- // 使用场景:资金事务内需要"与写操作同一快照"的校区判定(旧 SP 是同库 JOIN 语义),
- // 传 tx 保证读到的校区行与事务可见性一致;不传 tx 的 GetByID 走连接池默认隔离级别。
- type TxCampusReader interface {
- // GetByIDTx 在给定事务句柄上读取校区(只读,不写)。
- //
- // 入参:ctx 请求上下文;tx 事务句柄(可为 nil → 退化到连接池);campusID 校区 ID。
- // 出参:*CampusInfo;error 语义同 CampusReader.GetByID。
- GetByIDTx(ctx context.Context, tx *gorm.DB, campusID int64) (*CampusInfo, error)
- }
|