Fosi Fossil Service
Small teams. Open source. Built on Fossil.

IaC / SwiftFlow

High-performance WMS with wave picking, smart routing, and real-time inventory visibility.

Public | Owner: IaC | Default branch: trunk | Last update: 2026-10-23 14:37

Artifact 90b9af6495a3b5d5310d75c217127e1cc0821ed37ba13921e9db5877265046c0:


import database.{type Param, IntParam}
import gleam/list
import gleam/string

pub type Scope {
  AllWarehouses
  Warehouses(List(Int))
}

pub type Permission {
  Permission(code: String, name: String)
}

pub type Role {
  Role(
    code: String,
    name: String,
    terminals: List(String),
    permissions: List(String),
  )
}

pub const sys_admin = "ROLE_SYS_ADMIN"

pub const terminals = ["web", "desktop", "mobile", "miniapp"]

pub const sync_view = "sync.view"

pub const sync_run = "sync.run"

pub const warehouse_view = "warehouse.view"

pub const location_view = "location.view"

pub const location_manage = "location.manage"

pub const product_view = "product.view"

pub const order_view = "order.view"

pub const wave_manage = "wave.manage"

pub const inbound_view = "inbound.view"

pub const receiving_execute = "receiving.execute"

pub const putaway_execute = "putaway.execute"

pub const picking_execute = "picking.execute"

pub const shipment_execute = "shipment.execute"

pub const inventory_view = "inventory.view"

pub const move_execute = "move.execute"

pub const user_manage = "user.manage"

pub const audit_view = "audit.view"

pub fn permissions() -> List(Permission) {
  [
    Permission(sync_view, "查看同步状态与来肯连接"),
    Permission(sync_run, "手动触发来肯同步"),
    Permission(warehouse_view, "查看仓库"),
    Permission(location_view, "查看库位"),
    Permission(location_manage, "规划、新增、停用库位"),
    Permission(product_view, "查看商品"),
    Permission(order_view, "查看销售订单与出库记录"),
    Permission(wave_manage, "波次组单与撤销"),
    Permission(inbound_view, "查看采购单、采购入库单与批次码"),
    Permission(receiving_execute, "收货验货"),
    Permission(putaway_execute, "上架"),
    Permission(picking_execute, "拣货"),
    Permission(shipment_execute, "出库扣减库存"),
    Permission(inventory_view, "查看库存"),
    Permission(move_execute, "移库"),
    Permission(user_manage, "用户、角色与仓库授权管理"),
    Permission(audit_view, "查看审计日志"),
  ]
}

pub fn roles() -> List(Role) {
  let all = list.map(permissions(), fn(p) { p.code })
  [
    Role(sys_admin, "超级管理员", ["web", "desktop"], all),
    Role("ROLE_WH_MANAGER", "仓库主管", ["web", "desktop", "miniapp"], [
      sync_view,
      warehouse_view,
      location_view,
      location_manage,
      product_view,
      order_view,
      inbound_view,
      receiving_execute,
      putaway_execute,
      picking_execute,
      wave_manage,
      shipment_execute,
      inventory_view,
      move_execute,
    ]),
    Role("ROLE_ORDER_CLERK", "制单/调度员", ["web", "desktop"], [
      sync_view,
      sync_run,
      warehouse_view,
      location_view,
      product_view,
      order_view,
      wave_manage,
      inbound_view,
      inventory_view,
    ]),
    Role("ROLE_PACKER", "打包复核员", ["desktop"], [
      warehouse_view,
      location_view,
      product_view,
      order_view,
      picking_execute,
      shipment_execute,
      inventory_view,
    ]),
    Role("ROLE_OPERATOR", "库内作业员", ["mobile", "miniapp"], [
      warehouse_view,
      location_view,
      product_view,
      order_view,
      inbound_view,
      receiving_execute,
      putaway_execute,
      picking_execute,
      inventory_view,
      move_execute,
    ]),
  ]
}

pub fn find_role(code: String) -> Result(Role, Nil) {
  list.find(roles(), fn(role) { role.code == code })
}

pub fn permissions_of(role_codes: List(String)) -> List(String) {
  role_codes
  |> list.filter_map(find_role)
  |> list.flat_map(fn(role) { role.permissions })
  |> list.unique
}

pub fn terminal_allowed(role_codes: List(String), terminal: String) -> Bool {
  role_codes
  |> list.filter_map(find_role)
  |> list.any(fn(role) { list.contains(role.terminals, terminal) })
}

pub fn scope_for(role_codes: List(String), warehouse_ids: List(Int)) -> Scope {
  case list.contains(role_codes, sys_admin) {
    True -> AllWarehouses
    False -> Warehouses(warehouse_ids)
  }
}

pub fn allows(scope: Scope, warehouse_id: Int) -> Bool {
  case scope {
    AllWarehouses -> True
    Warehouses(ids) -> list.contains(ids, warehouse_id)
  }
}

/// 生成 `column IN (...)` 过滤条件,SQLite 与 PostgreSQL 通用。
pub fn sql_filter(scope: Scope, column: String) -> #(String, List(Param)) {
  case scope {
    AllWarehouses -> #("1 = 1", [])
    Warehouses([]) -> #("1 = 0", [])
    Warehouses(ids) -> #(
      column <> " IN (" <> string.join(list.map(ids, fn(_) { "?" }), ", ") <> ")",
      list.map(ids, IntParam),
    )
  }
}

Clone

You can clone this repository with the following command:

fossil clone https://fosi.dev/IaC/SwiftFlow

Contribute

The best way to contribute is through e-mail. See the project documentation for more details.