Skip to main content

Overview

The assessment engine powers self-service security assessments. Prospects and existing tenants complete questionnaires to evaluate their security posture. Completed assessments can be converted into full tenant accounts with pre-populated controls.

Data Model

assessment_templates (
  id            uuid PRIMARY KEY,
  name          text,
  description   text,
  category      text,          -- 'general', 'soc2', 'hipaa'
  is_active     boolean,
  created_at    timestamptz
)

assessment_template_questions (
  id            uuid PRIMARY KEY,
  template_id   uuid REFERENCES assessment_templates,
  question_text text,
  question_type text,          -- 'multiple_choice', 'yes_no', 'scale', 'text'
  options       jsonb,         -- Available choices for multiple_choice
  weight        numeric,       -- Scoring weight
  category      text,          -- Groups questions for category scoring
  sort_order    int
)

assessments (
  id            uuid PRIMARY KEY,
  template_id   uuid REFERENCES assessment_templates,
  tenant_id     uuid,          -- NULL until converted
  status        text,          -- 'in_progress', 'completed', 'converted'
  company_name  text,
  company_info  jsonb,
  created_at    timestamptz,
  completed_at  timestamptz
)

assessment_responses (
  id              uuid PRIMARY KEY,
  assessment_id   uuid REFERENCES assessments,
  question_id     uuid REFERENCES assessment_template_questions,
  response_value  jsonb,
  created_at      timestamptz
)

assessment_results (
  id              uuid PRIMARY KEY,
  assessment_id   uuid REFERENCES assessments,
  overall_score   numeric,
  category_scores jsonb,
  risk_level      text,        -- 'low', 'medium', 'high', 'critical'
  recommendations jsonb
)

Wizard Flow

The assessment follows a multi-step wizard:
1

Template Selection

User chooses an assessment template (e.g., General Security, SOC 2 Readiness, HIPAA).
2

Company Information

User provides company details: name, industry, size, existing security measures. Stored in assessments.company_info as JSONB.
3

Questions

Questions are presented in order, grouped by category. Responses are saved to assessment_responses as the user progresses (auto-save on each step).
4

Results

On completion, rpc_complete_assessment is called to calculate scores and generate recommendations.

Scoring

computeRiskScore

Calculates an overall risk score from individual question responses:
function computeRiskScore(responses: AssessmentResponse[]): number {
  let totalWeight = 0;
  let weightedScore = 0;

  for (const response of responses) {
    const weight = response.question.weight;
    const score = scoreResponse(response);
    weightedScore += score * weight;
    totalWeight += weight;
  }

  // Returns 0-100 where 100 = best security posture
  return Math.round((weightedScore / totalWeight) * 100);
}

computeTemplateScore

Breaks down scores by question category:
function computeTemplateScore(
  responses: AssessmentResponse[]
): CategoryScores {
  const categories = groupBy(responses, r => r.question.category);

  return Object.fromEntries(
    Object.entries(categories).map(([category, catResponses]) => [
      category,
      computeRiskScore(catResponses),
    ])
  );
}
Scoring uses a 0-100 scale where 100 represents the strongest security posture. This aligns with the tenant risk scoring model.

Assessment Completion

The rpc_complete_assessment function handles finalization:
SELECT rpc_complete_assessment(p_assessment_id := 'uuid-here');
This function:
  1. Validates all required questions are answered
  2. Computes overall_score and category_scores
  3. Determines risk_level from the score
  4. Generates recommendations based on low-scoring categories
  5. Updates assessments.status to 'completed'
  6. Inserts a row in assessment_results

Tenant Conversion

A completed assessment can be converted into a full tenant:
SELECT rpc_convert_assessment_to_tenant(
  p_assessment_id := 'uuid-here',
  p_owner_user_id := 'uuid-here'
);
This function:
  1. Creates a new tenants record from the company info
  2. Creates tenant_memberships for the owner
  3. Pre-populates tenant_controls based on assessment responses
  4. Sets initial maturity levels from the assessment scores
  5. Selects recommended frameworks based on industry and responses
  6. Updates assessments.status to 'converted' and sets tenant_id
Partners can use the assessment flow to onboard new clients. The assessment results help prioritize which controls and frameworks to focus on first.

Key RPC Functions

FunctionPurpose
rpc_complete_assessmentCalculate scores and finalize assessment
rpc_convert_assessment_to_tenantCreate tenant from completed assessment