Skip to content

Case Data Schema

Overview

The case management system stores all child protection cases, communications, and related information in the helpline MySQL database. This document describes the core data structures for contributors working on case-related features.

Core Tables

kase - Main Cases Table

Primary table storing case information.

sql
CREATE TABLE kase (
  id INT PRIMARY KEY AUTO_INCREMENT,
  case_number VARCHAR(50) UNIQUE NOT NULL,
  title VARCHAR(255) NOT NULL,
  description TEXT,
  category VARCHAR(50),
  subcategory VARCHAR(50),
  priority ENUM('low', 'medium', 'high', 'critical') DEFAULT 'medium',
  status ENUM('open', 'assigned', 'in_progress', 'resolved', 'closed') DEFAULT 'open',
  
  -- Reporter information
  reporter_name VARCHAR(255),
  reporter_phone VARCHAR(20),
  reporter_email VARCHAR(255),
  reporter_relationship VARCHAR(100),
  
  -- Child information
  child_name VARCHAR(255),
  child_age INT,
  child_gender ENUM('male', 'female', 'other', 'unknown'),
  child_location VARCHAR(255),
  
  -- Assignment
  assigned_user_id INT,
  assigned_organization VARCHAR(255),
  
  -- AI-generated fields
  ai_transcript TEXT,
  ai_translation TEXT,
  ai_entities JSON,
  ai_classification VARCHAR(100),
  ai_risk_level ENUM('low', 'medium', 'high', 'critical'),
  ai_confidence DECIMAL(3,2),
  
  -- Metadata
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  created_by INT,
  updated_by INT,
  
  FOREIGN KEY (assigned_user_id) REFERENCES auth(id),
  FOREIGN KEY (created_by) REFERENCES auth(id),
  INDEX idx_status (status),
  INDEX idx_priority (priority),
  INDEX idx_created_at (created_at)
);

Field Descriptions:

FieldTypeDescriptionExample
case_numberVARCHAR(50)Unique case identifier"CASE-2025-001234"
titleVARCHAR(255)Brief case description"Child safety concern reported"
categoryVARCHAR(50)Main case category"abuse", "neglect", "education"
priorityENUMCase urgency level"high", "critical"
ai_entitiesJSONExtracted entities from AI
ai_risk_levelENUMAI-assessed risk"high", "critical"

kase_activity - Case Activities

Tracks all actions and updates on cases.

sql
CREATE TABLE kase_activity (
  id INT PRIMARY KEY AUTO_INCREMENT,
  kase_id INT NOT NULL,
  activity_type ENUM('note', 'status_change', 'assignment', 'escalation', 'resolution'),
  description TEXT,
  previous_value VARCHAR(255),
  new_value VARCHAR(255),
  
  -- User information
  user_id INT,
  user_name VARCHAR(255),
  
  -- Metadata
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  ip_address VARCHAR(45),
  
  FOREIGN KEY (kase_id) REFERENCES kase(id) ON DELETE CASCADE,
  FOREIGN KEY (user_id) REFERENCES auth(id),
  INDEX idx_kase_id (kase_id),
  INDEX idx_created_at (created_at)
);

Activity Types:

  • note - General case note or comment
  • status_change - Case status updated
  • assignment - Case assigned to user/organization
  • escalation - Case escalated to supervisor
  • resolution - Case marked as resolved

contact - Communications Log

Records all communications related to cases (calls, SMS, emails, web forms).

sql
CREATE TABLE contact (
  id INT PRIMARY KEY AUTO_INCREMENT,
  kase_id INT,
  contact_type ENUM('call', 'sms', 'email', 'web', 'whatsapp') NOT NULL,
  direction ENUM('inbound', 'outbound') NOT NULL,
  
  -- Contact details
  contact_address VARCHAR(255),  -- Phone/email/username
  contact_name VARCHAR(255),
  
  -- Communication content
  subject VARCHAR(255),
  message TEXT,
  duration INT,  -- For calls, in seconds
  
  -- Call-specific fields
  call_id VARCHAR(100),
  call_status ENUM('answered', 'missed', 'busy', 'failed'),
  
  -- Audio processing
  audio_file_path VARCHAR(500),
  audio_processed BOOLEAN DEFAULT FALSE,
  
  -- Disposition
  disposition_id INT,
  disposition_notes TEXT,
  
  -- Metadata
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  created_by INT,
  
  FOREIGN KEY (kase_id) REFERENCES kase(id) ON DELETE SET NULL,
  FOREIGN KEY (created_by) REFERENCES auth(id),
  FOREIGN KEY (disposition_id) REFERENCES disposition(id),
  INDEX idx_kase_id (kase_id),
  INDEX idx_contact_type (contact_type),
  INDEX idx_created_at (created_at)
);

disposition - Call Outcomes

Categorizes communication outcomes.

sql
CREATE TABLE disposition (
  id INT PRIMARY KEY AUTO_INCREMENT,
  code VARCHAR(50) UNIQUE NOT NULL,
  name VARCHAR(255) NOT NULL,
  description TEXT,
  category ENUM('case_created', 'referral', 'information', 'prank', 'no_response'),
  is_active BOOLEAN DEFAULT TRUE,
  display_order INT,
  
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

Common Dispositions:

  • CASE_NEW - New case created from call
  • CASE_UPDATE - Existing case updated
  • REFERRAL_GIVEN - Caller referred to services
  • INFO_PROVIDED - Information/guidance provided
  • PRANK_CALL - Identified as prank
  • SILENT_CALL - No response from caller
  • FOLLOW_UP_SCHEDULED - Follow-up scheduled

attachment - File Attachments

Stores files attached to cases.

sql
CREATE TABLE attachment (
  id INT PRIMARY KEY AUTO_INCREMENT,
  kase_id INT NOT NULL,
  filename VARCHAR(255) NOT NULL,
  original_filename VARCHAR(255),
  file_path VARCHAR(500) NOT NULL,
  file_size INT,
  mime_type VARCHAR(100),
  file_type ENUM('audio', 'document', 'image', 'other'),
  
  -- Description
  description TEXT,
  
  -- Processing status (for audio files)
  processing_status ENUM('pending', 'processing', 'completed', 'failed') DEFAULT 'pending',
  ai_task_id VARCHAR(100),
  
  -- Metadata
  uploaded_by INT,
  uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  FOREIGN KEY (kase_id) REFERENCES kase(id) ON DELETE CASCADE,
  FOREIGN KEY (uploaded_by) REFERENCES auth(id),
  INDEX idx_kase_id (kase_id),
  INDEX idx_processing_status (processing_status)
);

JSON Field Structures

ai_entities (JSON)

Structure of AI-extracted entities:

json
{
  "PERSON": ["Maria Wanjiku", "Dr. John Kamau"],
  "LOC": ["Nairobi", "Kibera", "Kenya"],
  "ORG": ["Kenyatta Hospital", "Police Station"],
  "DATE": ["2025-09-26"],
  "TIME": ["14:30"],
  "AGE": ["12 years old"],
  "PHONE": ["+254700123456"]
}

Entity Types:

  • PERSON - Names of people mentioned
  • LOC - Locations (cities, neighborhoods, addresses)
  • ORG - Organizations (hospitals, schools, police)
  • DATE - Dates mentioned
  • TIME - Times mentioned
  • AGE - Age references
  • PHONE - Phone numbers

Data Relationships

┌─────────────┐
│    kase     │
│ (Main Case) │
└──────┬──────┘

       ├─────────┐
       │         │
       ▼         ▼
┌─────────────┐ ┌─────────────┐
│kase_activity│ │   contact   │
│(Activities) │ │(Communica-  │
│             │ │  tions)     │
└─────────────┘ └──────┬──────┘

       ┌───────────────┤
       │               │
       ▼               ▼
┌─────────────┐ ┌─────────────┐
│disposition  │ │ attachment  │
│(Outcomes)   │ │  (Files)    │
└─────────────┘ └─────────────┘

Example Queries

Create a New Case

sql
INSERT INTO kase (
  case_number,
  title,
  description,
  category,
  priority,
  reporter_phone,
  child_name,
  child_age,
  created_by
) VALUES (
  'CASE-2025-001234',
  'Child safety concern',
  'Reported concern about child welfare',
  'abuse',
  'high',
  '+254700123456',
  'Maria W.',
  12,
  5  -- user_id
);

Get Cases with Latest Activity

sql
SELECT 
    k.id,
    k.case_number,
    k.title,
    k.status,
    k.priority,
    MAX(ka.created_at) as last_activity,
    u.username as assigned_to
FROM 
    kase k
    LEFT JOIN kase_activity ka ON k.id = ka.kase_id
    LEFT JOIN auth u ON k.assigned_user_id = u.id
WHERE 
    k.status IN ('open', 'assigned', 'in_progress')
GROUP BY 
    k.id
ORDER BY 
    last_activity DESC
LIMIT 20;

Get Complete Case with Communications

sql
SELECT 
    k.*,
    c.id as contact_id,
    c.contact_type,
    c.message,
    c.created_at as contact_date,
    d.name as disposition
FROM 
    kase k
    LEFT JOIN contact c ON k.id = c.kase_id
    LEFT JOIN disposition d ON c.disposition_id = d.id
WHERE 
    k.case_number = 'CASE-2025-001234'
ORDER BY 
    c.created_at DESC;

Update Case with AI Results

sql
UPDATE kase SET
    ai_transcript = 'Transcribed text...',
    ai_translation = 'Translated text...',
    ai_entities = '{"PERSON": ["Maria"], "LOC": ["Nairobi"]}',
    ai_classification = 'child_protection',
    ai_risk_level = 'high',
    ai_confidence = 0.94,
    updated_at = NOW(),
    updated_by = 1
WHERE 
    id = 123;

Data Validation Rules

Case Creation

  • case_number must be unique
  • title is required
  • priority defaults to 'medium'
  • status defaults to 'open'
  • Either reporter_phone or reporter_email should be provided

Child Information

  • child_age must be 0-18
  • child_gender must be valid enum value
  • Child information should be anonymized in logs

AI Fields

  • ai_confidence must be between 0.00 and 1.00
  • ai_entities must be valid JSON
  • ai_risk_level triggers automatic assignment for 'critical' cases

Privacy Considerations

Sensitive Data

The following fields contain Personally Identifiable Information (PII):

  • reporter_name, reporter_phone, reporter_email
  • child_name, child_location
  • contact.contact_address, contact.message
  • ai_transcript, ai_translation

Data Protection

  • All PII should be encrypted at rest
  • Access logs maintained for all PII access
  • Data retention policies apply:
    • Active cases: Indefinite
    • Resolved cases: 7 years
    • AI transcripts: 1 year after case closure
  • Anonymization applied for analytics/reporting

Access Control

  • Case managers can view assigned cases only
  • Supervisors can view all cases in their region
  • System administrators have full access
  • Audit logs track all data access

Contributing Guidelines

When Adding New Fields

  1. Update this documentation
  2. Create database migration script
  3. Update API endpoints
  4. Add validation rules
  5. Consider privacy implications
  6. Update test fixtures

Best Practices

  • Always use prepared statements
  • Validate all user inputs
  • Log all data modifications
  • Handle NULL values appropriately
  • Use transactions for multi-table updates
  • Index frequently queried fields

For more information on using these schemas in your code, see the API Reference.