固定用途查询、受控导出与删除证明
tio-boot 的显式路由、请求拦截器和 java-db 事务适合承载用途清晰的数据服务。将身份认证、对象授权、业务事实、导出交付和删除证据分开,可以让用户看懂实际结果,也方便后台按原事项继续核验。
固定查询与字段白名单
先定义少量业务查询,再为每类查询配置固定 SQL、允许的期间和返回字段。参数只提供值,不让客户端提交表名、列名、SQL 或任意筛选表达式。身份来自已验证会话,对象范围在服务端重新检查。
公开字段、本人权益字段、分派事项字段、现金凭证应使用不同返回对象。聚合岗无需获得个人明细;配置岗可以查看版本和生效时点,无需读取现金凭证。前端按钮可见性用于交互,服务端仍逐次核权。
用一个事务记录执行结果和证据
以下示例假定应用迁移已经创建 app_display_record 和 app_purpose_receipt。accountId 必须由已认证身份得到;实际应用还应按原操作键做幂等校验。本例展示数据库事务和资源关闭方式,不能直接替代完整业务授权。
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.time.Instant;
import nexus.io.db.activerecord.Db;
import nexus.io.tio.utils.snowflake.SnowflakeIdUtils;
public final class DisplayCleanupService {
public long clearOwnedDisplay(long accountId) {
long receiptId = SnowflakeIdUtils.id();
Instant now = Instant.now();
boolean committed = Db.tx(Connection.TRANSACTION_REPEATABLE_READ, () -> {
Db.execute(connection -> {
int deletedRows;
try (PreparedStatement statement = connection.prepareStatement(
"delete from app_display_record where account_id=?")) {
statement.setLong(1, accountId);
deletedRows = statement.executeUpdate();
}
try (PreparedStatement statement = connection.prepareStatement("""
insert into app_purpose_receipt
(id, account_id, purpose_code, local_state, backup_state,
deleted_rows, completed_at)
values (?, ?, 'DISPLAY', 'SUCCEEDED', 'UNKNOWN', ?, ?)
""")) {
statement.setLong(1, receiptId);
statement.setLong(2, accountId);
statement.setInt(3, deletedRows);
statement.setTimestamp(4, Timestamp.from(now));
statement.executeUpdate();
}
return null;
});
return true;
});
if (!committed) {
throw new IllegalStateException("本地清理尚未提交");
}
return receiptId;
}
}
Db.execute 可以在当前事务连接上使用 JDBC 参数绑定。外层服务在执行首条 SQL 前确定隔离级别;一个调用链中的嵌套服务保持兼容的隔离级别,避免在事务中途改变隔离要求。删除和证据写入一起提交,重试时查询同一个操作键,不能把重复请求当成新的业务意图。
导出是有期限的业务交付
建议按“申请、独立批准、指定执行、下载”建模,分别记录自然人、用途、对象、期间、行数、字段类别、生成和到期时间。批准之后仍可能发生撤权,因此生成和下载都要重新核验申请人、批准人及执行人的当前权限和自然人关联。
有行数上限时,可固定查询上限加一行。多出的那一行用于判定超限,不能静默截断后宣称完整导出。同事项同目的的累计限制应持久化,不能仅检查单次 HTTP 请求。将文件内容与审计元数据分离,到期撤销下载并清理临时内容;审计只保留必要引用,不复制明细正文。
删除证明按用途分项表达
| 对象 | 可核结果 |
|---|---|
| 浏览与联系展示 | 本地记录已清理,不影响必要的长期联系去重 |
| 原始观察 | 按原发生时点到期,迟到接收不延长期限 |
| AI 辅助正文 | 沿该用途的独立期限处理,不套用业务账本期限 |
| 现金、权益及未结事项 | 沿原业务责任保留必要部分,给出具体复核点 |
| 备份、外部处理者、已下载文件 | 分别核验证据,未知就显示待核 |
应用可用 EnvUtils.get 或类型化读取方法管理采集开关。开关和用途核验同时满足才启用新增采集。删除完成证据只证明已执行的范围,不用本地成功代替外部副本清除。
固定聚合的解释
业务事实来自原业务 Owner,观察不能改写收款、退款、权益或履约。事件采用稳定身份去重;同身份相同内容只计一次,冲突进入待核。迟到数据修订原期并保留版本,不增加本期成功数。
同期间、同范围的详情主体作为分母,分子只能来自其中的首次揭示主体。零分母显示不适用,缺覆盖显示未核实,小样本不显示人数和比例。固定自然日、固定维度、互补单元格抑制及修订后数值限制可以减少差分风险;这些措施仍不等于匿名化证明。删除原始身份关联后,不将每日人数相加为跨期独立人数。
