jsonresume / resume-schema

JSON-Schema is used here to define and validate our proposed resume json
http://jsonresume.org
MIT License
2.15k stars 278 forks source link

Relaxed requirements for JSON resume #482

Closed JohnScience closed 5 months ago

JohnScience commented 5 months ago

At Searchless, we were planning to use JSON schema standard but found out that its requirements are too strict for conversion from regular resume to JSON resume.

The current schema

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "additionalProperties": false,
  "definitions": {
    "iso8601": {
      "type": "string",
      "description": "Similar to the standard date type, but each section after the year is optional. e.g. 2014-06-29 or 2023-04",
      "pattern": "^([1-2][0-9]{3}-[0-1][0-9]-[0-3][0-9]|[1-2][0-9]{3}-[0-1][0-9]|[1-2][0-9]{3})$"
    }
  },
  "properties": {
    "$schema": {
      "type": "string",
      "description": "link to the version of the schema that can validate the resume",
      "format": "uri"
    },
    "basics": {
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "name": {
          "type": "string"
        },
        "label": {
          "type": "string",
          "description": "e.g. Web Developer"
        },
        "image": {
          "type": "string",
          "description": "URL (as per RFC 3986) to a image in JPEG or PNG format"
        },
        "email": {
          "type": "string",
          "description": "e.g. thomas@gmail.com",
          "format": "email"
        },
        "phone": {
          "type": "string",
          "description": "Phone numbers are stored as strings so use any format you like, e.g. 712-117-2923"
        },
        "url": {
          "type": "string",
          "description": "URL (as per RFC 3986) to your website, e.g. personal homepage",
          "format": "uri"
        },
        "summary": {
          "type": "string",
          "description": "Write a short 2-3 sentence biography about yourself"
        },
        "location": {
          "type": "object",
          "additionalProperties": true,
          "properties": {
            "address": {
              "type": "string",
              "description": "To add multiple address lines, use \n. For example, 1234 Glücklichkeit Straße\nHinterhaus 5. Etage li."
            },
            "postalCode": {
              "type": "string"
            },
            "city": {
              "type": "string"
            },
            "countryCode": {
              "type": "string",
              "description": "code as per ISO-3166-1 ALPHA-2, e.g. US, AU, IN"
            },
            "region": {
              "type": "string",
              "description": "The general region where you live. Can be a US state, or a province, for instance."
            }
          }
        },
        "profiles": {
          "type": "array",
          "description": "Specify any number of social networks that you participate in",
          "additionalItems": false,
          "items": {
            "type": "object",
            "additionalProperties": true,
            "properties": {
              "network": {
                "type": "string",
                "description": "e.g. Facebook or Twitter"
              },
              "username": {
                "type": "string",
                "description": "e.g. neutralthoughts"
              },
              "url": {
                "type": "string",
                "description": "e.g. http://twitter.example.com/neutralthoughts",
                "format": "uri"
              }
            }
          }
        }
      }
    },
    "work": {
      "type": "array",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "e.g. Facebook"
          },
          "location": {
            "type": "string",
            "description": "e.g. Menlo Park, CA"
          },
          "description": {
            "type": "string",
            "description": "e.g. Social Media Company"
          },
          "position": {
            "type": "string",
            "description": "e.g. Software Engineer"
          },
          "url": {
            "type": "string",
            "description": "e.g. http://facebook.example.com",
            "format": "uri"
          },
          "startDate": {
            "$ref": "#/definitions/iso8601"
          },
          "endDate": {
            "$ref": "#/definitions/iso8601"
          },
          "summary": {
            "type": "string",
            "description": "Give an overview of your responsibilities at the company"
          },
          "highlights": {
            "type": "array",
            "description": "Specify multiple accomplishments",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. Increased profits by 20% from 2011-2012 through viral advertising"
            }
          }
        }
      }
    },
    "volunteer": {
      "type": "array",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "organization": {
            "type": "string",
            "description": "e.g. Facebook"
          },
          "position": {
            "type": "string",
            "description": "e.g. Software Engineer"
          },
          "url": {
            "type": "string",
            "description": "e.g. http://facebook.example.com",
            "format": "uri"
          },
          "startDate": {
            "$ref": "#/definitions/iso8601"
          },
          "endDate": {
            "$ref": "#/definitions/iso8601"
          },
          "summary": {
            "type": "string",
            "description": "Give an overview of your responsibilities at the company"
          },
          "highlights": {
            "type": "array",
            "description": "Specify accomplishments and achievements",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. Increased profits by 20% from 2011-2012 through viral advertising"
            }
          }
        }
      }
    },
    "education": {
      "type": "array",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "institution": {
            "type": "string",
            "description": "e.g. Massachusetts Institute of Technology"
          },
          "url": {
            "type": "string",
            "description": "e.g. http://facebook.example.com",
            "format": "uri"
          },
          "area": {
            "type": "string",
            "description": "e.g. Arts"
          },
          "studyType": {
            "type": "string",
            "description": "e.g. Bachelor"
          },
          "startDate": {
            "$ref": "#/definitions/iso8601"
          },
          "endDate": {
            "$ref": "#/definitions/iso8601"
          },
          "score": {
            "type": "string",
            "description": "grade point average, e.g. 3.67/4.0"
          },
          "courses": {
            "type": "array",
            "description": "List notable courses/subjects",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. H1302 - Introduction to American history"
            }
          }
        }
      }
    },
    "awards": {
      "type": "array",
      "description": "Specify any awards you have received throughout your professional career",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "title": {
            "type": "string",
            "description": "e.g. One of the 100 greatest minds of the century"
          },
          "date": {
            "$ref": "#/definitions/iso8601"
          },
          "awarder": {
            "type": "string",
            "description": "e.g. Time Magazine"
          },
          "summary": {
            "type": "string",
            "description": "e.g. Received for my work with Quantum Physics"
          }
        }
      }
    },
    "certificates": {
      "type": "array",
      "description": "Specify any certificates you have received throughout your professional career",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "e.g. Certified Kubernetes Administrator"
          },
          "date": {
            "$ref": "#/definitions/iso8601"
          },
          "url": {
            "type": "string",
            "description": "e.g. http://example.com",
            "format": "uri"
          },
          "issuer": {
            "type": "string",
            "description": "e.g. CNCF"
          }
        }
      }
    },
    "publications": {
      "type": "array",
      "description": "Specify your publications through your career",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "e.g. The World Wide Web"
          },
          "publisher": {
            "type": "string",
            "description": "e.g. IEEE, Computer Magazine"
          },
          "releaseDate": {
            "$ref": "#/definitions/iso8601"
          },
          "url": {
            "type": "string",
            "description": "e.g. http://www.computer.org.example.com/csdl/mags/co/1996/10/rx069-abs.html",
            "format": "uri"
          },
          "summary": {
            "type": "string",
            "description": "Short summary of publication. e.g. Discussion of the World Wide Web, HTTP, HTML."
          }
        }
      }
    },
    "skills": {
      "type": "array",
      "description": "List out your professional skill-set",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "e.g. Web Development"
          },
          "level": {
            "type": "string",
            "description": "e.g. Master"
          },
          "keywords": {
            "type": "array",
            "description": "List some keywords pertaining to this skill",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. HTML"
            }
          }
        }
      }
    },
    "languages": {
      "type": "array",
      "description": "List any other languages you speak",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "language": {
            "type": "string",
            "description": "e.g. English, Spanish"
          },
          "fluency": {
            "type": "string",
            "description": "e.g. Fluent, Beginner"
          }
        }
      }
    },
    "interests": {
      "type": "array",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "e.g. Philosophy"
          },
          "keywords": {
            "type": "array",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. Friedrich Nietzsche"
            }
          }
        }
      }
    },
    "references": {
      "type": "array",
      "description": "List references you have received",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "e.g. Timothy Cook"
          },
          "reference": {
            "type": "string",
            "description": "e.g. Joe blogs was a great employee, who turned up to work at least once a week. He exceeded my expectations when it came to doing nothing."
          }
        }
      }
    },
    "projects": {
      "type": "array",
      "description": "Specify career projects",
      "additionalItems": false,
      "items": {
        "type": "object",
        "additionalProperties": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "e.g. The World Wide Web"
          },
          "description": {
            "type": "string",
            "description": "Short summary of project. e.g. Collated works of 2017."
          },
          "highlights": {
            "type": "array",
            "description": "Specify multiple features",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. Directs you close but not quite there"
            }
          },
          "keywords": {
            "type": "array",
            "description": "Specify special elements involved",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. AngularJS"
            }
          },
          "startDate": {
            "$ref": "#/definitions/iso8601"
          },
          "endDate": {
            "$ref": "#/definitions/iso8601"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "e.g. http://www.computer.org/csdl/mags/co/1996/10/rx069-abs.html"
          },
          "roles": {
            "type": "array",
            "description": "Specify your role on this project or in company",
            "additionalItems": false,
            "items": {
              "type": "string",
              "description": "e.g. Team Lead, Speaker, Writer"
            }
          },
          "entity": {
            "type": "string",
            "description": "Specify the relevant company/entity affiliations e.g. 'greenpeace', 'corporationXYZ'"
          },
          "type": {
            "type": "string",
            "description": " e.g. 'volunteering', 'presentation', 'talk', 'application', 'conference'"
          }
        }
      }
    },
    "meta": {
      "type": "object",
      "description": "The schema version and any other tooling configuration lives here",
      "additionalProperties": true,
      "properties": {
        "canonical": {
          "type": "string",
          "description": "URL (as per RFC 3986) to latest version of this document",
          "format": "uri"
        },
        "version": {
          "type": "string",
          "description": "A version field which follows semver - e.g. v1.0.0"
        },
        "lastModified": {
          "type": "string",
          "description": "Using ISO 8601 with YYYY-MM-DDThh:mm:ss"
        }
      }
    }
  },
  "title": "Resume Schema",
  "type": "object"
}

rejects the following substandard "JSON resume" for multiple reasons:

{
  "basics": {
    "name": "Evan Agamabiche",
    "label": null,
    "image": null,
    "email": "evanagamabiche@yahoo.ca",
    "phone": "(416) 989-9898",
    "url": null,
    "summary": "Friendly, enthusiastic and upbeat high school graduate seeking a position as a Summer Camp Counsellor",
    "location": {
      "address": "456 Shallow Lake Crescent",
      "postalCode": "L6X 7Y8",
      "city": "Brampton, ON",
      "countryCode": "CA",
      "region": null
    },
    "profiles": []
  },
  "work": [],
  "volunteer": [
    {
      "organization": "The Dance Ability Movement, Mississauga, Ontario",
      "position": null,
      "url": null,
      "startDate": "2015",
      "endDate": "Present",
      "summary": "Providing support and mentorship for young dancers with special needs, and enhancing my ability to communicate sensitively with individuals experiencing communication, physical or social anxiety challenges",
      "highlights": ["Consistently commended by parents and dance instructors for my patience, reliability and ability to help dancers feel at ease"]
    }
  ],
  "education": [
    {
      "institution": "York University, Toronto, Ontario",
      "url": null,
      "area": null,
      "studyType": "Honours Bachelor of Fine Arts in Dance & Theatre Arts",
      "startDate": null,
      "endDate": "2020",
      "score": null,
      "courses": null
    },
    {
      "institution": "Mayfield Secondary School, Caledon, Ontario",
      "url": null,
      "area": null,
      "studyType": "Ontario Secondary School Diploma",
      "startDate": null,
      "endDate": "2016",
      "score": null,
      "courses": null
    }
  ],
  "awards": [],
  "certificates": [],
  "publications": [],
  "skills": [],
  "languages": [],
  "interests": [],
  "references": [],
  "projects": [],
  "meta": {
    "canonical": null,
    "version": null,
    "lastModified": null
  }
}

It was generated by our in-house tools from https://careers.yorku.ca/files/2017/04/Sample-Resume-1st-Year-No-Work-Experience.pdf. There are many problems with it.

If we run the checks of https://www.jsonschemavalidator.net/ against it, we'll see that there are 20 errors.

What's the main problem? nulls are necessary to represent real-world resumes. However, the schema technically does not allow for null values.

I propose to also have the "relaxed" variant of JSON resume schema with values permitting nulls.

JohnScience commented 5 months ago

Changes and non-changes

Non-change: In my opinion, a resume without the candidate's name probably should not be considered a resume.

Change: "type": "string" => "type": ["string", "null"]. Comment: Generic resumes exist.

Change: "type": "string" => "type": ["string", "null"]. Comment: Presence of a photo in the resume is already debatable. Probably, this field should be optional in the stricter version of JSON resume standard as well.

Non-change: Emails are so ubiquitous today that it's hard to imagine a situation where the resume without email would make sense.

Change: "type": "string" => "type": ["string", "null"]. Comment: Websites like Monster are known to be constantly scanned for phone numbers by scam callers. This resulted in some people keeping their phones off the resumes.

Change: "type": "string" => "type": ["string", "null"]. Comment: While most people might have a personal page (on Mastodon/FB/Instagram), it may make no sense to have it in the resume.

P.S.

WORK IN PROGRESS

thomasdavis commented 5 months ago

I had similar thoughts just yesterday https://github.com/jsonresume/jsonresume.org/issues/118

Will have a think and leave some thoughts later today

JohnScience commented 5 months ago

While drafting a new schema, I realized that type: "object" by default has implication that its fields can be omitted. Therefore, absence of a field (such as an endDate) is not an error.

thomasdavis commented 5 months ago

Yeah omission and additives should be fine.

JohnScience commented 5 months ago

Then my use case doesn't need any changes to the schema. Sorry for bothering you!

thomasdavis commented 5 months ago

Awesome @JohnScience

I am about to give some love to the schema repo, so let me know if you reach any other hurdles and we will try to sort out a solution.

You will likely outgrow the schema, but we are very much in support of super/sub sets.

There is also the meta property which allows for object for supplemental data.