feat(knowledge): add KnowledgeApi, KnowledgeRepository, wire providers
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../models/knowledge_item.dart';
|
||||
import 'api_client.dart';
|
||||
|
||||
class KnowledgeApi {
|
||||
final Dio _dio;
|
||||
const KnowledgeApi(this._dio);
|
||||
|
||||
/// Fetch a page of IDs. Returns (ids, total).
|
||||
Future<(List<int>, int)> fetchIds({
|
||||
String? noteType,
|
||||
List<String> tags = const [],
|
||||
String sort = 'modified',
|
||||
String? q,
|
||||
int limit = 50,
|
||||
int offset = 0,
|
||||
}) async {
|
||||
try {
|
||||
final params = <String, dynamic>{
|
||||
'limit': limit,
|
||||
'offset': offset,
|
||||
'sort': sort,
|
||||
if (noteType != null) 'type': noteType,
|
||||
if (tags.isNotEmpty) 'tags': tags.join(','),
|
||||
if (q != null && q.isNotEmpty) 'q': q,
|
||||
};
|
||||
final response =
|
||||
await _dio.get('/api/knowledge/ids', queryParameters: params);
|
||||
final data = response.data as Map<String, dynamic>;
|
||||
final ids =
|
||||
(data['ids'] as List<dynamic>).map((e) => e as int).toList();
|
||||
final total = data['total'] as int;
|
||||
return (ids, total);
|
||||
} on DioException catch (e) {
|
||||
throw dioToApp(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Batch-hydrate up to 100 IDs into full items.
|
||||
Future<List<KnowledgeItem>> fetchBatch(List<int> ids) async {
|
||||
if (ids.isEmpty) return [];
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
'/api/knowledge/batch',
|
||||
queryParameters: {'ids': ids.join(',')},
|
||||
);
|
||||
final data = response.data as Map<String, dynamic>;
|
||||
return (data['items'] as List<dynamic>)
|
||||
.map((e) => KnowledgeItem.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on DioException catch (e) {
|
||||
throw dioToApp(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Per-type counts for tab labels.
|
||||
Future<Map<String, int>> fetchCounts({List<String> tags = const []}) async {
|
||||
try {
|
||||
final params = <String, dynamic>{
|
||||
if (tags.isNotEmpty) 'tags': tags.join(','),
|
||||
};
|
||||
final response = await _dio.get('/api/knowledge/counts',
|
||||
queryParameters: params);
|
||||
return (response.data as Map<String, dynamic>)
|
||||
.map((k, v) => MapEntry(k, (v as num).toInt()));
|
||||
} on DioException catch (e) {
|
||||
throw dioToApp(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// All tags for the current type filter.
|
||||
Future<List<String>> fetchTags({String? noteType}) async {
|
||||
try {
|
||||
final response = await _dio.get(
|
||||
'/api/knowledge/tags',
|
||||
queryParameters: {if (noteType != null) 'type': noteType},
|
||||
);
|
||||
return (response.data['tags'] as List<dynamic>)
|
||||
.map((e) => e as String)
|
||||
.toList();
|
||||
} on DioException catch (e) {
|
||||
throw dioToApp(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import '../api/knowledge_api.dart';
|
||||
import '../models/knowledge_item.dart';
|
||||
|
||||
class KnowledgeRepository {
|
||||
final KnowledgeApi _api;
|
||||
const KnowledgeRepository(this._api);
|
||||
|
||||
Future<(List<int>, int)> fetchIds({
|
||||
String? noteType,
|
||||
List<String> tags = const [],
|
||||
String sort = 'modified',
|
||||
String? q,
|
||||
int limit = 50,
|
||||
int offset = 0,
|
||||
}) =>
|
||||
_api.fetchIds(
|
||||
noteType: noteType,
|
||||
tags: tags,
|
||||
sort: sort,
|
||||
q: q,
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
);
|
||||
|
||||
Future<List<KnowledgeItem>> fetchBatch(List<int> ids) =>
|
||||
_api.fetchBatch(ids);
|
||||
|
||||
Future<Map<String, int>> fetchCounts({List<String> tags = const []}) =>
|
||||
_api.fetchCounts(tags: tags);
|
||||
|
||||
Future<List<String>> fetchTags({String? noteType}) =>
|
||||
_api.fetchTags(noteType: noteType);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import '../data/api/api_client.dart';
|
||||
import '../data/api/auth_api.dart';
|
||||
import '../data/api/briefing_api.dart';
|
||||
import '../data/api/chat_api.dart';
|
||||
import '../data/api/knowledge_api.dart';
|
||||
import '../data/api/milestones_api.dart';
|
||||
import '../data/api/notes_api.dart';
|
||||
import '../data/api/projects_api.dart';
|
||||
@@ -14,6 +15,7 @@ import '../data/api/settings_api.dart';
|
||||
import '../data/api/tasks_api.dart';
|
||||
import '../data/repositories/auth_repository.dart';
|
||||
import '../data/repositories/chat_repository.dart';
|
||||
import '../data/repositories/knowledge_repository.dart';
|
||||
import '../data/repositories/milestones_repository.dart';
|
||||
import '../data/repositories/notes_repository.dart';
|
||||
import '../data/repositories/projects_repository.dart';
|
||||
@@ -83,6 +85,14 @@ final milestonesRepositoryProvider = Provider<MilestonesRepository>((ref) {
|
||||
return MilestonesRepository(ref.watch(milestonesApiProvider));
|
||||
});
|
||||
|
||||
final knowledgeApiProvider = Provider<KnowledgeApi>((ref) {
|
||||
return KnowledgeApi(ref.watch(dioProvider));
|
||||
});
|
||||
|
||||
final knowledgeRepositoryProvider = Provider<KnowledgeRepository>((ref) {
|
||||
return KnowledgeRepository(ref.watch(knowledgeApiProvider));
|
||||
});
|
||||
|
||||
final briefingApiProvider = Provider<BriefingApi>((ref) {
|
||||
return BriefingApi(ref.watch(dioProvider));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user