Skip to main content

Interviews — redesign technical guide

Nextgen data model and lifecycle​

ResourceSourceResponsibility
Campaignsrc/Infrastructure/Persistence/Entity/ReviewCampaign/Campaign.phpForm association, campaign dates, status and related configuration/population.
Campaign configuration.../ReviewCampaign/{CampaignConfigurationKey,CampaignConfigurationValue}.phpPersisted keys and campaign values; keys are repository-provided, not fully hard-coded defaults.
Reviewsrc/Infrastructure/Persistence/Entity/Review/Review.phpEmployee interview aggregate and overall progression.
UserReviewsrc/Infrastructure/Persistence/Entity/Review/UserReview.phpParticipant-specific contribution, type, workflow and sharing/signature state.
Typed answer entitiessrc/Infrastructure/Persistence/Entity/Review/Answer/Scalar, choice and specialized objective/development contributions.

Campaign states are draft, not_started, in_progress, done, archived (Domain/V2/ReviewCampaign/Enum/CampaignStatus.php). Participant states are not_started, in_progress, standby, in_interview, done, aborted (Domain/V2/Review/Enum/UserReviewStatus.php). These are distinct state machines: do not infer participant signatures from campaign completion.

UserReviewManager::start checks the current participant, expected state and unfinished campaign. manuallyFinishPreparation checks ownership, in-progress state, campaign availability and answer validation. UserReviewWorkflowManager applies transitions and wraps blocked transitions as workflow exceptions. It also supports expiry, abort and reopening; a signed review cannot be partially reopened through the checked guard.

Signature and submission contract​

UserReviewSignatureManager::signOrSubmit requires aggregate FINALIZATION, participant IN_INTERVIEW, current-user ownership, a campaign not done/archived and no previous signature/refusal timestamp. Evaluators cannot refuse; employee refusal requires campaign permission. When signatures are not required, accepting submits with isSigned = null while recording the completion timestamp. This explains why a submission timestamp is not proof of an affirmative signature.

The manager updates the aggregate and requests both PDF variants. Inspect its error handling and output status when diagnosing PDF failures; do not assume missing output means answers or signatures were never persisted.

API surface​

Paths below are relative to /api/v2; method/path declarations are checked in the routing YAML. They are implementation contracts, not instructions to execute changes on production.

Method and routeContract / caller
GET /review-campaignCampaign list. Supports title contains, strict status, dates, form ID and current-user-stat filters.
POST /review-campaignCampaign creation; create-campaign route permission.
PUT/PATCH /review-campaign/{id}Update; update-campaign permission and resource lookup.
GET /review/{id}Interview aggregate used by review.api.ts::getReview.
POST /user-review/{id}/startParticipant preparation start.
POST /user-review/{id}/finish-preparationValidates and finishes preparation; invalid mandatory answers produce a bad-request response.
POST /user-review/{userReviewId}/validation204 when valid; 400 when invalid. Missing-answer detail is documented for the affected participant, with standard failure for others.
POST /user-review/{id}/show-answers/{action}Reveal/hide sharing operation.
PUT /user-review/{id}/final-commentValidated comment DTO, separate from answers.
POST /user-review/{id}/sign/{action}Accept/refuse under signature-manager conditions.
POST /user-review/{id}/submit/{action}Submission flow under campaign completion rules.
POST /user-review/{id}/delegate/{evaluatorId}Evaluator reassignment; delegate-user-review route permission.
POST/DELETE /review/{id}/second-evaluator/{evaluatorId}Additional-evaluator operations; manager checks duplicate active assignments and the two-evaluator limit.
GET /review/{id}/pdf/{action}Output view/preview according to configured action.
POST /review/{id}/reopenReopening under aggregate/participant rules.

Example read request, using an illustrative title rather than tenant data:

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

campaign.api.ts::getCampaignList constructs and validates/maps the response. Its generic pagination fallback is 50, while the checked campaign store initializes 10. The store starts with creation-date descending; the API's own fallback sort is end-date descending. Do not describe those as one universal default.

The API interface declares evaluatorId, but the inspected builder does not serialize it. The My reviewees control therefore needs end-to-end verification before its behavior is promised. No data access rule should depend only on that UI filter.

Permissions and answer visibility​

Route permissions, resource-query scope, campaign ownership and participant ownership are separate layers. Many self-service participant routes declare ROLE_USER, then service ownership/state checks limit writes; that route declaration is not blanket write access to arbitrary participant IDs.

CampaignAccessChecker::checkAccess accepts a super administrator, creator or owner for callers invoking it. It is not proof that every read route uses that restriction. Form question audience, phase cross-visibility, advanced employee-answer visibility and participant reveal/hide state are also distinct. Full precedence across all question types and any People Review Talent Card consumer was not verified here.

Do not log answer text, final comments, signature metadata or personal identifiers to diagnose a general state-machine issue. Report status, operation and authorized record context through the application's normal support process.

Runtime dependencies, failures and extension points​

  • src/Command/ReviewCampaign/CampaignWorkflowCommand.php and src/Command/Review/UserReviewWorkflowCommand.php provide lifecycle execution; deployment scheduling was not verified.
  • config/message_broker/review_finished.yaml and review_campaign_regenerate_pdf.yaml declare asynchronous integration configuration. Configuration files do not establish live consumer health.
  • Related skills, goals, training catalog and optional generated summaries have their own data/services. No mandatory AIHub hop was established for the core interview workflow.
  • Extend question behavior through the form DTO/provider/renderer/answer paths together. Update mapping and validation when changing a contract; use the separate form guide for type details.
  • Distinguish resource/permission failures, invalid payloads, missing mandatory answers, blocked transitions, duplicate evaluators and output failures. The client catches some list parsing failures and retries mapping; successful rendering does not prove the strict response schema passed.

Legacy and nextgen coexistence​

Legacy shell app/config/neobrain/company/definitions.yml gates smr_campaigns through hybrid activation and its access role. Personal navigation can link to /space/personal/review/{id}. Navigation integration does not establish common answer tables or automatic migration.

Documented in Confluence: SMR interviews/reviews models, v1, 13 March 2026, documents different legacy/redesign data sources. Its example repeats “SML” for a nextgen table: treat that wording as a documentary inconsistency, not a schema definition. Standardizing the interview data model, v21, 12 February 2025, explains legacy reporting structures; Interview playbook, v11, 6 September 2023, describes legacy configuration intent.

Legacy and nextgen campaigns use separate resource and answer models. No automatic legacy-to-nextgen migration is defined by these workflows. The HTTP and persistence contracts in this guide describe internal implementation paths, not a public integration API.

Last updated on 3 November 2026