Skip to content

Commit 29200db

Browse files
committed
refactor: remove removePointFromNote feature and associated logic
- Deleted the removePointFromNote endpoint and its implementation in AiController. - Removed related methods and classes, including NoteDetailsRephrase and associated AI tools. - Updated OpenAPI documentation to reflect the removal of the feature. - Cleaned up generated TypeScript types and SDK to eliminate references to the removed feature. Co-authored-by: terry <terry@odd-e.com>
1 parent 9461f2f commit 29200db

File tree

11 files changed

+12
-229
lines changed

11 files changed

+12
-229
lines changed

backend/src/main/java/com/odde/doughnut/controllers/AiController.java

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
import com.odde.doughnut.controllers.dto.*;
55
import com.odde.doughnut.entities.Note;
66
import com.odde.doughnut.exceptions.UnexpectedNoAccessRightException;
7-
import com.odde.doughnut.factoryServices.EntityPersister;
87
import com.odde.doughnut.services.AuthorizationService;
98
import com.odde.doughnut.services.NotebookAssistantForNoteServiceFactory;
109
import com.odde.doughnut.services.ai.OtherAiServices;
11-
import com.odde.doughnut.testability.TestabilitySettings;
1210
import io.swagger.v3.oas.annotations.media.Schema;
1311
import java.util.List;
1412
import org.springframework.beans.factory.annotation.Autowired;
@@ -25,21 +23,15 @@ public class AiController {
2523
private final OtherAiServices otherAiServices;
2624
private final NotebookAssistantForNoteServiceFactory notebookAssistantForNoteServiceFactory;
2725
private final AuthorizationService authorizationService;
28-
private final EntityPersister entityPersister;
29-
private final TestabilitySettings testabilitySettings;
3026

3127
@Autowired
3228
public AiController(
3329
NotebookAssistantForNoteServiceFactory notebookAssistantForNoteServiceFactory,
3430
OtherAiServices otherAiServices,
35-
AuthorizationService authorizationService,
36-
EntityPersister entityPersister,
37-
TestabilitySettings testabilitySettings) {
31+
AuthorizationService authorizationService) {
3832
this.notebookAssistantForNoteServiceFactory = notebookAssistantForNoteServiceFactory;
3933
this.otherAiServices = otherAiServices;
4034
this.authorizationService = authorizationService;
41-
this.entityPersister = entityPersister;
42-
this.testabilitySettings = testabilitySettings;
4335
}
4436

4537
@GetMapping("/dummy")
@@ -87,24 +79,4 @@ public UnderstandingChecklistDTO generateUnderstandingChecklist(
8779
.generateUnderstandingChecklist();
8880
return new UnderstandingChecklistDTO(points);
8981
}
90-
91-
@PostMapping("/remove-point-from-note/{note}")
92-
@Transactional
93-
public NoteRealm removePointFromNote(
94-
@PathVariable(value = "note") @Schema(type = "integer") Note note,
95-
@RequestBody String pointToRemove)
96-
throws UnexpectedNoAccessRightException, JsonProcessingException {
97-
authorizationService.assertAuthorization(note);
98-
99-
String rephrasedDetails =
100-
notebookAssistantForNoteServiceFactory
101-
.createNoteAutomationService(note)
102-
.removePointFromNote(pointToRemove);
103-
104-
note.setDetails(rephrasedDetails);
105-
note.setUpdatedAt(testabilitySettings.getCurrentUTCTimestamp());
106-
entityPersister.save(note);
107-
108-
return note.toNoteRealm(authorizationService.getCurrentUser());
109-
}
11082
}

backend/src/main/java/com/odde/doughnut/services/NoteAutomationService.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,4 @@ public String suggestTitle() throws JsonProcessingException {
1818
public java.util.List<String> generateUnderstandingChecklist() throws JsonProcessingException {
1919
return chatCompletionNoteAutomationService.generateUnderstandingChecklist();
2020
}
21-
22-
public String removePointFromNote(String pointToRemove) throws JsonProcessingException {
23-
return chatCompletionNoteAutomationService.removePointFromNote(pointToRemove);
24-
}
2521
}

backend/src/main/java/com/odde/doughnut/services/ai/ChatCompletionNoteAutomationService.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,6 @@ public List<String> generateUnderstandingChecklist() throws JsonProcessingExcept
3939
List.of());
4040
}
4141

42-
public String removePointFromNote(String pointToRemove) throws JsonProcessingException {
43-
return executeWithTool(
44-
AiToolFactory.removePointFromNoteAiTool(pointToRemove),
45-
NoteDetailsRephrase.class,
46-
NoteDetailsRephrase::getDetails,
47-
"");
48-
}
49-
5042
private <T, R> R executeWithTool(
5143
InstructionAndSchema tool, Class<T> resultClass, Function<T, R> extractor, R defaultValue)
5244
throws JsonProcessingException {

backend/src/main/java/com/odde/doughnut/services/ai/NoteDetailsRephrase.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

backend/src/main/java/com/odde/doughnut/services/ai/tools/AiToolFactory.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,6 @@ public static InstructionAndSchema generateUnderstandingChecklistAiTool() {
160160
generateUnderstandingChecklist());
161161
}
162162

163-
public static InstructionAndSchema removePointFromNoteAiTool(String pointToRemove) {
164-
return new InstructionAndSchema(
165-
"Please rephrase the note details to remove the following point that the user considers unrelated to the note. Preserve the overall meaning and flow of the remaining content. The point to remove is: \""
166-
+ pointToRemove
167-
+ "\"",
168-
removePointFromNote());
169-
}
170-
171-
public static Class<?> removePointFromNote() {
172-
return NoteDetailsRephrase.class;
173-
}
174-
175163
public static List<Class<?>> getAllAssistantTools() {
176164
return List.of(
177165
completeNoteDetails(),

backend/src/test/java/com/odde/doughnut/controllers/AiControllerTest.java

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import static org.mockito.Mockito.*;
88

99
import com.fasterxml.jackson.core.JsonProcessingException;
10-
import com.odde.doughnut.controllers.dto.NoteRealm;
1110
import com.odde.doughnut.controllers.dto.SuggestedTitleDTO;
1211
import com.odde.doughnut.controllers.dto.UnderstandingChecklistDTO;
1312
import com.odde.doughnut.entities.*;
@@ -283,92 +282,4 @@ void shouldRequireUserToBeLoggedIn() {
283282
ResponseStatusException.class, () -> controller.generateUnderstandingChecklist(testNote));
284283
}
285284
}
286-
287-
@Nested
288-
class RemovePointFromNote {
289-
Note testNote;
290-
OpenAIChatCompletionMock openAIChatCompletionMock;
291-
292-
@BeforeEach
293-
void setup() {
294-
testNote = makeMe.aNote().creatorAndOwner(currentUser.getUser()).please();
295-
openAIChatCompletionMock = new OpenAIChatCompletionMock(officialClient);
296-
}
297-
298-
@Test
299-
void shouldReturnRephrasedNoteDetails()
300-
throws UnexpectedNoAccessRightException, JsonProcessingException {
301-
testNote.setDetails(
302-
"English serves as the world's most widespread lingua franca, vital for global communication.");
303-
String pointToRemove = "English is the world's most widespread lingua franca";
304-
String expectedRephrasedDetails =
305-
"English plays a crucial role in global communication, enabling people from different cultures to understand one another.";
306-
307-
// Mock AI response with rephrased content
308-
com.odde.doughnut.services.ai.NoteDetailsRephrase rephrasedNote =
309-
new com.odde.doughnut.services.ai.NoteDetailsRephrase();
310-
rephrasedNote.setDetails(expectedRephrasedDetails);
311-
openAIChatCompletionMock.mockChatCompletionAndReturnJsonSchema(rephrasedNote);
312-
313-
NoteRealm result = controller.removePointFromNote(testNote, pointToRemove);
314-
315-
assertThat(result.getNote().getDetails()).isEqualTo(expectedRephrasedDetails);
316-
}
317-
318-
@Test
319-
void shouldCallChatCompletionWithRightMessage()
320-
throws UnexpectedNoAccessRightException, JsonProcessingException {
321-
testNote.setDetails("Some note details about English language.");
322-
String pointToRemove = "English is the world's most widespread lingua franca";
323-
324-
com.odde.doughnut.services.ai.NoteDetailsRephrase rephrasedNote =
325-
new com.odde.doughnut.services.ai.NoteDetailsRephrase();
326-
rephrasedNote.setDetails("Rephrased details without the point.");
327-
openAIChatCompletionMock.mockChatCompletionAndReturnJsonSchema(rephrasedNote);
328-
329-
controller.removePointFromNote(testNote, pointToRemove);
330-
331-
ArgumentCaptor<com.openai.models.chat.completions.ChatCompletionCreateParams> paramsCaptor =
332-
ArgumentCaptor.forClass(
333-
com.openai.models.chat.completions.ChatCompletionCreateParams.class);
334-
verify(openAIChatCompletionMock.completionService()).create(paramsCaptor.capture());
335-
com.openai.models.chat.completions.ChatCompletionCreateParams params =
336-
paramsCaptor.getValue();
337-
338-
boolean hasPointToRemove =
339-
params.messages().stream()
340-
.map(Object::toString)
341-
.anyMatch(msg -> msg.contains(pointToRemove));
342-
MatcherAssert.assertThat(
343-
"A message should contain the point to remove", hasPointToRemove, is(true));
344-
345-
boolean hasNoteDetails =
346-
params.messages().stream()
347-
.map(Object::toString)
348-
.anyMatch(msg -> msg.contains("Some note details about English language"));
349-
MatcherAssert.assertThat(
350-
"A message should contain the original note details", hasNoteDetails, is(true));
351-
352-
MatcherAssert.assertThat(
353-
"Should use responseFormat instead of tools",
354-
params.responseFormat().isPresent(),
355-
is(true));
356-
}
357-
358-
@Test
359-
void shouldRequireUserToBeLoggedIn() {
360-
currentUser.setUser(null);
361-
assertThrows(
362-
ResponseStatusException.class,
363-
() -> controller.removePointFromNote(testNote, "some point"));
364-
}
365-
366-
@Test
367-
void shouldRequireAccessToNote() {
368-
Note otherUserNote = makeMe.aNote().please();
369-
assertThrows(
370-
UnexpectedNoAccessRightException.class,
371-
() -> controller.removePointFromNote(otherUserNote, "some point"));
372-
}
373-
}
374285
}

generated/backend/index.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

generated/backend/sdk.gen.ts

Lines changed: 1 addition & 12 deletions
Large diffs are not rendered by default.

generated/backend/types.gen.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2917,33 +2917,6 @@ export type SuggestTitleResponses = {
29172917

29182918
export type SuggestTitleResponse = SuggestTitleResponses[keyof SuggestTitleResponses];
29192919

2920-
export type RemovePointFromNoteData = {
2921-
body: string;
2922-
path: {
2923-
note: number;
2924-
};
2925-
query?: never;
2926-
url: '/api/ai/remove-point-from-note/{note}';
2927-
};
2928-
2929-
export type RemovePointFromNoteErrors = {
2930-
/**
2931-
* Internal Server Error
2932-
*/
2933-
500: string;
2934-
};
2935-
2936-
export type RemovePointFromNoteError = RemovePointFromNoteErrors[keyof RemovePointFromNoteErrors];
2937-
2938-
export type RemovePointFromNoteResponses = {
2939-
/**
2940-
* OK
2941-
*/
2942-
200: NoteRealm;
2943-
};
2944-
2945-
export type RemovePointFromNoteResponse = RemovePointFromNoteResponses[keyof RemovePointFromNoteResponses];
2946-
29472920
export type GenerateUnderstandingChecklistData = {
29482921
body?: never;
29492922
path: {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Remove the "remove point from note" AI feature from backend.
2+
3+
Scope:
4+
- Delete the `/api/ai/remove-point-from-note/{note}` endpoint and its service/tool chain.
5+
- Remove the backend unit tests that exercised this endpoint.
6+
- Regenerate OpenAPI and TypeScript client code after the removal.
7+
8+
Out of scope:
9+
- `ignoredChecklistTopics` in the note assimilation payload stays for now.

0 commit comments

Comments
 (0)