# Feature Specification: Feature 1 – Survey Management (Admin)

> **Terminology note:** This specification uses terms from the semantic data model (`Survey`, `Question`, `AnswerOption`, `QuestionTypeEnum`). The model is a separate artifact and is not copied here.

## Summary

Survey administrators create, configure, retrieve, and delete online surveys through the REST API of a backend. This increment covers the administrative lifecycle: survey metadata, ordered questions with type-specific answer options, retrieval of the complete structure, and cascading deletes. Collecting answers from respondents is out of scope.

## Goals

- Create a survey with a title and a creator, and with optional description, start date, and end date.
- Add ordered questions of the types defined in the data model (rating, single choice, multiple choice, open text).
- Create answer options with a display text and an internal value for every question type that requires them.
- Retrieve a survey with questions in ascending `OrderNumber` and each question's answer options in the order submitted when the question was created.
- Delete a single question, including its answer options, without affecting other questions of the same survey.
- Delete a survey, including all of its questions and answer options.

## Non-Goals

- No respondent-facing UI and no public survey-taking API.
- No authentication or authorization model in this increment; the caller is treated as an administrator.
- No publishing workflow, no draft/published status beyond the optional start and end dates on the survey.
- No persistence of `SurveyResponse`, `ResponseAnswer`, or `Respondent`. Those entities exist in the data model for later features.
- `IsOtherOption` is not supported in this increment. A free-text "other" option on Open questions, as allowed by the data model, is deferred.
- No implementation sequence, layering, or choice of test framework. That belongs in the implementation plan.

## Actors and Journeys

**Actor:** Survey administrator, calling the administrative API.

### Journey 1: Create a usable questionnaire

1. The administrator creates a survey with title `Customer Satisfaction 2026` and creator `QA Team`. Description and dates are omitted.
2. The API returns a generated survey identifier.
3. The administrator adds three questions in order:
   - order 1, rating, mandatory, with four answer options whose internal values are `1` to `4`;
   - order 2, single choice, mandatory, with three answer options;
   - order 3, open text, optional, without answer options.
4. The administrator retrieves the survey by identifier and sees the metadata, the three questions in order, and each of the first two questions' options in their original submission order.

### Journey 2: Remove a question, then discard the survey

1. The administrator deletes question 2 of the survey from journey 1.
2. The administrator retrieves the survey and now sees questions 1 and 3 only; their order numbers remain `1` and `3`.
3. The administrator deletes the survey.
4. The administrator retrieves the survey by the same identifier and receives "Not Found".

## Domain Rules

The data types, cardinalities, and field constraints of `Survey`, `Question`, and `AnswerOption` are defined in the semantic data model. This specification describes their effects at the API boundary and adds feature-specific behavioral rules:

- A survey is created even when description, start date, and end date are omitted; those fields are then empty.
- `EndDate` must not precede `StartDate` when both are present (the same constraint as in the data model; the API must reject the write).
- `OrderNumber` is unique per survey in the data model. This specification adds that the API does not renumber remaining questions after a delete.
- Each question's answer options are returned in their original submission order. The data model does not define option ordering; preserving this order is an additional behavioral requirement of this feature. Its storage representation is an implementation decision.
- Rating, single choice, and multiple choice questions require at least two answer options.
- Deleting a question deletes its answer options. Deleting a survey deletes its questions and their options.

## Error Cases

The following error cases use Given-When-Then scenarios to make verification unambiguous. Validation errors name the affected field or conflict. The API must also enforce the referenced rules from the semantic data model on write.

1. **Empty title**

   - Given a create-survey request
   - When title is missing, empty, or whitespace only
   - Then the request is rejected with a validation error naming `Title`

2. **Inverted dates**

   - Given a create-survey request with both dates set
   - When `EndDate` is before `StartDate`
   - Then the request is rejected with a validation error naming the date range

3. **Unknown survey**

   - Given no survey with the supplied identifier
   - When the administrator adds a question, retrieves the survey, or deletes it
   - Then the request is rejected as not found

4. **Duplicate order**

   - Given a survey that already has a question with `OrderNumber` 2
   - When another question with `OrderNumber` 2 is added
   - Then the request is rejected with a validation error naming `OrderNumber`

5. **Too few options**

   - Given a rating, single-choice, or multiple-choice question
   - When fewer than two answer options are submitted
   - Then the request is rejected with a validation error naming the answer options

6. **Duplicate internal values**

   - Given a question with answer options
   - When two options share the same internal value
   - Then the request is rejected with a validation error naming the conflicting values

7. **Options on a free-text question**

   - Given a free-text question
   - When answer options are submitted
   - Then the request is rejected with a validation error naming the answer options

8. **IsOtherOption set**

   - Given any question
   - When an option sets `IsOtherOption` to true
   - Then the request is rejected with a validation error naming the answer options, because the free-text option is out of this increment

9. **Delete an unknown question**

   - Given no question with the supplied identifier, including after a previous successful delete
   - When the administrator deletes that question
   - Then the request is rejected as not found and the stored survey remains unchanged

10. **Rejected addition leaves no partial changes**
    - Given an existing survey and an add-question request containing an invalid answer option
    - When the API rejects the request during validation
    - Then neither the new question nor any of its options are persisted; the existing survey remains unchanged

## Acceptance Criteria

- Journey 1 can be executed against the API and returns questions in ascending `OrderNumber`, with each question's answer options in their original submission order.
- Journey 2 returns the unchanged remaining questions after a question is deleted, and "Not Found" when the survey is retrieved again after deletion.
- All error cases described above return their specified error responses through the API. Rejected writes do not change the retrievable survey structure.
- Successful creates return the generated identifier of the survey or question.
- Error responses use a consistent format and name the field or conflict that caused the rejection.
- The data accepted and returned by the API matches the semantic data model for names, types, and constraints of `Survey`, `Question`, and `AnswerOption`. The restrictions in the non-goals are enforced.

## Verification

Each Given-When-Then scenario is covered by at least one automated API test. Additional persistence tests verify that cascading deletes leave no residual records and that rejected writes do not persist partial data. The implementation plan maps these checks to the implementation steps.

## References

The following paths refer to the example project:

- Semantic data model: `/docs/semantic_data_model.md`
- Architecture: `/docs/architecture.md`
