@yeaft/webchat-agent 1.0.662 → 1.0.663

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,7 +41,9 @@ db.exec(`
41
41
  CREATE TABLE IF NOT EXISTS user_preferences (
42
42
  user_id TEXT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
43
43
  sidebar_projects_ratio REAL NOT NULL DEFAULT 0.5
44
- CHECK (sidebar_projects_ratio >= 0.15 AND sidebar_projects_ratio <= 0.85)
44
+ CHECK (sidebar_projects_ratio >= 0.15 AND sidebar_projects_ratio <= 0.85),
45
+ sidebar_actions_compact INTEGER NOT NULL DEFAULT 0
46
+ CHECK (sidebar_actions_compact IN (0, 1))
45
47
  );
46
48
 
47
49
  -- Finalized deletion survives removal of the users row. This prevents a
@@ -337,6 +339,8 @@ db.exec(`
337
339
 
338
340
  // 数据库迁移 - 添加缺失的列
339
341
  const migrations = [
342
+ `ALTER TABLE user_preferences ADD COLUMN sidebar_actions_compact INTEGER NOT NULL DEFAULT 0
343
+ CHECK (sidebar_actions_compact IN (0, 1))`,
340
344
  `ALTER TABLE sessions ADD COLUMN user_id TEXT REFERENCES users(id)`,
341
345
  `ALTER TABLE users ADD COLUMN totp_secret TEXT`,
342
346
  `ALTER TABLE users ADD COLUMN totp_enabled INTEGER DEFAULT 0`,
@@ -907,14 +911,16 @@ export const stmts = {
907
911
  `),
908
912
 
909
913
  getUserPreferences: db.prepare(`
910
- SELECT sidebar_projects_ratio FROM user_preferences WHERE user_id = ?
914
+ SELECT sidebar_projects_ratio, sidebar_actions_compact FROM user_preferences WHERE user_id = ?
911
915
  `),
912
916
 
913
917
  upsertUserPreferences: db.prepare(`
914
- INSERT INTO user_preferences (user_id, sidebar_projects_ratio)
915
- VALUES (?, ?)
918
+ INSERT INTO user_preferences (user_id, sidebar_projects_ratio, sidebar_actions_compact)
919
+ VALUES (?, COALESCE(?, 0.5), COALESCE(?, 0))
916
920
  ON CONFLICT(user_id) DO UPDATE SET
917
- sidebar_projects_ratio = excluded.sidebar_projects_ratio
921
+ sidebar_projects_ratio = COALESCE(?, user_preferences.sidebar_projects_ratio),
922
+ sidebar_actions_compact = COALESCE(?, user_preferences.sidebar_actions_compact)
923
+ RETURNING sidebar_projects_ratio, sidebar_actions_compact
918
924
  `),
919
925
 
920
926
  // Invitation 操作
@@ -1,15 +1,23 @@
1
1
  import { stmts } from './connection.js';
2
2
 
3
+ function toPreferences(row) {
4
+ return {
5
+ sidebarProjectsRatio: row?.sidebar_projects_ratio ?? 0.5,
6
+ sidebarActionsCompact: !!row?.sidebar_actions_compact,
7
+ };
8
+ }
9
+
3
10
  /** Server-owned browser preferences, scoped to an authenticated user's DB id. */
4
11
  export const userPreferencesDb = {
5
12
  get(userId) {
6
- const row = stmts.getUserPreferences.get(userId);
7
- return { sidebarProjectsRatio: row?.sidebar_projects_ratio ?? 0.5 };
13
+ return toPreferences(stmts.getUserPreferences.get(userId));
8
14
  },
9
15
 
10
- // The HTTP boundary validates the ratio; the schema also enforces its range.
11
- update(userId, sidebarProjectsRatio) {
12
- stmts.upsertUserPreferences.run(userId, sidebarProjectsRatio);
13
- return this.get(userId);
16
+ // The HTTP boundary validates the patch. A single upsert preserves omitted
17
+ // fields without a read/merge/write race between independent clients.
18
+ update(userId, patch) {
19
+ const ratio = patch.sidebarProjectsRatio ?? null;
20
+ const compact = patch.sidebarActionsCompact === undefined ? null : Number(patch.sidebarActionsCompact);
21
+ return toPreferences(stmts.upsertUserPreferences.get(userId, ratio, compact, ratio, compact));
14
22
  },
15
23
  };
@@ -105,16 +105,20 @@ export function registerUserRoutes(app, {
105
105
 
106
106
  const body = req.body;
107
107
  if (!body || typeof body !== 'object' || Array.isArray(body)
108
- || Object.keys(body).some(key => key !== 'sidebarProjectsRatio')
109
- || typeof body.sidebarProjectsRatio !== 'number'
110
- || !Number.isFinite(body.sidebarProjectsRatio)
111
- || body.sidebarProjectsRatio < 0.15 || body.sidebarProjectsRatio > 0.85) {
108
+ || Object.keys(body).length === 0
109
+ || Object.keys(body).some(key => key !== 'sidebarProjectsRatio' && key !== 'sidebarActionsCompact')
110
+ || (Object.hasOwn(body, 'sidebarProjectsRatio') && (
111
+ typeof body.sidebarProjectsRatio !== 'number'
112
+ || !Number.isFinite(body.sidebarProjectsRatio)
113
+ || body.sidebarProjectsRatio < 0.15 || body.sidebarProjectsRatio > 0.85
114
+ ))
115
+ || (Object.hasOwn(body, 'sidebarActionsCompact') && typeof body.sidebarActionsCompact !== 'boolean')) {
112
116
  return res.status(400).json({
113
- error: 'Expected only sidebarProjectsRatio, a finite number between 0.15 and 0.85',
117
+ error: 'Expected a nonempty patch with only sidebarProjectsRatio (finite number between 0.15 and 0.85) and/or sidebarActionsCompact (boolean)',
114
118
  });
115
119
  }
116
120
 
117
- res.set('Cache-Control', 'private, no-store').json(userPreferencesDb.update(user.id, body.sidebarProjectsRatio));
121
+ res.set('Cache-Control', 'private, no-store').json(userPreferencesDb.update(user.id, body));
118
122
  } catch (err) {
119
123
  console.error('Update preferences error:', err);
120
124
  res.status(500).json({ error: 'Failed to update preferences' });
@@ -1 +1 @@
1
- {"version":"1.0.662"}
1
+ {"version":"1.0.663"}