text: /**
   * User.js
   *
   * A user who can log in to this application.
   */
  
  module.exports = {
  
    attributes: {
  
      //  ╔═╗╦═╗╦╔╦╗╦╔╦╗╦╦  ╦╔═╗╔═╗
      //  ╠═╝╠╦╝║║║║║ ║ ║╚╗╔╝║╣ ╚═╗
      //  ╩  ╩╚═╩╩ ╩╩ ╩ ╩ ╚╝ ╚═╝╚═╝
  
      emailAddress: {
        type: 'string',
        required: true,
        unique: true,
        isEmail: true,
        maxLength: 200,
        example: 'mary.sue@example.com'
      },
  
      emailStatus: {
        type: 'string',
        isIn: ['unconfirmed', 'change-requested', 'confirmed'],
        defaultsTo: 'confirmed',
        description: 'The confirmation status of the user\'s email address.',
        extendedDescription:
  `Users might be created as "unconfirmed" (e.g. normal signup) or as "confirmed" (e.g. hard-coded
  admin users).  When the email verification feature is enabled, new users created via the
  signup form have \`emailStatus: 'unconfirmed'\` until they click the link in the confirmation email.
  Similarly, when an existing user changes their email address, they switch to the "change-requested"
  email status until they click the link in the confirmation email.`
      },
  
      emailChangeCandidate: {
        type: 'string',
        isEmail: true,
        description: 'A still-unconfirmed email address that this user wants to change to (if relevant).'
      },
  
      password: {
        type: 'string',
        required: true,
        description: 'Securely hashed representation of the user\'s login password.',
        protect: true,
        example: '2$28a8eabna301089103-13948134nad'
      },
  
      fullName: {
        type: 'string',
        required: true,
        description: 'Full representation of the user\'s name.',
        maxLength: 120,
        example: 'Mary Sue van der McHenst'
      },
  
      isSuperAdmin: {
        type: 'boolean',
        description: 'Whether this user is a "super admin" with extra permissions, etc.',
        extendedDescription:
  `Super admins might have extra permissions, see a different default home page when they log in,
  or even have a completely different feature set from normal users.  In this app, the \`isSuperAdmin\`
  flag is just here as a simple way to represent two different kinds of users.  Usually, it's a good idea
  to keep the data model as simple as possible, only adding attributes when you actually need them for
  features being built right now.
  
  For example, a "super admin" user for a small to medium-sized e-commerce website might be able to
  change prices, deactivate seasonal categories, add new offerings, and view live orders as they come in.
  On the other hand, for an e-commerce website like Walmart.com that has undergone years of development
  by a large team, those administrative features might be split across a few different roles.
  
  So, while this \`isSuperAdmin\` demarcation might not be the right approach forever, it's a good place to start.`
      },
  
      passwordResetToken: {
        type: 'string',
        description: 'A unique token used to verify the user\'s identity when recovering a password.  Expires after 1 use, or after a set amount of time has elapsed.'
      },
  
      passwordResetTokenExpiresAt: {
        type: 'number',
        description: 'A JS timestamp (epoch ms) representing the moment when this user\'s `passwordResetToken` will expire (or 0 if the user currently has no such token).',
        example: 1502844074211
      },
  
      emailProofToken: {
        type: 'string',
        description: 'A pseudorandom, probabilistically-unique token for use in our account verification emails.'
      },
  
      emailProofTokenExpiresAt: {
        type: 'number',
        description: 'A JS timestamp (epoch ms) representing the moment when this user\'s `emailProofToken` will expire (or 0 if the user currently has no such token).',
        example: 1502844074211
      },
  
      stripeCustomerId: {
        type: 'string',
        protect: true,
        description: 'The id of the customer entry in Stripe associated with this user (or empty string if this user is not linked to a Stripe customer -- e.g. if billing features are not enabled).',
        extendedDescription:
  `Just because this value is set doesn't necessarily mean that this user has a billing card.
  It just means they have a customer entry in Stripe, which might or might not have a billing card.`
      },
  
      hasBillingCard: {
        type: 'boolean',
        description: 'Whether this user has a default billing card hooked up as their payment method.',
        extendedDescription:
  `More specifically, this indcates whether this user record's linked customer entry in Stripe has
  a default payment source (i.e. credit card).  Note that a user have a \`stripeCustomerId\`
  without necessarily having a billing card.`
      },
  
      billingCardBrand: {
        type: 'string',
        example: 'Visa',
        description: 'The brand of this user\'s default billing card (or empty string if no billing card is set up).',
        extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
      },
  
      billingCardLast4: {
        type: 'string',
        example: '4242',
        description: 'The last four digits of the card number for this user\'s default billing card (or empty string if no billing card is set up).',
        extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
      },
  
      billingCardExpMonth: {
        type: 'string',
        example: '08',
        description: 'The two-digit expiration month from this user\'s default billing card, formatted as MM (or empty string if no billing card is set up).',
        extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
      },
  
      billingCardExpYear: {
        type: 'string',
        example: '2023',
        description: 'The four-digit expiration year from this user\'s default billing card, formatted as YYYY (or empty string if no credit card is set up).',
        extendedDescription: 'To ensure PCI compliance, this data comes from Stripe, where it reflects the user\'s default payment source.'
      },
  
      tosAcceptedByIp: {
        type: 'string',
        description: 'The IP (ipv4) address of the request that accepted the terms of service.',
        extendedDescription: 'Useful for certain types of businesses and regulatory requirements (KYC, etc.)',
        moreInfoUrl: 'https://en.wikipedia.org/wiki/Know_your_customer'
      },
  
      lastSeenAt: {
        type: 'number',
        description: 'A JS timestamp (epoch ms) representing the moment at which this user most recently interacted with the backend while logged in (or 0 if they have not interacted with the backend at all yet).',
        example: 1502844074211
      },
  
      //  ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
      //  ║╣ ║║║╠╩╗║╣  ║║╚═╗
      //  ╚═╝╩ ╩╚═╝╚═╝═╩╝╚═╝
      // n/a
  
      //  ╔═╗╔═╗╔═╗╔═╗╔═╗╦╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
      //  ╠═╣╚═╗╚═╗║ ║║  ║╠═╣ ║ ║║ ║║║║╚═╗
      //  ╩ ╩╚═╝╚═╝╚═╝╚═╝╩╩ ╩ ╩ ╩╚═╝╝╚╝╚═╝
      restaurant: { model: 'restaurant', required: true },
  
    },
  
  
  };
  