refactor(apps): 重构数据层目录结构并新增启动预热编排器

This commit is contained in:
zl-q
2026-03-29 20:26:30 +08:00
parent 33340de8f9
commit 4db9a13bfe
108 changed files with 1653 additions and 1320 deletions
@@ -0,0 +1,89 @@
import 'package:dio/dio.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:social_app/data/network/i_api_client.dart';
import 'package:social_app/data/cache/cache_store.dart';
import 'package:social_app/features/chat/data/repositories/chat_history_repository.dart';
class _FakeApiClient implements IApiClient {
final Map<String, dynamic> _getResponses = <String, dynamic>{};
final Map<String, int> getCalls = <String, int>{};
void setGet(String path, dynamic data) => _getResponses[path] = data;
@override
Future<Response<T>> get<T>(String path, {Options? options}) async {
getCalls[path] = (getCalls[path] ?? 0) + 1;
if (!_getResponses.containsKey(path)) {
throw StateError('missing GET mock for $path');
}
return Response<T>(
requestOptions: RequestOptions(path: path),
data: _getResponses[path] as T,
);
}
@override
Future<Response<T>> delete<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
@override
Future<Stream<String>> getSseLines(
String path, {
Map<String, String>? headers,
}) {
throw UnimplementedError();
}
@override
Future<Response<T>> patch<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
@override
Future<Response<T>> post<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
@override
Future<Response<T>> put<T>(String path, {data, Options? options}) {
throw UnimplementedError();
}
}
void main() {
test('loads first-page history from cache on second read', () async {
final client = _FakeApiClient();
client.setGet('/api/v1/agent/history', {
'scope': 'history_day',
'threadId': 't1',
'day': '2026-03-29',
'hasMore': true,
'messages': [
{
'id': 'm1',
'seq': 1,
'role': 'assistant',
'content': 'hello',
'timestamp': '2026-03-29T08:00:00Z',
'attachments': [],
},
],
});
final repository = ChatHistoryRepository(
apiClient: client,
store: HybridCacheStore(
memory: MemoryCacheStore(),
persistent: PersistentCacheStore(),
),
);
final first = await repository.loadHistory();
final second = await repository.loadHistory();
expect(first.threadId, 't1');
expect(second.messages.length, 1);
expect(client.getCalls['/api/v1/agent/history'], 1);
});
}