Skip to content

LinaPro Release v0.5.0

Latest

Choose a tag to compare

@gqcn gqcn released this 03 Jul 05:38
· 26 commits to main since this release
5e433f1

Highlights

  • Domain capability architecture: Established capability.Services as the unified contract boundary between framework and plugins. All 17+ business domains (Users, Auth, Dict, Files, Jobs, Sessions, etc.) now expose a single Service interface consumed by both source code and dynamic plugins, replacing the previous AdminService separation. 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 through service + method + resource authorization 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 monolithic hostservices package is replaced by capabilityhost and capabilityowner, and the guest-side plugin bridge is consolidated under pluginbridge. This lays a stable foundation for future plugin ecosystem growth.

  • TIMESTAMPTZ standardization across all tables: Every TIMESTAMP column in the core framework and all official plugins is migrated to TIMESTAMPTZ, and a new database.timezone configuration option (defaulting to Asia/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_cache table and its DAO/entity layer are removed. Distributed KV caching is now backed by gcache (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 or plugin.autoEnable, giving operators full control over install, enable, upgrade, and uninstall. builtin is 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 lint cross-platform command for running golangci-lint across the workspace. Supports plugins=0 (host-only) and plugins=1 (full workspace including official plugins) modes. Tool versions are locked via .golangci-lint-version and .staticcheck-version files, and linactl automatically 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 Get method now accepts a default value parameter for missing keys.

  • Plugin build configuration consolidation: Plugin build commands, GoFrame code generation config, and hack/config.yaml are 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 Service interfaces, eliminating the AdminService separation. Each domain now has a single Service with 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() and Auth.Authz() sub-capabilities for tenant token selection, impersonation tokens, and permission management.

  • Graceful shutdown configuration simplified: The separate shutdown configuration section is removed in favor of GoFrame's native server.gracefulShutdownTimeout setting (default 30s), reducing configuration surface area.

  • Health endpoint removed: The /health API 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.retention to sys.cron.shell.enabled / sys.cron.log.retention to follow the sys. 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.yaml files 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 UTC instead of GMT. A regression test confirms 2026-06-29 09:30:08 UTC displays as 2026-06-29 17:30:08 in Asia/Shanghai.

  • Profile password-only update rejected (#71): Fixed a bug where PUT /api/v1/user/profile required nickname even when the user only wanted to change their password. The nickname, email, phone, sex, and password fields 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 with TenantId: 0 (platform admin) when the tenant plugin was disabled, because loginTenants returned 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 with CodeAuthTenantUnavailable when the tenant service reports unavailable.

Database Changes

  • TIMESTAMPTZ migration (all core tables): All TIMESTAMP columns in apps/lina-core/manifest/sql/ files (001 through 012, plus mock data) are changed to TIMESTAMPTZ. Affected tables include 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. Existing deployments must run an ALTER COLUMN ... TYPE TIMESTAMPTZ migration 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 use TIMESTAMPTZ casts.

  • sys_kv_cache table removed: The sys_kv_cache table, its unique index uk_sys_kv_cache_tenant_owner_namespace_key, and its secondary indexes are removed from 010-runtime-host-services.sql. Existing deployments should drop this table after upgrading.

  • sys_plugin.distribution column added: A new distribution VARCHAR(32) NOT NULL DEFAULT 'managed' column is added to the sys_plugin table in 008-plugin-framework.sql, with a column comment documenting managed and builtin as the allowed values. Existing deployments must run ALTER TABLE sys_plugin ADD COLUMN distribution VARCHAR(32) NOT NULL DEFAULT 'managed'.

  • Config key renames: Two built-in sys_config seed rows in 011-scheduled-job-management.sql are renamed: cron.shell.enabled to sys.cron.shell.enabled, and cron.log.retention to sys.cron.log.retention. Existing deployments must update these keys in the sys_config table.


主要亮点

  • 插件系统架构全面重构:对插件子系统的宿主服务、WASM 宿主调用、生命周期管理、存储层、升级流程和能力宿主/所有者模块进行了大规模重构。文件按更清晰的前缀重命名(wasm_host_service_*runtime_*lifecycle_*store_*upgrade_*),旧的单体 hostservices 包被 capabilityhostcapabilityowner 替代,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 秒),减少配置项。

  • 健康检查端点移除:移除了 /health API 端点及其控制器。健康探测改由现有系统信息端点处理。

  • 配置键命名空间标准化:定时任务的内置配置键从 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 UTCAsia/Shanghai 时区下正确显示为 2026-06-29 17:30:08

  • 个人中心仅修改密码被拒绝 (#71):修复了 PUT /api/v1/user/profile 接口在用户仅修改密码时仍要求必填 nickname 的问题。nicknameemailphonesexpassword 字段现在均为可选,支持局部更新。

  • 岗位管理页面部门树折叠 (#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_usersys_dict_typesys_dict_datasys_filesys_online_sessionsys_configsys_menusys_rolesys_lockersys_pluginsys_plugin_releasesys_plugin_migrationsys_plugin_resource_refsys_plugin_node_statesys_plugin_statesys_notify_channelsys_notify_messagesys_notify_deliverysys_job_groupsys_jobsys_job_logsys_cache_revision。已有部署需执行 ALTER COLUMN ... TYPE TIMESTAMPTZ 迁移或重新初始化数据库。

  • TIMESTAMPTZ 迁移(所有插件表):每个官方插件的 schema SQL 同样完成迁移。受影响插件:linapro-ai-corelinapro-content-noticelinapro-demo-dynamiclinapro-demo-sourcelinapro-monitor-loginloglinapro-monitor-operloglinapro-monitor-serverlinapro-org-corelinapro-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' 列,并附有列注释说明 managedbuiltin 为允许值。已有部署需执行 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.enabledcron.log.retention 改为 sys.cron.log.retention。已有部署需在 sys_config 表中更新这些键。