Skip to main content

Overview

CV Builder uses a strongly-typed data structure defined in lib/types.ts. All resume data is stored as a single CVData object containing personal information, experience, education, and other sections.

Core Data Type

The main data structure that represents a complete resume:
lib/types.ts
export interface CVData {
  personalInfo: PersonalInfo;
  experience: Experience[];
  education: Education[];
  projects: Project[];
  achievements: Achievement[];
  languages: Language[];
  skills: Skill[];
  sectionOrder: SectionId[];
  references: string;
  hiddenSections: SectionId[];
  template?: TemplateId;
}
personalInfo
PersonalInfo
required
User’s personal contact information and profile
experience
Experience[]
required
Array of work experience entries
education
Education[]
required
Array of education entries
projects
Project[]
required
Array of personal or professional projects
achievements
Achievement[]
required
Array of awards, certifications, or achievements
languages
Language[]
required
Array of languages with proficiency levels
skills
Skill[]
required
Array of technical and professional skills
sectionOrder
SectionId[]
required
Order in which sections appear in the resume
references
string
required
References text (e.g., “Available upon request”)
hiddenSections
SectionId[]
required
Sections hidden from preview and PDF export
template
TemplateId
Selected resume template (‘default’ | ‘rhyhorn’ | ‘nexus’)

Section Types

PersonalInfo

Personal contact information and profile:
lib/types.ts
export interface PersonalInfo {
  fullName: string;
  email: string;
  phone: string;
  address: string;
  jobTitle: string;
  summary: string;
  website?: string;
  linkedin?: string;
  github?: string;
  profileImageUrl?: string;
}
fullName
string
required
Full name of the person
email
string
required
Email address
phone
string
required
Phone number
address
string
required
Physical address or location
jobTitle
string
required
Current or desired job title
summary
string
required
Professional summary or bio
website
string
Personal website URL
linkedin
string
LinkedIn profile URL
github
string
GitHub profile URL
profileImageUrl
string
URL to profile image (Firebase Storage URL)

Experience

Work experience entries:
lib/types.ts
export interface Experience {
  id: string;
  company: string;
  role: string;
  startDate: string;
  endDate: string;
  current: boolean;
  description: string;
}
id
string
required
Unique identifier (generated with nanoid)
company
string
required
Company or organization name
role
string
required
Job title or position
startDate
string
required
Start date (ISO string or formatted)
endDate
string
required
End date (ISO string or formatted)
current
boolean
required
Whether this is the current position
description
string
required
Job responsibilities and achievements

Education

Education entries:
lib/types.ts
export interface Education {
  id: string;
  school: string;
  degree: string;
  startDate: string;
  endDate: string;
  description: string;
}
id
string
required
Unique identifier
school
string
required
School or institution name
degree
string
required
Degree or qualification obtained
startDate
string
required
Start date
endDate
string
required
End date or expected graduation
description
string
required
Additional details, honors, or coursework

Project

Project entries:
lib/types.ts
export interface Project {
  id: string;
  title: string;
  date: string;
  techStack: string; // "Skill: React, ..."
  description: string;
}
id
string
required
Unique identifier
title
string
required
Project name
date
string
required
Project date or date range
techStack
string
required
Technologies used (comma-separated)
description
string
required
Project description and outcomes

Achievement

Award or achievement entries:
lib/types.ts
export interface Achievement {
  id: string;
  title: string;
  organization: string;
  date: string;
}
id
string
required
Unique identifier
title
string
required
Achievement or award title
organization
string
required
Issuing organization
date
string
required
Date received

Language

Language proficiency entries:
lib/types.ts
export interface Language {
  id: string;
  name: string;
  proficiency: string; // "Native", "Fluent", etc.
}
id
string
required
Unique identifier
name
string
required
Language name
proficiency
string
required
Proficiency level (e.g., “Native”, “Fluent”, “Intermediate”)

Skill

Skill entries:
lib/types.ts
export interface Skill {
  id: string;
  name: string;
  description?: string; // The skill values like "C, C++, Java, Python"
  category?: 'technical' | 'professional';
}
id
string
required
Unique identifier
name
string
required
Skill category name
description
string
Comma-separated list of specific skills
category
'technical' | 'professional'
Skill category type

Section Management

SectionId Type

Available resume sections:
lib/types.ts
export type SectionId =
  | "personal"
  | "experience"
  | "education"
  | "projects"
  | "achievements"
  | "languages"
  | "skills"
  | "references";

Default Section Order

lib/types.ts
export const defaultSectionOrder: SectionId[] = [
  "personal",
  "skills",
  "experience",
  "education",
  "projects",
  "achievements",
  "languages",
  "references",
];

Version Control Types

CVVersion

Saved version of a resume:
lib/types.ts
export interface CVVersion {
  id: string;
  userId: string;
  data: CVData;
  versionName: string;
  description?: string;
  tags?: string[];
  createdAt: Date;
  isAutoSave: boolean;
}

CVDocument

Firestore document structure:
lib/types.ts
export interface CVDocument {
  data: CVData;
  updatedAt: Date;
  createdAt: Date;
  currentVersionId?: string;
}

Merge Types

Types used for conflict resolution during sync:

FieldConflict

lib/types.ts
export interface FieldConflict {
  section: SectionId | 'sectionOrder' | 'hiddenSections' | 'template' | 'references';
  field?: string;  // For nested fields like personalInfo.fullName, or item ID for arrays
  localValue: unknown;
  serverValue: unknown;
  baseValue: unknown;
  description?: string; // Human-readable description of the conflict
}
section
string
required
Section where the conflict occurred
field
string
Specific field name or item ID
localValue
unknown
required
Value from local (browser) storage
serverValue
unknown
required
Value from Firebase server
baseValue
unknown
required
Value from last sync (common ancestor)
description
string
Human-readable conflict description

MergeResult

lib/types.ts
export interface MergeResult {
  merged: CVData;
  conflicts: FieldConflict[];
  hasConflicts: boolean;
}
merged
CVData
required
Merged resume data
conflicts
FieldConflict[]
required
Array of detected conflicts
hasConflicts
boolean
required
Whether any conflicts were detected

Initial Data

The default empty resume structure:
lib/types.ts
export const initialCVData: CVData = {
  personalInfo: {
    fullName: "",
    email: "",
    phone: "",
    address: "",
    jobTitle: "",
    summary: "",
    linkedin: "",
    github: "",
    website: "",
    profileImageUrl: "",
  },
  experience: [],
  education: [],
  projects: [],
  achievements: [],
  languages: [],
  skills: [],
  sectionOrder: [...defaultSectionOrder],
  references: "Available upon request.",
  hiddenSections: [],
  template: 'default',
};

Usage Example

import { CVData, initialCVData } from '@/lib/types';

// Create a new resume
const myResume: CVData = {
  ...initialCVData,
  personalInfo: {
    ...initialCVData.personalInfo,
    fullName: "John Doe",
    email: "[email protected]",
    jobTitle: "Software Engineer",
  },
  experience: [
    {
      id: "exp_1",
      company: "Tech Corp",
      role: "Senior Developer",
      startDate: "2020-01",
      endDate: "2024-03",
      current: true,
      description: "Led development of core features",
    },
  ],
};

Build docs developers (and LLMs) love