feat: 会话记录接入客户端 X-Device-Id(auth_sessions.device_id)

- Flutter 端每次请求已携带 X-Device-Id;auth 读取该头(截断 128)经 CreateSessionRequest 透传,user 落 auth_sessions.device_id,为多设备会话列表备数据
- 门禁:./mvnw clean test → BUILD SUCCESS,74 测试 0 失败(新增 registerForwardsDeviceIdHeaderToTheSessionRecord + 会话落库断言)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 14:43:44 +08:00
parent 4dc3dcdfa3
commit 8bdaf53222
7 changed files with 65 additions and 16 deletions
@@ -57,7 +57,8 @@ class SessionLifecycleIntegrationTest {
private Map<String, Object> createSession(String userId) throws Exception {
String body = mockMvc.perform(internalPost("/internal/sessions")
.content("{\"userId\":\"%s\",\"userAgent\":\"junit\",\"ipAddress\":\"127.0.0.1\"}"
.content(("{\"userId\":\"%s\",\"deviceId\":\"junit-device\","
+ "\"userAgent\":\"junit\",\"ipAddress\":\"127.0.0.1\"}")
.formatted(userId)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0))
@@ -91,6 +92,13 @@ class SessionLifecycleIntegrationTest {
assertThat(storedHash).isEqualTo(expected).hasSize(32);
// The plaintext token appears nowhere in the row.
assertThat(new String(storedHash, StandardCharsets.ISO_8859_1)).isNotEqualTo(refreshToken);
String deviceId = jdbcClient.sql(
"SELECT device_id FROM identity.auth_sessions WHERE id = :id")
.param("id", UUID.fromString((String) session.get("sessionId")))
.query(String.class)
.single();
assertThat(deviceId).isEqualTo("junit-device");
}
@Test