feat(knowledge): add noteType field to Note model, api, repository, provider

This commit is contained in:
2026-04-04 23:37:53 -04:00
parent e89626a782
commit c8cdcbf230
5 changed files with 55 additions and 8 deletions
+4
View File
@@ -32,12 +32,14 @@ class NotesApi {
String body, { String body, {
List<String> tags = const [], List<String> tags = const [],
int? projectId, int? projectId,
String noteType = 'note',
}) async { }) async {
try { try {
final response = await _dio.post('/api/notes', data: { final response = await _dio.post('/api/notes', data: {
'title': title, 'title': title,
'body': body, 'body': body,
'tags': tags, 'tags': tags,
'note_type': noteType,
if (projectId != null) 'project_id': projectId, if (projectId != null) 'project_id': projectId,
}); });
return Note.fromJson(response.data as Map<String, dynamic>); return Note.fromJson(response.data as Map<String, dynamic>);
@@ -53,12 +55,14 @@ class NotesApi {
List<String> tags = const [], List<String> tags = const [],
int? projectId, int? projectId,
bool clearProject = false, bool clearProject = false,
String noteType = 'note',
}) async { }) async {
try { try {
final response = await _dio.put('/api/notes/$id', data: { final response = await _dio.put('/api/notes/$id', data: {
'title': title, 'title': title,
'body': body, 'body': body,
'tags': tags, 'tags': tags,
'note_type': noteType,
if (clearProject) 'project_id': null else if (projectId != null) 'project_id': projectId, if (clearProject) 'project_id': null else if (projectId != null) 'project_id': projectId,
}); });
return Note.fromJson(response.data as Map<String, dynamic>); return Note.fromJson(response.data as Map<String, dynamic>);
+6
View File
@@ -3,6 +3,7 @@ class Note {
final String title; final String title;
final String body; final String body;
final List<String> tags; final List<String> tags;
final String noteType;
final int? projectId; final int? projectId;
final int? milestoneId; final int? milestoneId;
final DateTime createdAt; final DateTime createdAt;
@@ -13,6 +14,7 @@ class Note {
required this.title, required this.title,
required this.body, required this.body,
required this.tags, required this.tags,
this.noteType = 'note',
this.projectId, this.projectId,
this.milestoneId, this.milestoneId,
required this.createdAt, required this.createdAt,
@@ -27,6 +29,7 @@ class Note {
?.map((e) => e as String) ?.map((e) => e as String)
.toList() ?? .toList() ??
[], [],
noteType: json['note_type'] as String? ?? 'note',
projectId: json['project_id'] as int?, projectId: json['project_id'] as int?,
milestoneId: json['milestone_id'] as int?, milestoneId: json['milestone_id'] as int?,
createdAt: DateTime.parse(json['created_at'] as String), createdAt: DateTime.parse(json['created_at'] as String),
@@ -37,6 +40,7 @@ class Note {
'title': title, 'title': title,
'body': body, 'body': body,
'tags': tags, 'tags': tags,
'note_type': noteType,
'project_id': projectId, 'project_id': projectId,
'milestone_id': milestoneId, 'milestone_id': milestoneId,
}; };
@@ -45,6 +49,7 @@ class Note {
String? title, String? title,
String? body, String? body,
List<String>? tags, List<String>? tags,
String? noteType,
Object? projectId = _undefined, Object? projectId = _undefined,
Object? milestoneId = _undefined, Object? milestoneId = _undefined,
}) => }) =>
@@ -53,6 +58,7 @@ class Note {
title: title ?? this.title, title: title ?? this.title,
body: body ?? this.body, body: body ?? this.body,
tags: tags ?? this.tags, tags: tags ?? this.tags,
noteType: noteType ?? this.noteType,
projectId: identical(projectId, _undefined) projectId: identical(projectId, _undefined)
? this.projectId ? this.projectId
: projectId as int?, : projectId as int?,
+8 -2
View File
@@ -13,8 +13,10 @@ class NotesRepository {
String body, { String body, {
List<String> tags = const [], List<String> tags = const [],
int? projectId, int? projectId,
String noteType = 'note',
}) => }) =>
_api.create(title, body, tags: tags, projectId: projectId); _api.create(title, body,
tags: tags, projectId: projectId, noteType: noteType);
Future<Note> update( Future<Note> update(
int id, int id,
@@ -23,9 +25,13 @@ class NotesRepository {
List<String> tags = const [], List<String> tags = const [],
int? projectId, int? projectId,
bool clearProject = false, bool clearProject = false,
String noteType = 'note',
}) => }) =>
_api.update(id, title, body, _api.update(id, title, body,
tags: tags, projectId: projectId, clearProject: clearProject); tags: tags,
projectId: projectId,
clearProject: clearProject,
noteType: noteType);
Future<void> delete(int id) => _api.delete(id); Future<void> delete(int id) => _api.delete(id);
} }
+9 -3
View File
@@ -17,10 +17,14 @@ class NotesNotifier extends AsyncNotifier<List<Note>> {
String body, { String body, {
List<String> tags = const [], List<String> tags = const [],
int? projectId, int? projectId,
String noteType = 'note',
}) async { }) async {
final note = await ref final note = await ref.read(notesRepositoryProvider).create(
.read(notesRepositoryProvider) title, body,
.create(title, body, tags: tags, projectId: projectId); tags: tags,
projectId: projectId,
noteType: noteType,
);
state = AsyncData([...state.value ?? [], note]); state = AsyncData([...state.value ?? [], note]);
return note; return note;
} }
@@ -32,6 +36,7 @@ class NotesNotifier extends AsyncNotifier<List<Note>> {
List<String> tags = const [], List<String> tags = const [],
int? projectId, int? projectId,
bool clearProject = false, bool clearProject = false,
String noteType = 'note',
}) async { }) async {
final updated = await ref.read(notesRepositoryProvider).update( final updated = await ref.read(notesRepositoryProvider).update(
id, id,
@@ -40,6 +45,7 @@ class NotesNotifier extends AsyncNotifier<List<Note>> {
tags: tags, tags: tags,
projectId: projectId, projectId: projectId,
clearProject: clearProject, clearProject: clearProject,
noteType: noteType,
); );
state = AsyncData([ state = AsyncData([
for (final n in state.value ?? []) for (final n in state.value ?? [])
+28 -3
View File
@@ -1,8 +1,33 @@
// Placeholder — integration tests go here once the app is running on device. import 'package:fabled_app/data/models/note.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
test('placeholder', () { group('Note.fromJson', () {
expect(true, isTrue); test('parses noteType when present', () {
final json = {
'id': 1,
'title': 'Alice',
'body': '',
'tags': <dynamic>[],
'note_type': 'person',
'created_at': '2024-01-01T00:00:00',
'updated_at': '2024-01-01T00:00:00',
};
final note = Note.fromJson(json);
expect(note.noteType, equals('person'));
});
test('defaults noteType to note when absent', () {
final json = {
'id': 2,
'title': 'My note',
'body': '',
'tags': <dynamic>[],
'created_at': '2024-01-01T00:00:00',
'updated_at': '2024-01-01T00:00:00',
};
final note = Note.fromJson(json);
expect(note.noteType, equals('note'));
});
}); });
} }