Training & Development $79.99 / mo Updated 2026-04-24 VERSION 2 · NEW

Agent Feedback & Surveys — Setup & Workflow Guide

Three feedback collection modes under one module — open-ended feedback with category + sentiment selectors, weekly pulse surveys with one-tap responses, and assigned multi-question surveys. Built around a FeedbackEngine class and /crm/api/feedback.php JSON endpoint with strict tenant isolation on every write.

Overview

Three distinct collection modes under one module:

  • Open-ended feedback — free-text submissions with category, sentiment, related-to context, and anonymous / visible-to-team toggles. Goes through a new → acknowledged → resolved workflow so supervisors can track follow-up.
  • Pulse surveys — one-question scaled surveys that recur every N days. One-tap responses with optional comments. Team average is recomputed after every response.
  • Assigned surveys — multi-question surveys assigned to all agents or specific roles. Supports text, textarea, radio, checkbox, rating, scale, NPS, matrix question types. Progress saves automatically; completion requires all is_required = 1 questions answered.

What's new in V2

Full submission flow

FeedbackEngine ships submitFeedback, respondToPulse, startSurvey, submitSurveyAnswer, and finishSurvey methods. /crm/api/feedback.php is the JSON endpoint, with inline submission forms wired into each tab of the CRM module.

Tenant isolation on every write

Every category_id, survey_id, and pulse_id is validated against the sender's tenant before the INSERT. A crafted POST with another tenant's category ID returns "Invalid category" with no row written.

Sanitized error responses

DB exceptions are logged server-side via error_log() but never echoed to the client. Clients see generic strings like "Could not submit — please try again." and /logs/php_errors.log has the detail.

Pulse rolling averages

Every pulse response triggers a recompute of feedback_pulse_surveys.total_responses and average_score. Dashboards are live — no daily roll-up cron needed.

Admin state viewer

New /admin/view-feedback-state.php shows schema health, per-tenant activity stats, recent feedback submissions, pulse participation, open action items, and survey response/completion counts. Per the browser-only QA workflow — no MySQL CLI needed.

Role-aware listing

Non-admin agents see only their own submissions plus anything marked visible_to_team. Tenant admins see everything. Server-side enforcement in listFeedback(), not just UI filtering.

Feedback submission

Agents hit the Feedback tab inside the CRM and see a submit form at the top:

  • Feedback text — required, up to 5,000 chars (truncated silently via mb_substr).
  • Category — optional dropdown populated from feedback_categories where tenant_id = current and is_active = 1.
  • Sentiment — positive / neutral / negative. Agent-declared; V2 doesn't auto-analyze. The Sentiment Analysis module integrates separately if needed.
  • Related to — optional context (manager / team / process / tools / training / system / other).
  • Submit anonymously — flips is_anonymous. Listing queries substitute "Anonymous" for the submitter name. The submitted_by user_id is still stored for FK integrity.
  • Share with team — flips visible_to_team. Non-admin teammates can see it.

Submissions default to status = 'new'. The admin acknowledge/resolve workflow takes over from there.

Pulse surveys

Single-question recurring surveys. Configured by tenant admins in feedback_pulse_surveys:

  • question — the prompt, up to 500 chars
  • scale_min / scale_max — numeric range (e.g. 1-5, 0-10)
  • scale_labels — optional JSON array of labels for each scale point (e.g. ["Poor","Fair","Good","Very good","Excellent"])
  • frequency_days — how often agents should respond (e.g. 7 for weekly)
  • allow_comments — if true, agents see an optional comment textarea

Agents see pulses in the Team Pulse tab. A "Due" badge shows when their last response is older than frequency_days; "Answered recently" otherwise. One tap on a scale button records the response. Team average is shown alongside the question. The engine validates the value is within [scale_min, scale_max] and strips comments if allow_comments = 0.

After every response, total_responses and average_score on the pulse row are recomputed in the same transaction. No background cron needed for the stats to stay fresh.

Assigned surveys

Multi-question surveys live in feedback_surveys with questions in feedback_survey_questions. V2 supports:

  • text / textarea — free-form with optional max_length
  • radio — single selection from options JSON array
  • checkbox — multiple selections, stored in answer_options JSON
  • rating / scale / nps — numeric with min_value / max_value validation
  • matrix — multi-dimensional selection (stored as JSON)

Flow: startSurvey(id) creates (or resumes) a response row with status = 'in_progress'. The UNIQUE constraint on (user_id, survey_id) prevents duplicates. submitSurveyAnswer(responseId, questionId, answer) upserts one answer row per question — the agent can revise answers until finalization. finishSurvey(responseId) validates all required questions have answers, flips status to 'completed', and records completion_time_seconds.

Survey creation (the admin side) isn't yet available through a UI in V2 — admins need to INSERT directly into feedback_surveys and feedback_survey_questions. A builder UI is on the V2.1 roadmap.

Admin workflow

Four statuses on feedback_submissions:

  1. new — fresh submission
  2. acknowledged — admin has seen it and flagged for follow-up (records acknowledged_by + acknowledged_at)
  3. in_review — longer-running investigation (optional intermediate state)
  4. resolved — closed with optional notes (records resolved_by + resolved_at + resolution_notes)

Admins see all submissions in the Feedback tab with action buttons next to each row: Acknowledge (only shows for status = 'new'), Resolve (any unresolved status → resolved). Both actions go through the engine which enforces admin role_id and tenant scoping.

Action items (feedback_action_items) can be created from feedback to track follow-up work: priority (critical / high / medium / low), assigned_to, due_date. The state viewer surfaces all open items sorted by priority. A UI for creating action items from feedback is on the V2.1 roadmap — today they require direct INSERT.

Quick start ≈ 15 minutes

  1. Activate the module at RubiMine. $79.99/mo.
  2. Sysadmin verifies schema at /admin/run-feedback-v2-migration.php. All 10 tables should show ✅ exists.
  3. Seed categories (if not already present) — the migration ships with 6 defaults per tenant. Customize via direct SQL in feedback_categories.
  4. Configure pulse surveys — default install ships 3 pulse questions per tenant. Review them or add your own in feedback_pulse_surveys.
  5. Announce the feature to agents — Internal Messaging's admin broadcast is a good channel. Point them at the CRM Feedback tab.
  6. Agents start submitting — forms are inline, no training needed.
  7. Admins acknowledge + resolve incoming feedback from the same tab.

API endpoints

All endpoints on /crm/api/feedback.php. Session-authenticated, tenant-scoped.

Feedback

POST action=submit_feedback         (feedback_text, category_id?, related_to?, sentiment?, is_anonymous?, visible_to_team?)
POST action=list_feedback           (status?, sentiment?, category_id?)
POST action=list_categories
POST action=acknowledge_feedback    (feedback_id) — admin only
POST action=resolve_feedback        (feedback_id, resolution_notes?) — admin only

Pulse

POST action=list_pulse_surveys
POST action=respond_to_pulse        (pulse_id, value, comment?)

Surveys

POST action=list_my_surveys         → pending + in-progress surveys for current user
GET  action=get_survey              (survey_id) → full questions + current answers
POST action=start_survey            (survey_id) → response_id
POST action=submit_answer           (response_id, question_id, answer)
POST action=finish_survey           (response_id) → {ok, completion_time_seconds} or {missing_question_ids}

Known limitations (V2)

  • Survey builder UI — admins need direct SQL to create surveys + questions today. UI coming in V2.1.
  • Action item creation UI — the feedback_action_items table exists but creating items from feedback needs direct INSERT. V2.1.
  • Sentiment auto-detection — sentiment is agent-declared. Integrates with the Sentiment Analysis module for automatic scoring; V2 doesn't do this inline.
  • Exit interview templates — schema supports the 'exit' survey type but no built-in templates. Custom creation via SQL.
  • Pulse analytics — state viewer shows 7-day + total counts. Trend charts (month-over-month, by department) planned for V2.1.
  • Agent notifications — no email / push notifications when new pulses become "due". V2.1 will integrate with Notifications Engine.
  • Feedback export — no CSV export today. Direct SQL works for e-discovery / compliance exports.

Frequently asked questions

What does the FeedbackEngine do?
FeedbackEngine is the single source of truth for every write path: submitFeedback, respondToPulse, startSurvey, submitSurveyAnswer, finishSurvey, plus admin acknowledge / resolve flows. /crm/api/feedback.php is the JSON endpoint wrapping each method. Inline submission forms in the CRM module's existing tabs post directly to the engine. Tenant isolation is enforced on every category_id, survey_id, and pulse_id reference before the INSERT.
How does anonymous feedback work?
Submitter's user_id is still stored (FK constraint) but is_anonymous = 1 makes the UI show "Anonymous" instead of their name. Tenant admins could still identify via direct DB access if required for legal compliance.
What validation runs before a submission?
Text non-empty + ≤ 5,000 chars; category_id (if provided) is tenant-owned + active; related_to matches enum; sentiment matches enum. Cross-tenant category_ids return "Invalid category".
How do pulse surveys work?
One-question scaled surveys that recur every N days. One-tap responses, optional comments. Team average recomputes after every response. Agents see "Due" or "Answered recently" badges based on their last response timestamp.
Can agents take the same survey twice?
No. UNIQUE (user_id, survey_id) prevents duplicates. Re-opening a completed survey returns the existing response; re-opening an in-progress one resumes it. Retake support is a V2.1 feature.
How are required questions enforced?
finishSurvey() runs a LEFT JOIN check — every is_required=1 question must have an answer row. Missing answers block finalization with a list of missing question_ids. Response stays in_progress until filled.
Can admins see anonymous feedback?
In the UI the From column shows "Anonymous" with a user-secret icon. Tenant admins see all submissions — anonymous and not — but the submitter's name is masked in the UI for is_anonymous rows.
What's the acknowledge / resolve workflow?
new → acknowledged → in_review → resolved. Each transition is timestamped + user-stamped. Resolution can include notes. All state lives on the feedback_submissions row.
How much does this cost?
$79.99 / month / tenant. Unlimited submissions, pulse responses, surveys, questions, action items. No per-seat or per-submission fees.

Ready to collect real feedback?

Activate from RubiMine, verify the schema, and your agents can start submitting in 15 minutes. Already active? Check the state viewer for current activity.