feat(question): MCQ options authoring editor (Phase 2 domain foundation)

Backend now supports MCQ options + a separate answer-key table
(PUT /questions/:id/options). Frontend side of that, authoring only —
no candidate exam-taking UI.

- Question type gains options?: QuestionOption[] (no correctness field —
  the API never returns one, matching the backend's split-table design)
- New question-api hooks: getQuestionWithOptions, setQuestionOptions
- New QuestionOptionsEditor component (separate file, not inlined into
  QuestionPage) — add/remove/reorder options, mark correct, bilingual text
- Wired into the question edit form, shown only for an existing CHOICE
  question (options attach to an id, matching the backend's replace
  endpoint)
- en/am i18n strings for the new editor

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
mihretue
2026-08-13 19:28:03 +00:00
parent d98d6a71fe
commit 14b5bb83f9
6 changed files with 214 additions and 0 deletions

View File

@@ -1,10 +1,12 @@
import { baseApi } from '@ema-platform/api';
import type {
Question,
QuestionOption,
ListResponse,
CreateQuestionPayload,
UpdateQuestionPayload,
ReviewQuestionPayload,
SetQuestionOptionsPayload,
} from '../types/question';
const questionApi = baseApi.injectEndpoints({
@@ -17,6 +19,11 @@ const questionApi = baseApi.injectEndpoints({
query: (id) => `/questions/${id}`,
providesTags: ['Api'],
}),
/** Same question, with `options` populated — the MCQ authoring editor. */
getQuestionWithOptions: builder.query<Question, string>({
query: (id) => `/questions/${id}?i=options`,
providesTags: ['Api'],
}),
createQuestion: builder.mutation<Question, CreateQuestionPayload>({
query: (body) => ({ url: '/questions', method: 'POST', body }),
invalidatesTags: ['Api'],
@@ -47,6 +54,15 @@ const questionApi = baseApi.injectEndpoints({
}),
invalidatesTags: ['Api'],
}),
/** Full replace of a CHOICE question's options + correct-answer set (Phase 2). */
setQuestionOptions: builder.mutation<QuestionOption[], SetQuestionOptionsPayload>({
query: ({ id, ...body }) => ({
url: `/questions/${id}/options`,
method: 'PUT',
body,
}),
invalidatesTags: ['Api'],
}),
}),
overrideExisting: false,
});
@@ -54,9 +70,11 @@ const questionApi = baseApi.injectEndpoints({
export const {
useGetQuestionsQuery,
useGetQuestionQuery,
useGetQuestionWithOptionsQuery,
useCreateQuestionMutation,
useUpdateQuestionMutation,
useDeleteQuestionMutation,
useSubmitQuestionMutation,
useReviewQuestionMutation,
useSetQuestionOptionsMutation,
} = questionApi;