package io.flow.lint.linters

import io.flow.lint.Linter
import com.bryzek.apidoc.spec.v0.models.{Field, Model, Service}

/**
  * For all models, except for those whose name ends in _form", common
  * fields should not have descriptions. This enables us to generate
  * consistent documenetation without worrying about whether a
  * particular description adds anything useful.
  */
case object CommonFieldsHaveNoDescriptions extends Linter with Helpers {

  val NamesWithNoDescriptions = Seq("id", "number", "guid", "email")

  override def validate(service: Service): Seq[String] = {
    service.models.filter(!_.name.endsWith("_form")).flatMap(validateModel(service, _))
  }

  def validateModel(service: Service, model: Model): Seq[String] = {
    model.fields.flatMap(validateFieldDescription(service, model, _))
  }

  def validateFieldDescription(service: Service, model: Model, field: Field): Seq[String] = {
    field.description match {
      case None => {
        Nil
      }
      case Some(desc) => {
        NamesWithNoDescriptions.contains(field.name) match {
          case false => {
            Nil
          }
          case true => {
            Seq(error(model, field, "Must not have a description"))
          }
        }
      }
    }
  }

}

package io.flow.lint.linters

import io.flow.lint.Linter
import com.bryzek.apidoc.spec.v0.models.{Field, Model, Service}

/**
  * For all models, except for those whose name ends in _form", common
  * fields should not have descriptions. This enables us to generate
  * consistent documenetation without worrying about whether a
  * particular description adds anything useful.
  */
case object CommonFieldsHaveNoDescriptions extends Linter with Helpers {

  val NamesWithNoDescriptions = Seq("id", "number", "guid")

  override def validate(service: Service): Seq[String] = {
    service.models.filter(!_.name.endsWith("_form")).flatMap(validateModel(service, _))
  }

  def validateModel(service: Service, model: Model): Seq[String] = {
    model.fields.flatMap(validateFieldDescription(service, model, _))
  }

  def validateFieldDescription(service: Service, model: Model, field: Field): Seq[String] = {
    field.description match {
      case None => {
        Nil
      }
      case Some(desc) => {
        NamesWithNoDescriptions.contains(field.name) match {
          case false => {
            Nil
          }
          case true => {
            Seq(error(model, field, "Must not have a description"))
          }
        }
      }
    }
  }

}

Allow description for email fields
Allow description for email fields

  - we had a nice description of user.email in common API which
    makes me think we should allow this:

If known, the user's primary email address. While in most common cases, we expect users to have email addresses, there are edge cases where it is useful to allow a user to NOT have an email address. For example, users interacting solely from mobile devices, guest user accounts, initial onboarding where email is not known, etc. We think by starting off with an optional primary email address we can support these use cases with very little implementation cost.
