d95c62bad4
Remove 557-line server-design.md from _go-learning/architecture - content is now covered in updated architecture documentation with real implementation examples and test coverage.
26 KiB
26 KiB
Data Models Diagram
Data Model Overview
┌──────────────────────────────────────────────────────────────┐
│ Data Model Structure │
└──────────────────────────────────────────────────────────────┘
internal/models/
├── cv/ CV data structures
│ ├── cv.go Main CV model
│ ├── personal.go Personal information
│ ├── experience.go Work experience
│ ├── education.go Education history
│ ├── skills.go Technical skills
│ └── languages.go Language proficiency
│
└── ui/ UI text structures
├── ui.go Main UI model
├── sections.go Section titles
├── buttons.go Button labels
└── messages.go User messages
CV Data Model
┌──────────────────────────────────────────────────────────────┐
│ CV Structure (cv/cv.go) │
├──────────────────────────────────────────────────────────────┤
│ type CV struct { │
│ Personal Personal `json:"personal"` │
│ Summary string `json:"summary"` │
│ Experience []Experience `json:"experience"` │
│ Education []Education `json:"education"` │
│ Skills Skills `json:"skills"` │
│ Languages []Language `json:"languages"` │
│ } │
│ │
│ Methods: │
│ ├─ LoadCV(lang string) (*CV, error) │
│ │ └─→ Read data/cv-{lang}.json │
│ │ │
│ ├─ Validate() error │
│ │ └─→ Ensure all required fields present │
│ │ │
│ └─ CalculateDurations() │
│ └─→ Calculate years/months for experiences │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Personal Information (cv/personal.go) │
├──────────────────────────────────────────────────────────────┤
│ type Personal struct { │
│ Name string `json:"name"` │
│ Title string `json:"title"` │
│ Email string `json:"email"` │
│ Phone string `json:"phone,omitempty"` │
│ Location string `json:"location"` │
│ Website string `json:"website,omitempty"` │
│ LinkedIn string `json:"linkedin,omitempty"` │
│ GitHub string `json:"github,omitempty"` │
│ Photo string `json:"photo,omitempty"` │
│ } │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Work Experience (cv/experience.go) │
├──────────────────────────────────────────────────────────────┤
│ type Experience struct { │
│ Company string `json:"company"` │
│ Position string `json:"position"` │
│ Location string `json:"location"` │
│ StartDate string `json:"start_date"` │
│ EndDate string `json:"end_date,omitempty"` │
│ Current bool `json:"current"` │
│ Description string `json:"description"` │
│ Highlights []string `json:"highlights"` │
│ Duration string `json:"-"` // Calculated │
│ } │
│ │
│ Methods: │
│ ├─ CalculateDuration() string │
│ │ ├─ Parse StartDate and EndDate │
│ │ ├─ Calculate difference │
│ │ └─ Return: "2 years 3 months" or "Present" │
│ │ │
│ └─ IsCurrent() bool │
│ └─→ Check if EndDate is empty or Current flag │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Education (cv/education.go) │
├──────────────────────────────────────────────────────────────┤
│ type Education struct { │
│ Institution string `json:"institution"` │
│ Degree string `json:"degree"` │
│ Field string `json:"field"` │
│ Location string `json:"location"` │
│ StartDate string `json:"start_date"` │
│ EndDate string `json:"end_date,omitempty"` │
│ GPA string `json:"gpa,omitempty"` │
│ Honors []string `json:"honors,omitempty"` │
│ } │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Skills (cv/skills.go) │
├──────────────────────────────────────────────────────────────┤
│ type Skills struct { │
│ Technical []Skill `json:"technical"` │
│ Soft []Skill `json:"soft"` │
│ Tools []Skill `json:"tools"` │
│ } │
│ │
│ type Skill struct { │
│ Name string `json:"name"` │
│ Level string `json:"level,omitempty"` │
│ Icon string `json:"icon,omitempty"` │
│ Category string `json:"category,omitempty"` │
│ } │
│ │
│ Methods: │
│ └─ SplitIntoColumns(numCols int) [][]Skill │
│ └─→ Distribute skills evenly across columns │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Languages (cv/languages.go) │
├──────────────────────────────────────────────────────────────┤
│ type Language struct { │
│ Name string `json:"name"` │
│ Level string `json:"level"` │
│ Proficiency string `json:"proficiency,omitempty"` │
│ } │
│ │
│ Levels: Native, Fluent, Professional, Intermediate, Basic │
└──────────────────────────────────────────────────────────────┘
UI Data Model
┌──────────────────────────────────────────────────────────────┐
│ UI Structure (ui/ui.go) │
├──────────────────────────────────────────────────────────────┤
│ type UI struct { │
│ Sections Sections `json:"sections"` │
│ Buttons Buttons `json:"buttons"` │
│ Messages Messages `json:"messages"` │
│ Labels Labels `json:"labels"` │
│ } │
│ │
│ Methods: │
│ └─ LoadUI(lang string) (*UI, error) │
│ └─→ Read data/ui-{lang}.json │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Section Titles (ui/sections.go) │
├──────────────────────────────────────────────────────────────┤
│ type Sections struct { │
│ Summary string `json:"summary"` │
│ Experience string `json:"experience"` │
│ Education string `json:"education"` │
│ Skills string `json:"skills"` │
│ Languages string `json:"languages"` │
│ Contact string `json:"contact"` │
│ } │
│ │
│ Example (English): │
│ { │
│ "summary": "Professional Summary", │
│ "experience": "Work Experience", │
│ "education": "Education", │
│ "skills": "Technical Skills", │
│ "languages": "Languages", │
│ "contact": "Contact Information" │
│ } │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Button Labels (ui/buttons.go) │
├──────────────────────────────────────────────────────────────┤
│ type Buttons struct { │
│ ExportPDF string `json:"export_pdf"` │
│ ToggleLength string `json:"toggle_length"` │
│ ToggleIcons string `json:"toggle_icons"` │
│ ToggleTheme string `json:"toggle_theme"` │
│ ToggleLanguage string `json:"toggle_language"` │
│ Print string `json:"print"` │
│ } │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ User Messages (ui/messages.go) │
├──────────────────────────────────────────────────────────────┤
│ type Messages struct { │
│ Loading string `json:"loading"` │
│ Error string `json:"error"` │
│ Success string `json:"success"` │
│ PDFGenerating string `json:"pdf_generating"` │
│ PDFReady string `json:"pdf_ready"` │
│ } │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ Labels (ui/labels.go) │
├──────────────────────────────────────────────────────────────┤
│ type Labels struct { │
│ ShortCV string `json:"short_cv"` │
│ LongCV string `json:"long_cv"` │
│ ShowIcons string `json:"show_icons"` │
│ HideIcons string `json:"hide_icons"` │
│ Light string `json:"light"` │
│ Dark string `json:"dark"` │
│ } │
└──────────────────────────────────────────────────────────────┘
Data Flow
┌────────────────────────────────────────────────────────────┐
│ Data Flow │
└────────────────────────────────────────────────────────────┘
JSON Files (data/)
├── cv-en.json English CV data
├── cv-es.json Spanish CV data
├── ui-en.json English UI strings
└── ui-es.json Spanish UI strings
│
▼
┌─────────────────────────┐
│ LoadCV(lang) │
│ LoadUI(lang) │
│ (internal/models/) │
└─────────────────────────┘
│
├─→ Parse JSON
├─→ Validate structure
└─→ Return typed structs
│
▼
┌─────────────────────────┐
│ Handler │
│ (internal/handlers/) │
└─────────────────────────┐
│
├─→ Calculate durations
├─→ Split skills
└─→ Build template data map
│
▼
┌─────────────────────────┐
│ Template Rendering │
│ (templates/) │
└─────────────────────────┘
│
▼
HTML Response
Example Data Structure
┌────────────────────────────────────────────────────────────┐
│ Sample CV Data (data/cv-en.json) │
└────────────────────────────────────────────────────────────┘
{
"personal": {
"name": "John Doe",
"title": "Senior Software Engineer",
"email": "john@example.com",
"location": "San Francisco, CA",
"linkedin": "linkedin.com/in/johndoe",
"github": "github.com/johndoe"
},
"summary": "Experienced software engineer with 8+ years...",
"experience": [
{
"company": "Tech Corp",
"position": "Senior Software Engineer",
"location": "San Francisco, CA",
"start_date": "2020-01",
"end_date": "",
"current": true,
"description": "Leading backend development...",
"highlights": [
"Designed and implemented microservices architecture",
"Reduced API response time by 60%",
"Mentored 5 junior developers"
]
}
],
"education": [
{
"institution": "University of California",
"degree": "Bachelor of Science",
"field": "Computer Science",
"location": "Berkeley, CA",
"start_date": "2012-09",
"end_date": "2016-05",
"gpa": "3.8/4.0"
}
],
"skills": {
"technical": [
{"name": "Go", "level": "Expert", "icon": "golang"},
{"name": "JavaScript", "level": "Advanced", "icon": "js"},
{"name": "Python", "level": "Intermediate", "icon": "python"}
],
"tools": [
{"name": "Docker", "icon": "docker"},
{"name": "Kubernetes", "icon": "k8s"},
{"name": "Git", "icon": "git"}
]
},
"languages": [
{"name": "English", "level": "Native"},
{"name": "Spanish", "level": "Fluent"}
]
}
┌────────────────────────────────────────────────────────────┐
│ Sample UI Data (data/ui-en.json) │
└────────────────────────────────────────────────────────────┘
{
"sections": {
"summary": "Professional Summary",
"experience": "Work Experience",
"education": "Education",
"skills": "Technical Skills",
"languages": "Languages"
},
"buttons": {
"export_pdf": "Export PDF",
"toggle_length": "Toggle Length",
"toggle_icons": "Toggle Icons",
"toggle_theme": "Toggle Theme",
"toggle_language": "Switch Language"
},
"messages": {
"loading": "Loading...",
"error": "An error occurred",
"pdf_generating": "Generating PDF...",
"pdf_ready": "PDF is ready for download"
},
"labels": {
"short_cv": "Short",
"long_cv": "Long",
"show_icons": "Show Icons",
"hide_icons": "Hide Icons"
}
}
Data Validation
┌────────────────────────────────────────────────────────────┐
│ Validation Rules │
└────────────────────────────────────────────────────────────┘
CV Validation:
├─ Personal
│ ├─ Name: Required, non-empty
│ ├─ Title: Required, non-empty
│ ├─ Email: Required, valid email format
│ └─ Location: Required, non-empty
│
├─ Experience
│ ├─ Company: Required, non-empty
│ ├─ Position: Required, non-empty
│ ├─ StartDate: Required, valid date (YYYY-MM)
│ └─ EndDate: Optional, must be after StartDate if present
│
├─ Education
│ ├─ Institution: Required, non-empty
│ ├─ Degree: Required, non-empty
│ └─ Field: Required, non-empty
│
├─ Skills
│ ├─ Name: Required, non-empty
│ └─ Level: Optional, one of [Basic, Intermediate, Advanced, Expert]
│
└─ Languages
├─ Name: Required, non-empty
└─ Level: Required, one of [Native, Fluent, Professional, Intermediate, Basic]
UI Validation:
├─ All section titles: Required, non-empty
├─ All button labels: Required, non-empty
└─ All messages: Required, non-empty
Model Lifecycle
┌────────────────────────────────────────────────────────────┐
│ Model Lifecycle │
└────────────────────────────────────────────────────────────┘
Application Start
│
└─→ Models NOT loaded (lazy loading)
│
▼
Request Arrives (lang=es)
│
├─→ Handler calls LoadCV("es")
│ ├─ Check cache (if caching enabled)
│ ├─ Read data/cv-es.json
│ ├─ Parse JSON → CV struct
│ ├─ Validate struct
│ └─ Return *CV
│
├─→ Handler calls LoadUI("es")
│ ├─ Read data/ui-es.json
│ ├─ Parse JSON → UI struct
│ └─ Return *UI
│
└─→ Handler processes data
├─ Calculate durations
├─ Split skills
└─ Render template
Next Request (lang=es)
│
└─→ Models reloaded (no persistent cache)
(Each request loads fresh data for hot reload)
Data Transformation
┌────────────────────────────────────────────────────────────┐
│ Data Transformation Pipeline │
└────────────────────────────────────────────────────────────┘
JSON (static)
│
├─ "start_date": "2020-01"
└─ "end_date": ""
│
▼
Go Struct (typed)
│
├─ StartDate: "2020-01"
├─ EndDate: ""
└─ Duration: "" (empty)
│
▼
Calculate Duration
│
├─ Parse dates
├─ Calculate difference
└─ Format: "3 years 2 months"
│
▼
Template Data (enriched)
│
├─ StartDate: "2020-01"
├─ EndDate: "Present"
└─ Duration: "3 years 2 months"
│
▼
HTML (rendered)
│
└─ <span class="duration">3 years 2 months</span>
Related Diagrams
- System Architecture - Overall system design
- Request Flow - HTTP request lifecycle
- Template Rendering - Template processing