Sign in

    mldong/jeeflow-core/spi does not have a README file

    ProcessExtRepository

    pub(open) trait ProcessExtRepository {
    async fn find_design_by_id(Self, Int64) ->
    ProcessDesign
    ? raise
    JeeflowError

    async fn save_design(Self,
    ProcessDesign
    ) -> Unit raise
    JeeflowError

    async fn update_design(Self,
    ProcessDesign
    ) -> Unit raise
    JeeflowError

    async fn remove_design(Self, Int64) -> Unit raise
    JeeflowError

    async fn page_designs(Self,
    PageQuery
    ) ->
    PageResult
    [
    ProcessDesign
    ] raise
    JeeflowError

    async fn save_design_his(Self,
    ProcessDesignHis
    ) -> Unit raise
    JeeflowError

    async fn list_design_his(Self, Int64) -> Array[
    ProcessDesignHis
    ] raise
    JeeflowError

    async fn find_surrogate_by_id(Self, Int64) ->
    ProcessSurrogate
    ? raise
    JeeflowError

    async fn save_surrogate(Self,
    ProcessSurrogate
    ) -> Unit raise
    JeeflowError

    async fn update_surrogate(Self,
    ProcessSurrogate
    ) -> Unit raise
    JeeflowError

    async fn remove_surrogate(Self, Int64) -> Unit raise
    JeeflowError

    async fn page_surrogates(Self,
    PageQuery
    ) ->
    PageResult
    [
    ProcessSurrogate
    ] raise
    JeeflowError

    async fn get_surrogate(Self, String, String, String) ->
    ProcessSurrogate
    ? raise
    JeeflowError

    }

    IProcessExtRepository(spec/05,design/his/surrogate 三族)。法数同上——不写死 (audit8 R71:旧文案写 14、现读 13)

    ProcessRepository

    pub(open) trait ProcessRepository {
    async fn find_define_by_id(Self, Int64) ->
    ProcessDefine
    ? raise
    JeeflowError

    async fn save_define(Self,
    ProcessDefine
    ) -> Unit raise
    JeeflowError

    async fn update_define(Self,
    ProcessDefine
    ) -> Unit raise
    JeeflowError

    async fn update_define_state(Self, Int64, Int) -> Unit raise
    JeeflowError

    async fn remove_define(Self, Int64) -> Unit raise
    JeeflowError

    async fn has_instances_by_define_id(Self, Int64) -> Bool raise
    JeeflowError

    async fn find_instance_by_id(Self, Int64) ->
    ProcessInstance
    ? raise
    JeeflowError

    async fn save_instance(Self,
    ProcessInstance
    ) -> Unit raise
    JeeflowError

    async fn update_instance(Self,
    ProcessInstance
    ) -> Unit raise
    JeeflowError

    async fn find_task_by_id(Self, Int64) ->
    ProcessTask
    ? raise
    JeeflowError

    async fn save_task(Self,
    ProcessTask
    ) -> Unit raise
    JeeflowError

    async fn update_task(Self,
    ProcessTask
    ) -> Unit raise
    JeeflowError

    async fn find_doing_tasks(Self, Int64, Array[String]) -> Array[
    ProcessTask
    ] raise
    JeeflowError

    async fn find_done_tasks(Self, Int64, Array[String]) -> Array[
    ProcessTask
    ] raise
    JeeflowError

    async fn find_history_tasks(Self, Int64) -> Array[
    ProcessTask
    ] raise
    JeeflowError

    async fn find_task_actors(Self, Int64) -> Array[String] raise
    JeeflowError

    async fn add_task_actor(Self, Int64, Array[String]) -> Unit raise
    JeeflowError

    async fn remove_task_actor(Self, Int64, Array[String]) -> Unit raise
    JeeflowError

    async fn create_cc_instance(Self, Int64, String, Array[String]) -> Unit raise
    JeeflowError

    async fn find_cc_actors(Self, Int64) -> Array[String] raise
    JeeflowError

    async fn create_cc_instance_if_absent(Self, Int64, String, Array[String]) -> Array[String] raise
    JeeflowError

    async fn update_cc_status(Self, Int64, String) -> Unit raise
    JeeflowError

    async fn page_todo_tasks(Self,
    PageQuery
    ) ->
    PageResult
    [
    TaskRow
    ] raise
    JeeflowError

    async fn page_done_tasks(Self,
    PageQuery
    ) ->
    PageResult
    [
    TaskRow
    ] raise
    JeeflowError

    async fn page_instances(Self,
    PageQuery
    ) ->
    PageResult
    [
    InstanceRow
    ] raise
    JeeflowError

    async fn page_cc_instances(Self,
    PageQuery
    ) ->
    PageResult
    [
    InstanceRow
    ] raise
    JeeflowError

    async fn page_defines(Self,
    PageQuery
    ) ->
    PageResult
    [
    DefineRow
    ] raise
    JeeflowError

    async fn count_todo_tasks(Self, String) -> Int64 raise
    JeeflowError

    async fn get_all_instances(Self) -> Array[
    ProcessInstance
    ] raise
    JeeflowError

    async fn get_all_tasks(Self) -> Array[
    ProcessTask
    ] raise
    JeeflowError

    }

    IProcessRepository(spec/05,全 async)。法数不在此写死——本 trait 的 async fn 声明条数 就是权威读数(audit8 R71:旧文案写 26、现读 29,注释里的计数会随契约演进而失真)

    抄送两条义务(issues/141 · spec 06-facade §2.5 / §4)——两仓储(内存 / MySQL)必须同判据同答案: · G1 分页归属必填:page_cc_instances 的归属列 cc.actor_id(本栈取值通道=PageQuery.operator) 无有效条件(缺键 / 空串 / 全空白)时返回空页,严禁退化成"这条不加"而放出全部实例; 判据单点在 @model.cc_ownership_operator。非归属列的空值放行维持既有通用放行。 · G2 写侧判重=幂等空操作:同一 (instance_id, actor_id) 已有 cc 行时跳过——不新增行、 不重置未读 state、不更新原行时间,并且不 fire CC_CREATE(码 4);建 cc 的三条入口一律改调 create_cc_instance_if_absent 并拿它返回的实际新建子集去 fire,子集为空整支不发。 查询侧不引入去重、历史重复行不清理(owner 2026-09-29 拍)。 · G10 空抄送人不建 cc 行(spec 06-facade §2.10,owner 2026-09-29 拍「空不创建行」;基准=java 5fbd5ac):create_cc_instance 与 create_cc_instance_if_absent 的入参里空串、纯空白一律丢弃, 落库与比较值取 trim 后的串(" 123 " 与 "123" 是同一个人 ⇒ 与上面的 G2 判重咬合, 不 trim 就会让同一人落两行);判据单点在 @model.normalize_cc_actors。 ⚠️ 写侧这一层必须实现方自己挡:引擎漏斗(parse_cc_actors)与门面手动腿都归一,但绕过它们 直连仓储的调用方(集成层、第三方仓储消费者)照样能把空归属值灌进 actor_id —— 那正是 issues/129 那族"空 operator 读全库"的病根。丢完为空 ⇒ 一行不建、也不 fire CC_CREATE(码 4)。 反向哨兵:"0" 这类"看起来像空"的正常 id 是有效值,不得被当空值丢掉。

    Ctx

    pub(all) struct Ctx[R, E] {
    repository : R
    ext_repository : E
    user_provider : async (String) ->
    UserInfo
    ? raise
    JeeflowError
    ?
    org_user_provider : OrgUserProviderFns?
    user_search_provider : UserSearchProviderFns?
    json_provider : JsonProviderFns?
    expression_evaluator : (String, Map[String, Json]) -> Json raise
    JeeflowError
    ?
    id_generator : () -> Int64 raise
    JeeflowError
    ?
    action_permission_provider : (String) -> Array[String]?
    biz_data_reader : async (String, Int64) -> Map[String, Json]? raise
    JeeflowError
    ?
    assignment_handlers : Map[String, async (
    Execution
    ) -> String raise
    JeeflowError
    ]
    decision_handlers : Map[String, async (
    Execution
    ) -> String raise
    JeeflowError
    ]
    custom_handlers : Map[String, async (
    Execution
    ) -> Json raise
    JeeflowError
    ]
    named_interceptors : Map[String, InterceptorFn]
    interceptors : Array[InterceptorFn]
    pre_interceptors : Array[InterceptorFn]
    event_listeners : Array[async (
    ProcessEvent
    ) -> Unit raise
    JeeflowError
    ]
    surrogate_auto_apply : Bool
    }
    ServiceContext —— 启动期构建、运行期只读的 SPI 注册表

    Ctx::event_listeners

    Ctx::ext_repository

    fn[R, E] Ctx::ext_repository(self : Ctx[R, E]) -> E

    Ctx::find_assignment_handler

    fn[R, E] Ctx::find_assignment_handler(self : Ctx[R, E], name : String) -> async (
    Execution
    ) -> String raise
    JeeflowError
    ?

    Ctx::find_custom_handler

    fn[R, E] Ctx::find_custom_handler(self : Ctx[R, E], clazz : String) -> async (
    Execution
    ) -> Json raise
    JeeflowError
    ?
    不打断建单**,spec/02 §6.2 第 2 条;处理器自身执行失败不在豁免内,照旧外抛)。

    Ctx::find_decision_handler

    fn[R, E] Ctx::find_decision_handler(self : Ctx[R, E], name : String) -> async (
    Execution
    ) -> String raise
    JeeflowError
    ?

    Ctx::for_request

    fn[R, E] Ctx::for_request(self : Ctx[R, E], repository : R, ext_repository : E) -> Ctx[R, E]
    运行期再 register_* 只落进当前这一份,跨请求不可见——这是派生的语义,不是 bug。

    Ctx::id_generator_or_default

    fn[R, E] Ctx::id_generator_or_default(self : Ctx[R, E]) -> (() -> Int64 raise
    JeeflowError
    )
    IIdGenerator:未注入时回退默认雪花(worker 0)

    Ctx::json_provider_or_default

    fn[R, E] Ctx::json_provider_or_default(self : Ctx[R, E]) -> JsonProviderFns

    Ctx::named_interceptor

    fn[R, E] Ctx::named_interceptor(self : Ctx[R, E], name : String) -> InterceptorFn?
    按名查拦截器实体(只查表;查不到由调用方报错,本函数不缓存错误⇒每次真查)

    Ctx::new

    fn[R, E] Ctx::new(repository : R, ext_repository : E) -> Ctx[R, E]

    Ctx::permission_codes

    fn[R, E] Ctx::permission_codes(self : Ctx[R, E], action : String) -> Array[String]
    IActionPermissionProvider:未注入用默认 wf:{action /→:}

    Ctx::register_assignment_handler

    fn[R, E] Ctx::register_assignment_handler(self : Ctx[R, E], name : String, handler : async (
    Execution
    ) -> String raise
    JeeflowError
    ) -> Unit

    Ctx::register_assignment_handler_sync

    fn[R, E] Ctx::register_assignment_handler_sync(self : Ctx[R, E], name : String, handler : (
    Execution
    ) -> String raise
    JeeflowError
    ) -> Unit

    Ctx::register_custom_handler

    fn[R, E] Ctx::register_custom_handler(self : Ctx[R, E], clazz : String, handler : async (
    Execution
    ) -> Json raise
    JeeflowError
    ) -> Unit
    (大小写/前缀归一是 issues/141 G4 义务 1 的 C 方案,立法在前、实现另批,这里不抢跑)。

    Ctx::register_custom_handler_sync

    fn[R, E] Ctx::register_custom_handler_sync(self : Ctx[R, E], clazz : String, handler : (
    Execution
    ) -> Json raise
    JeeflowError
    ) -> Unit

    Ctx::register_decision_handler

    fn[R, E] Ctx::register_decision_handler(self : Ctx[R, E], name : String, handler : async (
    Execution
    ) -> String raise
    JeeflowError
    ) -> Unit

    Ctx::register_decision_handler_sync

    fn[R, E] Ctx::register_decision_handler_sync(self : Ctx[R, E], name : String, handler : (
    Execution
    ) -> String raise
    JeeflowError
    ) -> Unit

    Ctx::register_event_listener

    fn[R, E] Ctx::register_event_listener(self : Ctx[R, E], l : async (
    ProcessEvent
    ) -> Unit raise
    JeeflowError
    ) -> Unit

    Ctx::register_event_listener_sync

    fn[R, E] Ctx::register_event_listener_sync(self : Ctx[R, E], l : (
    ProcessEvent
    ) -> Unit raise
    JeeflowError
    ) -> Unit

    Ctx::register_interceptor

    fn[R, E] Ctx::register_interceptor(self : Ctx[R, E], i : InterceptorFn) -> Unit

    Ctx::register_interceptor_sync

    fn[R, E] Ctx::register_interceptor_sync(self : Ctx[R, E], order : Int, run : (
    Execution
    ) -> Unit raise
    JeeflowError
    ) -> Unit
    拦截器的同步档:只补 run 的形状,order 与排序语义不变。

    Ctx::register_named_interceptor

    fn[R, E] Ctx::register_named_interceptor(self : Ctx[R, E], name : String, i : InterceptorFn) -> Unit
    与 register_interceptor(引擎级列表)是两档——声明档存在时只走本表,两档不叠加。

    Ctx::register_pre_interceptor

    fn[R, E] Ctx::register_pre_interceptor(self : Ctx[R, E], i : InterceptorFn) -> Unit
    ⚠️ pre 体系的整体 canonical 形态归 issues/104 §P1,本轮只打通"有地方挂"这一步。

    Ctx::register_pre_interceptor_sync

    fn[R, E] Ctx::register_pre_interceptor_sync(self : Ctx[R, E], order : Int, run : (
    Execution
    ) -> Unit raise
    JeeflowError
    ) -> Unit

    Ctx::repository

    fn[R, E] Ctx::repository(self : Ctx[R, E]) -> R

    Ctx::with_action_permission_provider

    fn[R, E] Ctx::with_action_permission_provider(self : Ctx[R, E], f : (String) -> Array[String]) -> Ctx[R, E]

    Ctx::with_biz_data_reader

    fn[R, E] Ctx::with_biz_data_reader(self : Ctx[R, E], f : async (String, Int64) -> Map[String, Json]? raise
    JeeflowError
    ) -> Ctx[R, E]

    Ctx::with_biz_data_reader_sync

    fn[R, E] Ctx::with_biz_data_reader_sync(self : Ctx[R, E], f : (String, Int64) -> Map[String, Json]? raise
    JeeflowError
    ) -> Ctx[R, E]

    Ctx::with_expression_evaluator

    fn[R, E] Ctx::with_expression_evaluator(self : Ctx[R, E], f : (String, Map[String, Json]) -> Json raise
    JeeflowError
    ) -> Ctx[R, E]

    Ctx::with_id_generator

    fn[R, E] Ctx::with_id_generator(self : Ctx[R, E], f : () -> Int64 raise
    JeeflowError
    ) -> Ctx[R, E]

    Ctx::with_org_user_provider

    fn[R, E] Ctx::with_org_user_provider(self : Ctx[R, E], p : OrgUserProviderFns) -> Ctx[R, E]

    Ctx::with_org_user_provider_sync

    fn[R, E] Ctx::with_org_user_provider_sync(self : Ctx[R, E], p : OrgUserProviderFnsSync) -> Ctx[R, E]

    Ctx::with_surrogate_auto_apply

    fn[R, E] Ctx::with_surrogate_auto_apply(self : Ctx[R, E], on : Bool) -> Ctx[R, E]
    引擎侧消费点见 engine/surrogate.mbt 的 apply_surrogate。

    Ctx::with_user_provider

    fn[R, E] Ctx::with_user_provider(self : Ctx[R, E], p : async (String) ->
    UserInfo
    ? raise
    JeeflowError
    ) -> Ctx[R, E]

    Ctx::with_user_provider_sync

    fn[R, E] Ctx::with_user_provider_sync(self : Ctx[R, E], p : (String) ->
    UserInfo
    ? raise
    JeeflowError
    ) -> Ctx[R, E]

    Ctx::with_user_search_provider

    fn[R, E] Ctx::with_user_search_provider(self : Ctx[R, E], p : UserSearchProviderFns) -> Ctx[R, E]

    Ctx::with_user_search_provider_sync

    fn[R, E] Ctx::with_user_search_provider_sync(self : Ctx[R, E], p : UserSearchProviderFnsSync) -> Ctx[R, E]

    InterceptorFn

    pub(all) struct InterceptorFn {
    order : Int
    run : async (
    Execution
    ) -> Unit raise
    JeeflowError

    }
    FlowInterceptor 闭包形态(带 order)

    JsonProviderFns

    pub(all) struct JsonProviderFns {
    to_json : (Json) -> String
    from_json : (String) -> Json raise
    JeeflowError

    is_json : (String) -> Bool
    }
    IJsonProvider 闭包组(spec/05)

    NoExtRepository

    pub(all) struct NoExtRepository {
    }

    引擎不需要扩展仓储时的空实现

    NoExtRepository::find_design_by_id

    NoExtRepository::find_surrogate_by_id

    NoExtRepository::get_surrogate

    NoExtRepository::new

    NoExtRepository::remove_design

    async fn NoExtRepository::remove_design(_self : NoExtRepository, _id : Int64) -> Unit raise
    JeeflowError

    NoExtRepository::remove_surrogate

    async fn NoExtRepository::remove_surrogate(_self : NoExtRepository, _id : Int64) -> Unit raise
    JeeflowError

    OrgUserProviderFns

    pub(all) struct OrgUserProviderFns {
    find_dept_leaders : async (String) -> Array[String] raise
    JeeflowError

    find_dept_main_leaders : async (String) -> Array[String] raise
    JeeflowError

    find_by_role : async (String) -> Array[String] raise
    JeeflowError

    }
    IOrgUserProvider 闭包组(spec/05 v1.6.0)

    OrgUserProviderFnsSync

    pub(all) struct OrgUserProviderFnsSync {
    find_dept_leaders : (String) -> Array[String] raise
    JeeflowError

    find_dept_main_leaders : (String) -> Array[String] raise
    JeeflowError

    find_by_role : (String) -> Array[String] raise
    JeeflowError

    }
    两条通道注册完的 Ctx 字段类型完全相同,引擎只认 async 那一种。

    OrgUserProviderFnsSync::to_async

    UserSearchProviderFns

    IUserSearchProvider 闭包组(spec/06 §4.3/§6)

    UserSearchProviderFnsSync

    UserSearchProviderFnsSync::to_async

    async_of_sync

    fn[R, A] async_of_sync(f : (A) -> R raise
    JeeflowError
    ) -> (async (A) -> R raise
    JeeflowError
    )
    真查库的宿主实现直接写 async fn(id) raise @error.JeeflowError { ... },不经本桥。

    async_of_sync2

    fn[R, A, B] async_of_sync2(f : (A, B) -> R raise
    JeeflowError
    ) -> (async (A, B) -> R raise
    JeeflowError
    )
    两参档(biz_data_reader 的 (table, id))

    default_action_permission_provider

    fn default_action_permission_provider(action : String) -> Array[String]
    IActionPermissionProvider 默认实现:wf:{action /→:}(spec/06 §2.6)

    default_json_provider

    fn default_json_provider() -> JsonProviderFns
    默认 JsonProvider(core stdlib @cjson 承载)