feat(FN-1445): add project-scoping and fallback handling for AI routes and missions

- Add projectId parameter to refineText API and TaskForm for proper scoping
- Update mission routes to require projectId and add regression tests
- Add mission interview fallback to mission-level context when target not found
- Add AI refine route scoping tests for project isolation
- Update component tests to expect projectId argument
- Update prompt-keys test counts for new system prompts
This commit is contained in:
gsxdsm
2026-04-11 15:23:03 -07:00
parent 18f242b2bc
commit b76a1011b6
16 changed files with 828 additions and 35 deletions

View File

@@ -919,7 +919,7 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
setIsRefineMenuOpen(false);
setIsRefining(true);
try {
const refined = await refineText(trimmed, type);
const refined = await refineText(trimmed, type, projectId);
setDescription(refined);
addToast("Description refined with AI", "success");
// Auto-resize textarea after content update
@@ -933,7 +933,7 @@ export function QuickEntryBox({ onCreate, addToast, tasks = [], availableModels,
} finally {
setIsRefining(false);
}
}, [description, isRefining, addToast]);
}, [description, isRefining, addToast, projectId]);
const truncate = (s: string, len: number) =>
s.length > len ? s.slice(0, len) + "…" : s;

View File

@@ -418,7 +418,7 @@ export function TaskForm({
setIsRefining(true);
try {
const refined = await refineText(trimmed, type);
const refined = await refineText(trimmed, type, projectId);
onDescriptionChange(refined);
setIsRefineMenuOpen(false);
addToast("Description refined with AI", "success");
@@ -432,7 +432,7 @@ export function TaskForm({
} finally {
setIsRefining(false);
}
}, [description, isRefining, addToast, onDescriptionChange]);
}, [description, isRefining, addToast, onDescriptionChange, projectId]);
const handleToggleFavorite = useCallback(async (provider: string) => {
const currentFavorites = favoriteProviders;

View File

@@ -1665,7 +1665,7 @@ describe("QuickEntryBox", () => {
fireEvent.click(screen.getByTestId("refine-clarify"));
await waitFor(() => {
expect(refineText).toHaveBeenCalledWith("Original text", "clarify");
expect(refineText).toHaveBeenCalledWith("Original text", "clarify", TEST_PROJECT_ID);
});
// Textarea should be updated

View File

@@ -501,7 +501,8 @@ describe("TaskForm", () => {
fireEvent.click(screen.getByTestId("refine-clarify"));
await waitFor(() => {
expect(refineText).toHaveBeenCalledWith("Some text to refine", "clarify");
// projectId is undefined in this test context
expect(refineText).toHaveBeenCalledWith("Some text to refine", "clarify", undefined);
expect(onDescriptionChange).toHaveBeenCalledWith("Refined text");
});
});