Skip to content

Data model

sandramchung edited this page Jun 29, 2017 · 14 revisions

assignment

  • id: type.string(),
  • user_id: requiredString(),
  • campaign_id: requiredString(),
  • created_at: timestamp()

campaign

  • id: type.string(),
  • organization_id: requiredString(),
  • title: optionalString(),
  • description: optionalString(),
  • is_started: type.boolean().required(),
  • due_by: type.date().required().default(null),
  • created_at: timestamp(),
  • is_archived: type.boolean().required()

campaign-contact

  • id: type.string(),
  • campaign_id: requiredString(),
  • assignment_id: optionalString(),
  • first_name: optionalString(),
  • last_name: optionalString(),
  • cell: requiredString(),
  • zip: optionalString(),
  • custom_fields: type.object().required().allowNull(false).default({}),
  • created_at: timestamp(),
  • message_status: requiredString().enum(['needsMessage','needsResponse','messaged','closed']).default('needsMessage'),
  • is_opted_out: type.boolean().default(false),
  • timezone_offset: type.string().default('').required()

canned-response

  • id: type.string(),
  • campaign_id: requiredString(),
  • text: requiredString(),
  • title: requiredString(),
  • user_id: optionalString(),
  • created_at: timestamp()

interaction-step

  • id: type.string(),
  • campaign_id: requiredString(),
  • question: optionalString(),
  • script: optionalString(),
  • answer_options: type.array().schema({interaction_step_id: optionalString(), value: optionalString()}).required().allowNull(false),
  • created_at: timestamp()

invite

  • id: type.string(),
  • is_valid: type.boolean().required().allowNull(false),
  • created_at: timestamp()

job-request

  • id: type.string(),
  • payload: type.object().required(),
  • queue_name: requiredString(),
  • job_type: requiredString(),
  • locks_queue: type.boolean().required().default(false),
  • assigned: type.boolean().required().default(false),
  • status: type.number().integer().required().default(0),
  • updated_at: timestamp(),
  • created_at: timestamp()

message

  • id: type.string(),
  • user_number: optionalString(),
  • contact_number: requiredString(),
  • is_from_contact: type.boolean().required().allowNull(false),
  • text: optionalString(),
  • assignment_id: requiredString(),
  • service: optionalString(),
  • send_status: requiredString().enum('QUEUED', 'SENT', 'DELIVERED', 'ERROR', 'PAUSED', 'NOT_ATTEMPTED'),
  • service_message_ids: type.array().schema(type.string()).required().default([]),
  • service_messages: type.array().schema(type.object()).required().default([]),
  • created_at: timestamp()

opt-out

  • id: type.string(),
  • cell: requiredString(),
  • assignment_id: requiredString(),
  • organization_id: requiredString(),
  • created_at: timestamp()

organization (flattened)

  • id: type.string(),
  • name: requiredString(),
  • created_at: timestamp(),
  • features: type.string().required().default(''), //should be restricted by FEATURES
  • texting_hours_enforced: type.boolean().required().default(false),
  • texting_hours_start: type.number().integer().required().min(0).max(24).default(9),
  • texting_hours_end: type.number().integer().required().min(0).max(24).default(21)

pending-message-part

  • id: type.string(),
  • service: requiredString(),
  • parent_id: optionalString(),
  • service_message: type.object().required(),
  • user_number: requiredString(),
  • contact_number: requiredString(),
  • created_at: timestamp()

question-response

  • id: type.string(),
  • campaign_contact_id: requiredString(),
  • interaction_step_id: requiredString(),
  • value: requiredString(),
  • created_at: timestamp()

user

  • id: type.string(),
  • auth0_id: requiredString(),
  • first_name: requiredString(),
  • last_name: requiredString(),
  • cell: requiredString(),
  • email: requiredString(),
  • created_at: timestamp(),
  • assigned_cell: type.string(),
  • is_superadmin: type.boolean()

user-cell

  • id: type.string(),
  • cell: requiredString(),
  • user_id: requiredString(),
  • service: type.string().required().enum('nexmo', 'twilio'),
  • is_primary: type.boolean().required()

user-organization

  • id: type.string(),
  • user_id: requiredString(),
  • organization_id: requiredString(),
  • role: requiredString().enum('OWNER', 'ADMIN', 'TEXTER')

zip-code

In case you are curious, yes there are zip codes that each map to multiple cities (100 or so) and timezones.

  • zip: requiredString(),
  • city: requiredString(),
  • state: requiredString(),
  • location: type.point().required().allowNull(false),
  • timezone_offset: type.number().required().allowNull(false),
  • has_dst: type.boolean().required().allowNull(false)

Clone this wiki locally