Highlights
-
Domain capability architecture: Established
capability.Servicesas the unified contract boundary between framework and plugins. All 17+ business domains (Users, Auth, Dict, Files, Jobs, Sessions, etc.) now expose a singleServiceinterface consumed by both source code and dynamic plugins, replacing the previousAdminServiceseparation. This provides clear decoupling, method-level governance (risk, authorization, data permissions), and rich foundational capabilities (batch operations, candidate searches, visibility validation) while maintaining strict security isolation throughservice + method + resourceauthorization for dynamic plugins. -
Plugin framework architecture overhaul: Major restructuring of the plugin subsystem across host services, WASM host calls, lifecycle management, store layer, upgrade flow, and capability host/owner modules. Files are renamed with clearer prefixes (
wasm_host_service_*,runtime_*,lifecycle_*,store_*,upgrade_*), the old monolithichostservicespackage is replaced bycapabilityhostandcapabilityowner, and the guest-side plugin bridge is consolidated underpluginbridge. This lays a stable foundation for future plugin ecosystem growth. -
TIMESTAMPTZ standardization across all tables: Every
TIMESTAMPcolumn in the core framework and all official plugins is migrated toTIMESTAMPTZ, and a newdatabase.timezoneconfiguration option (defaulting toAsia/Shanghai) is added. This eliminates timezone ambiguity when displaying and decoding temporal data in PostgreSQL. -
In-memory cache replaces SQL-backed KV cache: The
sys_kv_cachetable and its DAO/entity layer are removed. Distributed KV caching is now backed bygcache(in-memory) with coordinated revision invalidation, reducing database round-trips for hot cache operations. -
Plugin distribution mode: Added a new plugin distribution mode feature that classifies plugins into two governance categories based on how they are managed throughout their lifecycle.
managed(the default) covers plugins governed through the plugin management UI orplugin.autoEnable, giving operators full control over install, enable, upgrade, and uninstall.builtinis reserved for source plugins that the host must automatically install, enable, and upgrade at startup, with their lifecycle protected from manual intervention in the management UI. This separation establishes clear behavioral boundaries between operator-managed and host-governed plugins. -
Go static linting as a quality gate: Added a new
make lintcross-platform command for runninggolangci-lintacross the workspace. Supportsplugins=0(host-only) andplugins=1(full workspace including official plugins) modes. Tool versions are locked via.golangci-lint-versionand.staticcheck-versionfiles, andlinactlautomatically installs the correct version when missing. This provides an efficient quality assurance mechanism for AI-driven development workflows.
Improvements
-
Plugin management UI hardening: Builtin plugins (
distribution=builtin) are now protected from enable/disable, install, uninstall, upgrade, and tenant provisioning policy changes in the management table. Version display shows a visual diff arrow when the effective version differs from the discovered version. Disabling or uninstalling a plugin now automatically closes its open tabs. -
Host config read priority unification: The host configuration read path is unified so that static host configuration takes precedence for plugins, and the
Getmethod now accepts a default value parameter for missing keys. -
Plugin build configuration consolidation: Plugin build commands, GoFrame code generation config, and
hack/config.yamlare consolidated into each plugin's root directory, reducing scattered configuration files. -
User profile password validation enhancement: The user profile update API now allows partial password updates, so users can update their profile without being forced to provide both old and new passwords.
-
Plugin service method refactoring and test coverage: Plugin service methods are refactored with improved dependency injection patterns, and test coverage is significantly expanded across plugin lifecycle, runtime upgrade, auto-enable, list projection, and host service authorization.
-
Domain capability Service unification: Consolidated all plugin-visible domain capabilities into unified
Serviceinterfaces, eliminating theAdminServiceseparation. Each domain now has a singleServicewith method-level governance metadata, enabling both source code and dynamic plugins to consume identical capability contracts. -
Authorization domain capability unification: Unified authorization capabilities under the auth domain with
Auth.Token()andAuth.Authz()sub-capabilities for tenant token selection, impersonation tokens, and permission management. -
Graceful shutdown configuration simplified: The separate
shutdownconfiguration section is removed in favor of GoFrame's nativeserver.gracefulShutdownTimeoutsetting (default 30s), reducing configuration surface area. -
Health endpoint removed: The
/healthAPI endpoint and its controller are removed. Health probing is now handled through existing system info endpoints. -
Config key namespace standardization: Built-in config keys for scheduled jobs are renamed from
cron.shell.enabled/cron.log.retentiontosys.cron.shell.enabled/sys.cron.log.retentionto follow thesys.prefix convention. -
Dynamic plugin host call demo enhancement: The dynamic demo plugin's host call service is significantly expanded with new job registration, heartbeat, and host service interaction examples, along with improved test coverage.
-
Plugin manifest YAML documentation: All
plugin.yamlfiles across official plugins now include bilingual inline comments documenting each field's purpose and allowed values.
Bug Fixes
-
Sidebar menu refresh after plugin lifecycle changes (#63): Fixed an issue where the sidebar menus did not refresh after plugin install, uninstall, or enable/disable operations.
-
Tenant plugin pointer update (#64): Fixed the tenant plugin submodule pointer to ensure correct plugin state after lifecycle operations.
-
Timezone display error (#72): Fixed a bug where timestamps displayed in the management UI were offset by the local timezone (e.g., +8 hours) due to incorrect UTC/GMT handling. Frontend time formatting now uses Unix milliseconds rendered in the selected timezone, and all built-in timezone labels use
UTCinstead ofGMT. A regression test confirms2026-06-29 09:30:08 UTCdisplays as2026-06-29 17:30:08inAsia/Shanghai. -
Profile password-only update rejected (#71): Fixed a bug where
PUT /api/v1/user/profilerequirednicknameeven when the user only wanted to change their password. Thenickname,email,phone,sex, andpasswordfields are now all optional, enabling partial profile updates. -
Post management department tree collapse (#57): Fixed a bug where the department tree on the post management page would collapse and fail to re-expand after creating new posts. The tree now automatically collects and expands all department node IDs after each refresh. An E2E test (
TC004-post-dept-tree-refresh-expand) covers the scenario of creating two consecutive posts while the tree remains expanded. -
Tenant user login fallback to platform admin (#74): Fixed a security issue where a tenant user (
tenant_id > 0) would receive a JWT withTenantId: 0(platform admin) when the tenant plugin was disabled, becauseloginTenantsreturned an empty list and the token issuer defaulted to the platform tenant. The login check now rejects non-platform users when the tenant service is unavailable (!tenantSvcAvailable), not only when the tenant list is empty. A unit test confirms that login is blocked withCodeAuthTenantUnavailablewhen the tenant service reports unavailable.
Database Changes
-
TIMESTAMPTZ migration (all core tables): All
TIMESTAMPcolumns inapps/lina-core/manifest/sql/files (001 through 012, plus mock data) are changed toTIMESTAMPTZ. Affected tables includesys_user,sys_dict_type,sys_dict_data,sys_file,sys_online_session,sys_config,sys_menu,sys_role,sys_locker,sys_plugin,sys_plugin_release,sys_plugin_migration,sys_plugin_resource_ref,sys_plugin_node_state,sys_plugin_state,sys_notify_channel,sys_notify_message,sys_notify_delivery,sys_job_group,sys_job,sys_job_log,sys_cache_revision. Existing deployments must run anALTER COLUMN ... TYPE TIMESTAMPTZmigration or re-initialize the database. -
TIMESTAMPTZ migration (all plugin tables): Every official plugin's schema SQL is similarly migrated. Affected plugins:
linapro-ai-core,linapro-content-notice,linapro-demo-dynamic,linapro-demo-source,linapro-monitor-loginlog,linapro-monitor-operlog,linapro-monitor-server,linapro-org-core,linapro-tenant-core. Plugin mock data SQL files are also updated to useTIMESTAMPTZcasts. -
sys_kv_cachetable removed: Thesys_kv_cachetable, its unique indexuk_sys_kv_cache_tenant_owner_namespace_key, and its secondary indexes are removed from010-runtime-host-services.sql. Existing deployments should drop this table after upgrading. -
sys_plugin.distributioncolumn added: A newdistribution VARCHAR(32) NOT NULL DEFAULT 'managed'column is added to thesys_plugintable in008-plugin-framework.sql, with a column comment documentingmanagedandbuiltinas the allowed values. Existing deployments must runALTER TABLE sys_plugin ADD COLUMN distribution VARCHAR(32) NOT NULL DEFAULT 'managed'. -
Config key renames: Two built-in
sys_configseed rows in011-scheduled-job-management.sqlare renamed:cron.shell.enabledtosys.cron.shell.enabled, andcron.log.retentiontosys.cron.log.retention. Existing deployments must update these keys in thesys_configtable.
主要亮点
-
插件系统架构全面重构:对插件子系统的宿主服务、
WASM宿主调用、生命周期管理、存储层、升级流程和能力宿主/所有者模块进行了大规模重构。文件按更清晰的前缀重命名(wasm_host_service_*、runtime_*、lifecycle_*、store_*、upgrade_*),旧的单体hostservices包被capabilityhost和capabilityowner替代,Guest端插件桥接统一到pluginbridge下。这为未来插件生态扩展奠定了稳定基础。 -
新增领域能力架构设计:建立
capability.Services作为主框架与插件的统一契约边界。17+项业务领域(用户、认证、字典、文件、任务、会话等)现在暴露单一Service接口,供源码插件和动态插件统一消费。该架构提供清晰的解耦、方法级治理(风险、授权、数据权限)和丰富的基础能力(批量操作、候选搜索、可见性校验),同时通过service + method + resource授权机制为动态插件维护严格的安全隔离。 -
新增插件分发模式特性:根据插件在全生命周期中的治理方式将其划分为两类:
managed(默认)覆盖通过插件管理界面或plugin.autoEnable治理的插件,运维人员可完全控制其安装、启用、升级和卸载;builtin保留给宿主启动时必须自动安装、启用和升级的源码插件,其生命周期在管理界面中受保护,禁止手动干预。该特性为运维管理型插件与宿主自治型插件建立了清晰的行为边界。 -
新增Go静态检查质量门禁:新增
make lint跨平台命令,可在工作区内运行golangci-lint检查。工具版本通过.golangci-lint-version和.staticcheck-version文件锁定,开发环境在缺失工具时自动安装正确版本。这是AI驱动开发流程中高效保障代码质量的重要手段之一。 -
全表 TIMESTAMPTZ 标准化:核心框架和所有官方插件中的每个
TIMESTAMP列均迁移为TIMESTAMPTZ,并新增database.timezone配置项(默认Asia/Shanghai)。这消除了在PostgreSQL中显示和解码时间数据时的时区歧义。 -
内存缓存替代 SQL KV 缓存:移除了
sys_kv_cache表及其 DAO/实体层。分布式 KV 缓存改为基于gcache(内存)实现,配合协调修订号失效机制,减少了热缓存操作的数据库往返。
功能改进
-
插件管理界面加固:内建插件(
distribution=builtin)在管理表格中禁止执行启用/禁用、安装、卸载、升级和租户开通策略变更。版本列在有效版本与发现版本不一致时显示视觉差异箭头。禁用或卸载插件后自动关闭其已打开的标签页。 -
宿主配置读取优先级统一:宿主配置读取路径统一,静态宿主配置对插件优先,
Get方法新增默认值参数支持缺失键场景。 -
插件构建配置整合:插件构建命令、
GoFrame代码生成配置和hack/config.yaml整合到各插件根目录,减少分散的配置文件。 -
用户资料密码校验增强:用户资料更新接口现在允许部分密码更新,用户无需同时提供新旧密码即可更新资料。
-
插件服务方法重构与测试覆盖:插件服务方法重构并改进了依赖注入模式,插件生命周期、运行时升级、自动启用、列表投影和宿主服务授权等方面的测试覆盖显著扩展。
-
领域能力 Service 统一化:将所有插件可见的领域能力统一收敛到
Service接口,消除了原有的AdminService接口分类。每个领域现在暴露单一Service并配备方法级治理元数据,使源码插件和动态插件能够消费相同的能力契约。 -
授权领域能力统一:授权相关能力统一归入
auth领域,Auth.Token()和Auth.Authz()子能力提供统一的租户令牌选择、代用户令牌和权限管理接口。 -
优雅关停配置简化:移除独立的
shutdown配置段,改用GoFrame原生的server.gracefulShutdownTimeout设置(默认30秒),减少配置项。 -
健康检查端点移除:移除了
/healthAPI端点及其控制器。健康探测改由现有系统信息端点处理。 -
配置键命名空间标准化:定时任务的内置配置键从
cron.shell.enabled/cron.log.retention重命名为sys.cron.shell.enabled/sys.cron.log.retention,遵循sys.前缀规范。 -
动态插件宿主调用示例增强:动态演示插件的宿主调用服务大幅扩展,新增任务注册、心跳和宿主服务交互示例,测试覆盖同步提升。
-
插件清单 YAML 文档化:所有官方插件的
plugin.yaml文件均新增双语行内注释,说明各字段用途和允许值。
Bug 修复
-
插件生命周期变更后侧边栏菜单刷新 (#63):修复了插件安装、卸载或启用/禁用后侧边栏菜单未刷新的问题。
-
租户插件指针更新 (#64):修复了租户插件子模块指针,确保生命周期操作后插件状态正确。
-
时区显示偏移错误 (#72):修复了管理界面时间戳因 UTC/GMT 处理不当而被错误叠加本地时区偏移(如 +8 小时)的问题。前端时间格式化改为基于 Unix 毫秒时间戳在所选时区下渲染,所有内置时区选项的标签统一使用
UTC替代GMT。回归测试确认2026-06-29 09:30:08 UTC在Asia/Shanghai时区下正确显示为2026-06-29 17:30:08。 -
个人中心仅修改密码被拒绝 (#71):修复了
PUT /api/v1/user/profile接口在用户仅修改密码时仍要求必填nickname的问题。nickname、email、phone、sex和password字段现在均为可选,支持局部更新。 -
岗位管理页面部门树折叠 (#57):修复了岗位管理页面在新增岗位后左侧部门树折叠且无法重新展开的问题。部门树现在在每次刷新后自动收集并展开全部部门节点 ID。E2E 测试(
TC004-post-dept-tree-refresh-expand)覆盖了连续新增两个岗位后部门树仍保持展开的场景。 -
租户用户登录降级为平台超管 (#74):修复了一个安全问题:当租户插件被禁用时,租户用户(
tenant_id > 0)登录后会获得TenantId: 0(平台超管)的 JWT,因为loginTenants返回空列表后 token 签发默认使用了平台租户。登录校验逻辑现在在租户服务不可用时(!tenantSvcAvailable)即拒绝非超管用户登录,而不仅仅在租户列表为空时才拒绝。单元测试确认租户服务报告不可用时登录被正确阻止并返回CodeAuthTenantUnavailable。
数据库变更
-
TIMESTAMPTZ 迁移(所有核心表):
apps/lina-core/manifest/sql/下的所有 SQL 文件(001 至 012,以及 mock 数据)中的TIMESTAMP列均改为TIMESTAMPTZ。受影响的表包括sys_user、sys_dict_type、sys_dict_data、sys_file、sys_online_session、sys_config、sys_menu、sys_role、sys_locker、sys_plugin、sys_plugin_release、sys_plugin_migration、sys_plugin_resource_ref、sys_plugin_node_state、sys_plugin_state、sys_notify_channel、sys_notify_message、sys_notify_delivery、sys_job_group、sys_job、sys_job_log、sys_cache_revision。已有部署需执行ALTER COLUMN ... TYPE TIMESTAMPTZ迁移或重新初始化数据库。 -
TIMESTAMPTZ 迁移(所有插件表):每个官方插件的 schema SQL 同样完成迁移。受影响插件:
linapro-ai-core、linapro-content-notice、linapro-demo-dynamic、linapro-demo-source、linapro-monitor-loginlog、linapro-monitor-operlog、linapro-monitor-server、linapro-org-core、linapro-tenant-core。插件 mock 数据 SQL 文件也同步更新为TIMESTAMPTZ类型转换。 -
sys_kv_cache表移除:010-runtime-host-services.sql中的sys_kv_cache表、其唯一索引uk_sys_kv_cache_tenant_owner_namespace_key及二级索引均已移除。已有部署应在升级后删除该表。 -
sys_plugin.distribution列新增:008-plugin-framework.sql中的sys_plugin表新增distribution VARCHAR(32) NOT NULL DEFAULT 'managed'列,并附有列注释说明managed和builtin为允许值。已有部署需执行ALTER TABLE sys_plugin ADD COLUMN distribution VARCHAR(32) NOT NULL DEFAULT 'managed'。 -
配置键重命名:
011-scheduled-job-management.sql中两个内置sys_config种子行重命名:cron.shell.enabled改为sys.cron.shell.enabled,cron.log.retention改为sys.cron.log.retention。已有部署需在sys_config表中更新这些键。