Realistic people and customers

Customer tables, user sign-ups and CRM imports all need people. This guide shows three ways to make them, from flat columns to one consistent object.

Flat columns in the user's language

Names, cities and streets follow output.language. With por you get Portuguese spellings, Brazilian documents and phone numbers:

clientes.yaml
version: "1"
output: { language: por, format: csv, quantity: 3 }
fields:
  - { name: nome, type: text, category: fullName }
  - { name: cpf, type: identifier, kind: cpf, formatted: true }
  - { name: celular, type: phone, formatted: true }
  - { name: cidade, type: text, category: city }
  - { name: cep, type: postcode, country: BR }
  - { name: nascimento, type: date, min: "1960-01-01", max: "2006-12-31" }
ghostbakery-output.csv
nome,cpf,celular,cidade,cep,nascimento
Priscila Gomes,277.599.066-50,(58) 96818-4101,Faro,76689-878,1988-12-28
Manuela Santos,212.441.620-00,(71) 98293-6966,Lisboa,98971-148,1996-04-30
Nuno Magalhães,384.575.708-62,(48) 90779-2149,Maceió,81907-233,1994-01-15

Each column is right on its own — the CPFs pass check-digit validation — but the columns do not know about each other: the city list covers the Portuguese-speaking world, and the postcode and area code are not the city's. For forms and imports that validate each field, that is what you want. Do not use it to test geocoding.

Useful categories for people: firstName, middleName, lastName, fullName, namePrefix, nameSuffix, gender, company, street, city. See Text categories.

One consistent person

A person field produces all of a person's details together: the e-mail is built from the name, and the prefix follows the gender.

profiles.yaml
version: "1"
output: { language: eng, format: json, quantity: 2, options: { pretty: true } }
fields:
  - { name: id, type: uuid }
  - { name: profile, type: person, fields: [namePrefix, fullName, gender, age, email] }
ghostbakery-output.json
[
  {
    "id": "91c8f198-9f81-4929-a431-a105bf05cd37",
    "profile": {
      "age": 40,
      "email": "donald.scott@example.com",
      "fullName": "Donald Scott",
      "gender": "male",
      "namePrefix": "Mr."
    }
  },
  
]

fields picks and orders the subfields; without it you get firstName, lastName, fullName, age and email. contact works the same way for e-mail, phone and address. In CSV and other flat formats, these objects are written as JSON text in one cell.

For consistent flat columns, tie the fields together yourself, as the quickstart does: firstName and lastName fields, then an email template built from them.

ASCII for legacy systems

Some systems still reject ß or ã. Add ascii: true and names switch to their romanized form:

ascii.yaml
version: "1"
output: { language: deu, format: csv, quantity: 3 }
fields:
  - { name: name, type: text, category: fullName, ascii: true }   # Köhler -> Koehler
  - { name: street, type: text, category: street }                # stays Schlossstraße

email, username, slug and domain names are always romanized, whatever the language.

Tips

  • Use unique: true on the column your system treats as a key — e-mail, username, document. With very large quantities, a type can run out of distinct values; the job then fails instead of repeating one.
  • Add emptyRate to optional columns, so your code sees missing values too: { name: middle_name, type: text, category: middleName, emptyRate: 0.6 }.
  • Generated people are synthetic: any resemblance to a real person is chance. Never put real personal data in a recipe.