Skip to main content

Forms — redesign technical guide

Nextgen components and typed model​

Component / sourceResponsibility
Front src/modules/CompanySettings/Forms/Library store, filters, pagination and form actions.
Front src/modules/ModuleConfig/Campaigns/modules/FormBuilder/Typed form schemas, multilingual mapping, section/question authoring and AI proposals.
Front .../Reviews/modules/FormRender/Question rendering, answer API/store and participant validation UI.
Back src/Http/Api/Routing/V2/review_form.yamlHTTP contracts, permission configuration and list filters.
Back src/Http/Api/Controller/V2/{ReviewFormController,ReviewFormQuestionController}.phpGeneration, publication, duplication, locale management and typed question operations.
Back src/Infrastructure/Persistence/Entity/ReviewForm/Form, Section, typed Question entities and localized content.
Back src/Infrastructure/Persistence/Repository/ReviewForm/FormRepository.phpForm retrieval, campaign-use/read-only queries, section refresh and counts.

The checked frontend families are text, numeric, single answer, multiple answers, scale, list, skills, past/future objectives, development and date. formBuilder.mapper.ts maps UI types to backend types; frontend labels are not API discriminators. Specialized backend families can exist beyond what this checked frontend exposes.

TitleDescriptionTranslationTrait.php and question/section translation entities carry localized content. VisibilityType defines employee = 1, evaluators = 2, all = 3. FormStatus defines draft = 0 and published = 1. Neither visibility nor publication is a substitute for answer-read authorization or campaign assignment.

API contracts​

Paths are relative to /api/v2, checked in src/Http/Api/Routing/V2/review_form.yaml:

Method / pathBehavior and relevant constraint
GET /review-formLibrary list with title, creator, status, dates and read-only filters.
POST /review-formCreate; create-form permission.
GET /review-form/{id}Detail under configured read permissions and repository scope.
PUT /review-form/{id}Full form update; route explicitly directs partial changes to section/question routes. Do not assume PATCH support here.
DELETE /review-form/{id}Delete with delete-form; route declares soft_deletable: false. This is not a reversible preview operation.
POST /review-form/{id}/status/{action}Publish/unpublish action.
POST /review-form/{id}/duplicatePersisted duplicate through FormManager::duplicateForm. Historical answers are not a stated copy contract.
POST /review-form/{id}/translateTranslation workflow.
DELETE /review-form/{id}/locale/{locale}Locale removal; does not translate or migrate answers.
POST /review-form/generateReturns a proposal without saving the form, explicitly stated in routing configuration.
POST /review-form/section/generate-descriptionSection-description proposal without persistence.

ReviewFormQuestionController implements create/show/update/delete/move and description/choice generation; inspect the corresponding route definitions before using those operations.

Example read request with illustrative criteria:

GET /api/v2/review-form?page=1&per_page=10&filters[title][contain]=Annual&filters[status]=1&filters[read_only]=0

CompanySettings/Forms/api/forms.api.ts::getFormsList sends title/creator contains filters, maps draft/published to 0/1, sends optional boolean read_only, maps sorting keys and validates/maps the list response. FormsSearch.vue debounces title/creator input by 300 ms and resets pagination on filter changes. The generic API fallback is 50 per page; the observed UI displayed ten rows per page.

Validation, ownership and read-only derivation​

  • Domain/V2/ReviewForm/Validator/SectionOwnershipValidator.php validates the section owner kind and conditional structure: form and choice-question ownership cannot both be set, conditional sections require valid trigger values, and skill/past-objective/future-objective questions are forbidden in those subsections.
  • ReviewerCustomizationAllowedValidator requires evaluator titles when customization is enabled and visibility is all. Otherwise supplied evaluator titles/descriptions are rejected.
  • OpinionScaleNotShrunkValidator obtains the highest used development-question opinion and rejects too few options. This specifically protects development opinion values, not every numeric scale in the system.
  • ReviewChoiceQuestionExistValidator and typed DTO validation participate in question consistency. Validation is type-specific; changing a discriminator requires compatible options and answer handling.
  • FormRepository::addReadOnlyFilter uses existence of a linked campaign whose status is not draft/not-started. formHasActiveCampaign/findIdsWithActiveCampaign implement the related usage check. Completed/archived campaigns still count; publication alone does not determine read only.

Review the Infrastructure/Persistence/Listener/ReviewForm/{FormListener,QuestionListener}.php call sites when extending writes. A list filter is not itself the complete update-authorization policy.

Optional generation and AIHub boundary​

Infrastructure/Service/ReviewForm/AI/OpenAIFormGenerator.php implements Domain/V2/ReviewForm/Contract/FormGeneratorInterface. It uses the nextgen OpenAI provider abstraction, templates, serialization and shared cache. Checked constants include a 120-second timeout and 3,600-second cache TTL; provider selection belongs to platform configuration, not the customer form UI.

ReviewFormController::generate validates the generation DTO and returns form content. formBuilder.api.ts::generateFormBuilder normalizes the proposal, including temporary question identifiers, scale options and unsupported skill-selection cases, before mapping it into the editor. Generated identifiers/content should not be treated as already-persisted records. Save/publish are separate operations.

No mandatory AIHub route was established: the inspected generator calls nextgen's provider abstraction. The AIHub source search did not establish a questionnaire-generation owner. Do not invent an AIHub dependency for the core form workflow.

Consumption, security and extensions​

Campaigns associate the nextgen form; participant renderers load its typed content and use separate answer endpoints/stores. Question visibility, campaign phase visibility and participant sharing must be considered together. The form's audience enum does not establish all answer-consumer permissions, including People Review Talent Cards.

Keep form titles/descriptions and generated content free of unnecessary employee data. Answers and final comments are HR data and should not be copied into error logs or generation prompts by default. Translation, deletion and duplication are persistent actions with their own rights.

For a new question family, trace frontend schema → mapper → builder → backend DTO/provider/entity/validation → participant renderer → typed answer flow and outputs. Updating a picker alone is insufficient. For read-only/reporting changes, preserve the distinction between publication, campaign usage and participant answer state.

Failure modes and runtime dependencies​

FailureInvestigation path
List missing a formTenant/read scope, locale filtering, status, read-only criterion and title/creator query.
Full update rejectedMethod, resource scope, conditional section structure, type-specific DTOs and existing-use restrictions.
Generation failurePermission, DTO validity, provider/configuration, timeout and response deserialization.
Translation/content mismatchSelected content locale, available translations and mapper fallback; UI locale is separate.
Invalid participant answerTyped renderer/rules and server validation; form publication is not answer validity.

Core authoring requires the nextgen API/persistence and any configured referentials. AI assistance additionally needs the provider and cache. Worker/PDF dependencies belong to interview execution/output and are documented in Interviews technical. No deployed service health or migration jobs were verified.

Evidence and limitations​

Documented in Confluence: Interview playbook, v11, 6 September 2023; Standardizing the interview data model, v21, 12 February 2025; SMR interviews/reviews models, v1, 13 March 2026. Documentary legacy question/export examples are not nextgen API specifications. The supplied FAQ folder and PS general-methodology/onboarding entry points were checked without treating them as form defaults.

Observed in application: the nextgen form authoring flow supports a saved bilingual form with sections, typed questions, preview and publication; see configuration. The form was not assigned to a campaign, so respondent completion and answer validation are not established. Not verified: deployed revisions, complete cross-generation conversion, every question family, all translation/provider failures, complete permissions parity and the full downstream PDF/answer-sharing matrix. No screenshot assets are embedded in this technical guide.

Functional-guide evidence​

These implementation and product references support the functional guide. Local source behavior does not establish which revision or optional features are deployed. Application observations remain distinct from code and documentary evidence.

  • Observed in application: smartmobility.io, 16 October 2026, EN/FR legacy and nextgen libraries, EN/FR nextgen blank authoring dialogs, and personal nextgen interview entry/pre-start screen. No populated answer form was changed or captured.
  • Verified in code — legacy: src/Company/AssessmentBundle/Controller/DefaultController.php; src/Company/AssessmentBundle/Resources/views/Default/list.html.twig.
  • Verified in code — nextgen front: src/modules/CompanySettings/Forms/components/FormsSearch.vue, api/forms.api.ts; src/modules/ModuleConfig/Campaigns/modules/FormBuilder/domain/formBuilder.frontend.schemas.ts.
  • Verified in code — nextgen back: src/Infrastructure/Persistence/Repository/ReviewForm/FormRepository.php (addReadOnlyFilter, formHasActiveCampaign); src/Domain/V2/Questionnaire/Question/Enum/VisibilityType.php.
  • Documented in Confluence: Playbook – Interviews, v11, 6 September 2023; SMR interviews/reviews models, v1, 13 March 2026. The latter explains the naming difference; it is not proof of automatic migration.
  • Not verified: filled employee/evaluator forms, all expanded authoring controls in both locales, bulk actions and complete filter combinations. No legacy form-conversion process was established.

Journey verification — 26 October 2026​

Observed in application: a legacy draft retained its title, description, Brouillon status and Support entretien type after reload. Its open question retained the required flag in the reopened editor. A separate nextgen example was saved in French and English, previewed and published. Neither example was assigned to a campaign; no respondent answer or notification was generated. A legacy Tests type could not be confirmed as saved.

Last updated on 3 November 2026