1
0
forked from boos/BoosAPI

feat: Add normalized types and utility functions for handling chat formats

- Introduced `NormalizedContentBlock`, `NormalizedUsage`, and related types for structured data handling.
- Implemented utility functions for creating and merging normalized usage statistics.
- Added a new module for shared transformers to manage chat formats.

feat: Implement app local state management

- Created functions to clear application installation state and manage local storage keys.
- Added constants for theme and user profile storage keys.

test: Add tests for BrandIcon component rendering

- Implemented tests to ensure BrandIcon does not force a colored background for recognized brands.

test: Enhance ModelAnalysisPanel tests

- Added tests for rendering token summaries with compact units in ModelAnalysisPanel.

test: Add tests for ModernSelect component

- Implemented tests to verify icon rendering for selected options in ModernSelect.

test: Add number formatting tests

- Created tests for `formatCompactTokenMetric` to validate token formatting logic.

feat: Implement account creation intent handling

- Added logic to handle session and API key creation intents in the Accounts page.

test: Add tests for dashboard performance card

- Implemented tests to verify rendering of performance metrics in the dashboard.

feat: Implement default connection segment resolution

- Added logic to determine initial connection segments based on platform types.

test: Add tests for settings factory reset functionality

- Implemented tests to verify the factory reset process and local state clearing.

test: Add tests for site creation redirect logic

- Implemented tests to verify redirection based on site capabilities during creation.

test: Add tests for token routes refresh decision action

- Implemented tests to verify refresh decision actions in TokenRoutes.

test: Add tests for token routes snapshot load

- Implemented tests to verify loading of cached snapshot data in TokenRoutes.
This commit is contained in:
cita
2026-03-08 12:08:57 +08:00
parent ed05b37626
commit 23922a5965
115 changed files with 18597 additions and 4411 deletions
+53
View File
@@ -23,6 +23,7 @@ const TABLES_WITH_NUMERIC_ID = new Set([
'token_routes',
'route_channels',
'proxy_logs',
'proxy_video_tasks',
'downstream_api_keys',
'events',
]);
@@ -138,6 +139,49 @@ function ensureTokenManagementSchema() {
`);
}
function ensureProxyVideoTaskSchema() {
const sqlite = requireSqliteConnection();
sqlite.exec(`
CREATE TABLE IF NOT EXISTS proxy_video_tasks (
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
public_id text NOT NULL,
upstream_video_id text NOT NULL,
site_url text NOT NULL,
token_value text NOT NULL,
requested_model text,
actual_model text,
channel_id integer,
account_id integer,
status_snapshot text,
upstream_response_meta text,
last_upstream_status integer,
last_polled_at text,
created_at text DEFAULT (datetime('now')),
updated_at text DEFAULT (datetime('now'))
);
`);
if (!tableColumnExists('proxy_video_tasks', 'status_snapshot')) {
sqlite.exec('ALTER TABLE proxy_video_tasks ADD COLUMN status_snapshot text;');
}
if (!tableColumnExists('proxy_video_tasks', 'upstream_response_meta')) {
sqlite.exec('ALTER TABLE proxy_video_tasks ADD COLUMN upstream_response_meta text;');
}
if (!tableColumnExists('proxy_video_tasks', 'last_upstream_status')) {
sqlite.exec('ALTER TABLE proxy_video_tasks ADD COLUMN last_upstream_status integer;');
}
if (!tableColumnExists('proxy_video_tasks', 'last_polled_at')) {
sqlite.exec('ALTER TABLE proxy_video_tasks ADD COLUMN last_polled_at text;');
}
sqlite.exec(`
CREATE UNIQUE INDEX IF NOT EXISTS proxy_video_tasks_public_id_unique
ON proxy_video_tasks(public_id);
`);
sqlite.exec(`
CREATE INDEX IF NOT EXISTS proxy_video_tasks_upstream_video_id_idx
ON proxy_video_tasks(upstream_video_id);
`);
}
function ensureSiteStatusSchema() {
const sqlite = requireSqliteConnection();
if (!tableExists('sites')) {
@@ -303,6 +347,14 @@ function ensureRouteGroupingSchema() {
sqlite.exec(`ALTER TABLE token_routes ADD COLUMN display_icon text;`);
}
if (!tableColumnExists('token_routes', 'decision_snapshot')) {
sqlite.exec(`ALTER TABLE token_routes ADD COLUMN decision_snapshot text;`);
}
if (!tableColumnExists('token_routes', 'decision_refreshed_at')) {
sqlite.exec(`ALTER TABLE token_routes ADD COLUMN decision_refreshed_at text;`);
}
if (!tableColumnExists('route_channels', 'source_model')) {
sqlite.exec(`ALTER TABLE route_channels ADD COLUMN source_model text;`);
}
@@ -695,6 +747,7 @@ function initSqliteDb() {
ensureRouteGroupingSchema();
ensureDownstreamApiKeySchema();
ensureProxyLogBillingDetailsSchema();
ensureProxyVideoTaskSchema();
const rawDb = drizzleSqliteProxy(
(sqlText, params, method) => sqliteProxyQuery(sqlText, params, method as SqlMethod),
+24
View File
@@ -109,6 +109,8 @@ export const tokenRoutes = sqliteTable('token_routes', {
displayName: text('display_name'),
displayIcon: text('display_icon'),
modelMapping: text('model_mapping'), // JSON
decisionSnapshot: text('decision_snapshot'), // JSON
decisionRefreshedAt: text('decision_refreshed_at'),
enabled: integer('enabled', { mode: 'boolean' }).default(true),
createdAt: text('created_at').default(sql`(datetime('now'))`),
updatedAt: text('updated_at').default(sql`(datetime('now'))`),
@@ -167,6 +169,28 @@ export const proxyLogs = sqliteTable('proxy_logs', {
modelActualCreatedIdx: index('proxy_logs_model_actual_created_at_idx').on(table.modelActual, table.createdAt),
}));
export const proxyVideoTasks = sqliteTable('proxy_video_tasks', {
id: integer('id').primaryKey({ autoIncrement: true }),
publicId: text('public_id').notNull(),
upstreamVideoId: text('upstream_video_id').notNull(),
siteUrl: text('site_url').notNull(),
tokenValue: text('token_value').notNull(),
requestedModel: text('requested_model'),
actualModel: text('actual_model'),
channelId: integer('channel_id'),
accountId: integer('account_id'),
statusSnapshot: text('status_snapshot'),
upstreamResponseMeta: text('upstream_response_meta'),
lastUpstreamStatus: integer('last_upstream_status'),
lastPolledAt: text('last_polled_at'),
createdAt: text('created_at').default(sql`(datetime('now'))`),
updatedAt: text('updated_at').default(sql`(datetime('now'))`),
}, (table) => ({
publicIdUnique: uniqueIndex('proxy_video_tasks_public_id_unique').on(table.publicId),
upstreamVideoIdIdx: index('proxy_video_tasks_upstream_video_id_idx').on(table.upstreamVideoId),
createdAtIdx: index('proxy_video_tasks_created_at_idx').on(table.createdAt),
}));
export const settings = sqliteTable('settings', {
key: text('key').primaryKey(),
value: text('value'), // JSON