People Review — redesign technical guide
Nextgen implementation
Paths are relative to smartmobility-nextgen-back, except where explicitly marked frontend/legacy.
Components and data model
| Source | Responsibility |
|---|---|
Frontend src/modules/ModuleConfig/PeopleReview/ | Campaign list, wizard, assessment/committee views, filter serialization, API callers. |
Frontend src/router/private-routes.ts | Authenticated People Review entry points and fullscreen assessment route. |
src/Http/Api/Routing/V2/people_review*.yaml | Operation permissions, routes, repository methods and nested-resource bindings. |
src/Infrastructure/Persistence/Entity/PeopleReviewCampaign/PeopleReviewCampaign.php | Campaign configuration and relationships, including owners, reviewed users, committee and Talent Card selections. |
src/Infrastructure/Persistence/Entity/PeopleReview/PeopleReview.php | One employee/evaluator assessment record, statuses, calibration/answer relationships. |
src/Infrastructure/Service/PeopleReview/PeopleReviewValidationService.php | Actor and campaign-phase checks for answer operations and review writes. |
src/Infrastructure/Persistence/Service/PeopleReview/PeopleReviewReviewCampaignInformationProvider.php | Configured source interview questions and employee-specific answer slots. |
Company answers support scale, weighted and performance; custom-assessment answers support text and scale. Custom questions belong to one People Review campaign. Company-question validation uses findQuestionForCampaign; custom-question validation binds question ID to the same campaign. A valid question ID in another campaign is not sufficient.
PeopleReviewCampaignTalentCardQuestion binds a People Review campaign to a Review Campaign question and type. It is separate from both the campaign's custom questions and the legacy Assessment template. Form reuse/migration across these structures was not established.
Access algorithm: permission, campaign, employee, operation
- The route declares an operation permission, evaluated by the resource controller infrastructure.
- Campaign retrieval uses
PeopleReviewCampaignAuthorizationTrait::applyAccessFilter: privileged branch or owner/creator, plus evaluator/collective-reviewer branches when full access is enabled. - The review list/matrix/export repository chooses the employee scope appropriate to that operation.
- Individual detail uses
PeopleReviewAuthorizationTrait:pr.evaluator = currentUser OR cr.user = currentUser. - Answer operations additionally validate supported type, question membership, and read/write actor/phase eligibility.
The operation-specific differences are intentional documentation boundaries; a single “admin sees everything” rule would be inaccurate.
| Surface | Population or actor check verified in code |
|---|---|
| Campaign read/list | Owner, creator, assigned evaluator or committee membership, with privileged campaign bypass. |
| Campaign review list | PeopleReviewRepository::applyCampaignReviewScope permits full campaign for owner/creator/privileged or committee; others restricted to evaluator. |
| Matrix-cell and matrix top-review scope | Calls the same scope helper with withOwner: false; committee expands scope, other actors are limited to evaluator assignments. |
| Individual detail and source interview information | findPeopleReviewForAuthorizedUser applies evaluator OR committee; ownership/creator status alone does not satisfy it. |
| Calibration read | PeopleReviewCalibrationRepository::findCalibrationForAuthorizedUser uses the People Review authorization trait. |
| Answer read | validateAvailableToRead: evaluator or committee; no phase restriction in this validator. |
| Answer/comment/flag/submit write | validateAvailableToWrite: evaluator in phase 1; committee in standby or phase 2; rejected otherwise. Workflow transition validity is an additional concern. |
| Export trigger | Export permission plus PeopleReviewCampaignAccessChecker: owner/creator or privileged. Committee alone is insufficient. Batch query applies campaign scope and optional My reviewees restriction. |
| Status transition | Update permission plus campaign access checker; workflow guards still apply. |
A permission-scoped visibility group and field transformation can further affect returned related data. The table describes inspected campaign/review predicates, not proof that every profile attribute is returned unconditionally. A reviewed employee alone does not match an evaluator/committee predicate; a job title alone is also insufficient.
Request and data flow example
For a user opening employee A's review, the frontend calls the individual endpoint with a review ID, not an arbitrary employee ID. The permission check precedes authorized repository retrieval. Answer calls then bind that review, the configured question and its type. The actor must be the assigned evaluator or a campaign committee member for reads. For writes, campaign status selects evaluator or committee eligibility. The controller dispatches to the type-specific resource implementation.
API prefix /api/v2 is verified in frontend api/peopleReview.api.ts; route fragments below are verified in backend YAML.
| Method and path | Contract / relevant permission |
|---|---|
GET /api/v2/people-review-campaign | Paginated campaign list; read-people-review-campaign. |
POST /api/v2/people-review-campaign | Campaign creation; create-people-review-campaign. |
GET /api/v2/people-review-campaign/{id}/review | Scoped review list; campaign read permission. |
GET /api/v2/people-review/{id} | Authorized review detail; read-people-review. |
POST /api/v2/people-review/{id}/delegate/{evaluatorId} | Evaluator reassignment; delegate-people-review; method-specific policy must be checked independently of answer-write rules. |
POST /api/v2/people-review/{id}/comment | Phase-aware comment write; update-people-review. |
POST /api/v2/people-review/{id}/flag | Phase-aware discussion flag toggle; update-people-review. |
PUT /api/v2/people-review/{id}/submit | Evaluator submission or committee calibration submission; update-people-review, actor/phase and workflow checks. |
GET /api/v2/people-review/{id}/calibration | Authorized calibration retrieval; read-people-review. |
GET /api/v2/people-review/{id}/review-campaign-information/{reviewCampaignId} | Configured Talent Card evidence for the reviewed employee; read-people-review plus individual review scope. |
POST /api/v2/people-review-campaign/{id}/export | Asynchronous export; returns 202 with export-task representation; permission plus owner/creator/privileged check. |
Custom answer routes in people_review_campaign_custom_assessment_answer.yaml:
POST /api/v2/people-review/{peopleReviewId}/custom-assessment-answer/{type}/{questionId}
GET /api/v2/people-review/{peopleReviewId}/custom-assessment-answer/{type}/{questionId}/{scope}
PUT /api/v2/people-review/{peopleReviewId}/custom-assessment-answer/{type}/{questionId}/{id}
Route shapes describe caller/resource boundaries; full answer payloads, scope enum values and all response DTO fields are not specified here because they were not completely traced.
Read-only query example, with fictional IDs:
GET /api/v2/people-review-campaign/101/review?filters[employee_username][contain]=Example
Accept: application/json
Filters narrow the authorized population. Dynamic standard/custom employee fields are processed by field-type-specific operators; different fields combine with AND. Unsupported operators are ignored according to the route descriptions. Do not infer a filter can grant access or mutate the employee record.
Talent Card: what prior answers can be exposed?
PeopleReviewReviewCampaignInformationProvider::provide first resolves configured question selections for the People Review campaign and requested Review Campaign. No selection produces an entity-not-found exception. It loads answers for peopleReview.employee.id, not the logged-in reviewer's identity.
Answers are grouped into self, evaluator, secondEvaluator according to UserReviewType and main-evaluator status. The provider keeps the first answer per slot from most-recent-first entries, omits unanswered questions, resolves the source form and includes supported nested choice subquestions. No loaded answers or missing source form can yield an empty information DTO.
This makes selected employee interview responses available through the People Review detail authorization path. A legacy PDF setting is not checked in this provider. Complete equivalence with source-review question visibility, conditional display, sharing and publication rules was Not verified. Do not assert those restrictions are inherited automatically.
Lifecycle and asynchronous assignment
CampaignStatus contains draft, not_started, phase_1, standby, phase_2, done, archived. isEditable() recognizes draft/not started. Immutable-status validators apply to campaign structure, matrices and custom questions; review answer writes use a different validator.
PeopleReviewCampaignManager::isCommitteePhase recognizes standby and phase 2. The inspected write validator therefore accepts committee writes in standby as well as phase 2. The answer-read predicate does not hide phase-1 answers from committee members. Submission delegates to evaluator or committee workflow methods and can reject an invalid status transition.
Assignment uses user, group and talent-pool publishers/consumers. PeopleReviewRepository::updateEvaluatorsByCampaign supports hierarchy levels 1/2/3; N+2 falls back to N+1, N+3 to N+2/N+1 when available. This contradicts the playbook's direct-manager-only description and is why documentation refers to the assigned evaluator. Delegation can also change the stored evaluator; reporting hierarchy alone is not the final read predicate.
Relevant directories: src/Command/Consumer/PeopleReviewCampaign/, src/Infrastructure/MessageBroker/Publisher/PeopleReview/, src/Infrastructure/Persistence/Listener/PeopleReviewCampaign/. Runtime broker processing, notification delivery and actual synchronization delays were not observed.
Failure modes, observability and extension points
| Failure | Where to inspect |
|---|---|
| Permission denied | YAML operation permission, role/group scope, then campaign/review actor predicate. |
| Campaign visible but detail denied | Owner/creator list expansion versus evaluator/committee detail check. |
| Unsupported answer type or missing question | AbstractAnswerValidationService, company/custom validation subclasses and type locators. |
| Readable but write rejected | PeopleReviewValidationService, campaign status and evaluator/committee identity. |
| Invalid submit/status transition | Workflow managers and campaign status service; the controller translates invalid transitions to a bad request. |
| Empty Talent Card | Configured source question selections, source form and reviewed employee's actual answers. |
| Delayed/missing assignments | Related event listener, publisher, consumer and reporting relationship data. |
| Export already running | Export service/task handling; trigger catches the already-in-progress exception. |
Use application error/status information and broker/export operational monitoring without logging questionnaire answers or identifying employee data. Specific log messages, dashboards and operational alerts were not verified.
To extend behavior, trace both route permission and repository scope, then answer validation, DTO transformation and frontend controls. New question types require the appropriate entity, repository/locator, validator, answer and renderer support; adding a frontend control alone does not establish backend support. Translation and Talent Card source rendering are separate concerns.
Coexistence, security and evidence limits
Legacy shell app/config/neobrain/company/definitions.yml declares redesigned People Review activation/menu dependencies. Legacy src/Service/V2/CampaignService.php calls src/Service/PartnerAPI/Mark4/Mk4ReviewCampaignService.php, which declares /api/v2/user/self/people-review-campaign; this establishes a cross-generation caller, not proof of legacy questionnaire migration.
Keep the following decisions separate: menu entry, campaign discovery, employee row scope, answer-read scope, phase write authority, source interview data, PDF/export output and permission-scoped related fields. Neither “administrator” nor “HR” has one universal meaning across these layers.
Documented in Confluence, read during investigation:
| Source | Version / last modified | Use |
|---|---|---|
| Handle visibility rules in a People Review | v5 / 21 May 2026 | Legacy relationship scope and campaign Administrator. |
| Playbook - People Review | v7 / 8 August 2023 | Legacy questionnaire and campaign setup. |
| People Review - Form Visibility | v3 / 7 August 2023 | PDF question visibility, distinct from on-screen authorization. |
| Playbook - SmartMobility Redesign (SMR) | v3 / 24 September 2026 | Assessment/calibration/Talent Card context; wizard and hierarchy statements differ from current code. |
| Questions that can be removed from a People Review questionnaire | v3 / 21 May 2026 | Questionnaire focus; advisory examples are not access-control requirements. |
KBCT 2136702980 was resolved as the FAQ folder. PS 2104033292 (methodology, v7) and 2104983553 (onboarding, v9) were read; no endpoint or permission claim relies on them. Documentary guidance is not proof of production behavior.
Not verified: live deployment revision, all middleware and field-level security paths, complete source-form visibility inheritance, every legacy write endpoint, production notification/broker operation, and any automatic migration. No secrets, real employee answers or application screenshots are included.
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.
Reviewed on 15 October 2026. Verified in code refers to local working-tree sources, not proof of production deployment.
| Source | Evidence used |
|---|---|
smartmobility-legacy/src/Company/ReviewBundle/Controller/DefaultController.php — indexAction | Campaign list, relationship-derived employee list, sorting. |
smartmobility-legacy/src/Company/ReviewBundle/Services/UsersRelationsReview.php | Employee relationships, reviewer and campaign-admin membership. |
smartmobility-legacy/src/Company/ReviewBundle/Controller/ReviewAssessmentController.php, ReviewPDFController.php | Individual/collective/PDF conditions and their differences. |
smartmobility-nextgen-back/src/Infrastructure/Persistence/Repository/PeopleReview/PeopleReviewRepository.php | Campaign-list, matrix and export populations. |
smartmobility-nextgen-back/src/Infrastructure/Service/PeopleReview/PeopleReviewValidationService.php | Answer reads and phase-dependent writes. |
smartmobility-nextgen-back/src/Infrastructure/Persistence/Service/PeopleReview/PeopleReviewReviewCampaignInformationProvider.php | Employee-specific Talent Card answer retrieval. |
smartmobility-nextgen-front/src/modules/ModuleConfig/PeopleReview/ | Filters, store defaults, wizard and API callers. |
Documented in Confluence: the linked legacy visibility guide, legacy playbook, PDF-visibility guide and redesign playbook were read. Legacy playbook version metadata is recorded in the technical guide. The KBCT entry point 2136702980 resolves to the 4. FAQ Produit folder. PS methodology/onboarding entry points were read but do not establish People Review access rules.
Documented in Confluence: Handle visibility rules in a People Review, version 5, last modified 21 May 2026. The campaign list and employee list behavior are also Verified in code in DefaultController::indexAction and UsersRelationsReview.
Dernière mise à jour : 3 novembre 2026