# Epic Technical Specification: Resume Data & Types Date: 2025-11-30 Author: mahdi Epic ID: 1 Status: Draft --- ## Overview Epic 1 establishes the data foundation for the Resume Export feature. This epic creates TypeScript interfaces based on the JSON Resume schema (modified), implements a sample resume data file with realistic content, and provides a composable for reactive data access throughout the application. This is a foundational epic with no UI components - it provides the typed data layer that Epic 2 (Preview Page) and Epic 3 (PDF Export) will consume. ## Objectives and Scope ### In Scope - TypeScript interfaces for all resume sections (basics, work, education, skills, languages, certifications) - Sample resume data file with Ali Arghyani's information - Composable for data access with helper functions (date formatting, filename generation) - Type exports for use in Vue components ### Out of Scope - UI components (Epic 2) - PDF generation (Epic 3) - Persian language resume data (Growth feature) - Database storage (file-based only) - API endpoints for resume data ## System Architecture Alignment ### Components Referenced | Component | Purpose | Architecture Section | |-----------|---------|---------------------| | `app/types/resume.ts` | TypeScript interfaces | Data Architecture | | `app/data/resume.en.ts` | English resume data | Data Architecture | | `app/composables/useResumeData.ts` | Data access layer | Implementation Patterns | ### Constraints - Must follow JSON Resume schema (modified) as defined in Architecture doc - Data must be independent from existing portfolio data - Must support future language extension (file naming: `resume.{locale}.ts`) - Must use existing project patterns (composables, TypeScript strict mode) ## Detailed Design ### Services and Modules | Module | Responsibility | Inputs | Outputs | |--------|---------------|--------|---------| | `types/resume.ts` | Type definitions | None | TypeScript interfaces | | `data/resume.en.ts` | Data storage | None | `Resume` object | | `composables/useResumeData.ts` | Data access | None | Reactive refs + helpers | ### Data Models and Contracts ```typescript // app/types/resume.ts export interface ResumeBasics { name: string label: string // Job title email: string phone: string url?: string location: { city: string country: string } profiles: Array<{ network: string // LinkedIn, GitHub, etc. url: string icon?: string // Iconify icon name }> summary: string } export interface WorkExperience { company: string position: string startDate: string // YYYY-MM format endDate?: string // YYYY-MM or undefined for "Present" highlights: string[] // Bullet points } export interface Education { institution: string area: string // Field of study studyType: string // Degree type startDate: string endDate?: string } export interface Skill { name: string // Category name keywords: string[] // Individual skills } export interface Language { language: string fluency: 'Native' | 'Fluent' | 'Intermediate' | 'Basic' } export interface Certification { name: string issuer: string date: string } export interface Resume { basics: ResumeBasics work: WorkExperience[] education: Education[] skills: Skill[] languages?: Language[] certifications?: Certification[] } ``` ### APIs and Interfaces **Composable Interface:** ```typescript // app/composables/useResumeData.ts export function useResumeData() { // Returns: resume: ComputedRef // Reactive resume data formatDate(date: string): string // "2023-01" → "Jan 2023" getFullName(): string // "Ali Arghyani" getPdfFilename(): string // "Ali_Arghyani_Resume.pdf" } ``` ### Workflows and Sequencing ``` Story 1.1: Create Types ↓ Story 1.2: Create Sample Data (imports types) ↓ Story 1.3: Create Composable (imports data) ↓ Epic 2: Preview Components (uses composable) ``` ## Non-Functional Requirements ### Performance | Metric | Target | Rationale | |--------|--------|-----------| | Type checking | < 1s | Part of build process | | Data import | Instant | Static import, no async | | Composable init | < 1ms | Simple computed refs | ### Security - No PII in committed code (sample data uses placeholder info) - Resume data is read-only (no mutations) - No external API calls for data ### Reliability/Availability - Static data - 100% availability - No runtime dependencies - TypeScript ensures compile-time safety ### Observability - TypeScript errors surface at build time - No runtime logging needed for data layer ## Dependencies and Integrations ### Existing Dependencies (No new packages required) | Package | Version | Purpose | |---------|---------|---------| | typescript | ^5.9.x | Type definitions | | vue | ^3.5.x | Composable reactivity | | nuxt | ^4.1.x | Auto-imports | ### Integration Points | Integration | Direction | Notes | |-------------|-----------|-------| | Epic 2 Components | Downstream | Components consume `useResumeData()` | | Epic 3 PDF API | Downstream | API uses data for filename | ## Acceptance Criteria (Authoritative) ### Story 1.1: Create Resume TypeScript Interfaces | AC ID | Criteria | Testable | |-------|----------|----------| | AC-1.1.1 | File exists at `app/types/resume.ts` | ✓ | | AC-1.1.2 | `ResumeBasics` interface includes: name, label, email, phone, url?, location, profiles, summary | ✓ | | AC-1.1.3 | `WorkExperience` interface includes: company, position, startDate, endDate?, highlights | ✓ | | AC-1.1.4 | `Education` interface includes: institution, area, studyType, startDate, endDate? | ✓ | | AC-1.1.5 | `Skill` interface includes: name, keywords[] | ✓ | | AC-1.1.6 | `Language` interface includes: language, fluency (union type) | ✓ | | AC-1.1.7 | `Certification` interface includes: name, issuer, date | ✓ | | AC-1.1.8 | `Resume` interface combines all above with optional languages/certifications | ✓ | | AC-1.1.9 | All date fields use YYYY-MM string format | ✓ | | AC-1.1.10 | All interfaces are exported | ✓ | ### Story 1.2: Create Sample Resume Data File | AC ID | Criteria | Testable | |-------|----------|----------| | AC-1.2.1 | File exists at `app/data/resume.en.ts` | ✓ | | AC-1.2.2 | Exports `resumeData` of type `Resume` | ✓ | | AC-1.2.3 | Contains full name and job title | ✓ | | AC-1.2.4 | Contains contact info (email, phone, location) | ✓ | | AC-1.2.5 | Contains at least 2 social profiles with icons | ✓ | | AC-1.2.6 | Contains professional summary (2-3 sentences) | ✓ | | AC-1.2.7 | Contains at least 2 work experiences with 3+ highlights each | ✓ | | AC-1.2.8 | Contains at least 1 education entry | ✓ | | AC-1.2.9 | Contains at least 2 skill categories with 4+ keywords each | ✓ | | AC-1.2.10 | Contains at least 2 languages | ✓ | | AC-1.2.11 | Data is independent from portfolio data | ✓ | ### Story 1.3: Create Resume Data Composable | AC ID | Criteria | Testable | |-------|----------|----------| | AC-1.3.1 | File exists at `app/composables/useResumeData.ts` | ✓ | | AC-1.3.2 | Exports `useResumeData()` function | ✓ | | AC-1.3.3 | Returns `resume` as reactive reference | ✓ | | AC-1.3.4 | Returns `formatDate()` that converts "2023-01" to "Jan 2023" | ✓ | | AC-1.3.5 | Returns `getFullName()` that returns full name | ✓ | | AC-1.3.6 | Returns `getPdfFilename()` that returns "FirstName_LastName_Resume.pdf" | ✓ | ## Traceability Mapping | AC | FR | Spec Section | Component | Test Idea | |----|-----|--------------|-----------|-----------| | AC-1.1.1-10 | FR1, FR2 | Data Models | `types/resume.ts` | TypeScript compilation | | AC-1.2.1-11 | FR1, FR2, FR3, FR4 | Data Models | `data/resume.en.ts` | Type check + content validation | | AC-1.3.1-6 | FR1 | APIs/Interfaces | `composables/useResumeData.ts` | Unit test composable | ## Risks, Assumptions, Open Questions ### Risks | Risk | Impact | Mitigation | |------|--------|------------| | Sample data doesn't match real user needs | Low | Easy to modify file | | Type changes break downstream | Medium | Strict typing catches at compile | ### Assumptions - Developer will replace sample data with real resume content - English locale is sufficient for MVP - JSON Resume schema modifications are acceptable ### Open Questions - None - Epic 1 is well-defined ## Test Strategy Summary ### Test Levels | Level | Scope | Approach | |-------|-------|----------| | Static | Types | TypeScript compiler | | Unit | Composable | Vitest (if needed) | | Integration | Data flow | Manual verification | ### Coverage - All interfaces compile without errors - Sample data passes type checking - Composable functions return expected values ### Edge Cases - Empty arrays (work, education, skills) - Missing optional fields (url, endDate, certifications) - Date formatting edge cases (invalid format)