Skip to content

Commit d0b6e96

Browse files
emmanuelperuclaude
andauthored
feat(model): add reference in cv model (#86)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 94d981f commit d0b6e96

File tree

9 files changed

+191
-2
lines changed

9 files changed

+191
-2
lines changed

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test.pdf
1717
/generated-test-*/
1818

1919
# Themes
20-
/themes/
20+
/themes/*
2121

2222
# Generated directory
2323
/generated/
@@ -61,3 +61,9 @@ docs/github-pages/yarn-error.log*
6161
/event.json
6262
/events.json
6363
/act.log
64+
65+
#Intellij
66+
.idea
67+
68+
#Code Assist
69+
.claude

cv.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,22 @@ education:
488488
location: Lens, France
489489
dates: 2019 - 2014
490490
link: https://ig2i.centralelille.fr
491+
492+
references:
493+
- name: Jane Doe
494+
position: CTO
495+
company: TechCorp
496+
date: Jan 2024
497+
url: https://linkedin.com/in/janedoe
498+
socialNetworks:
499+
linkedin: janedoe
500+
github: janedoe-gh
501+
description: "Germain est un excellent ingénieur, très compétent sur les sujets DevOps et Kubernetes. Je recommande vivement !"
502+
- name: John Smith
503+
position: Lead Developer
504+
company: WebSolutions
505+
date: Dec 2023
506+
url: https://linkedin.com/in/johnsmith
507+
socialNetworks:
508+
linkedin: johnsmith
509+
description: "Un plaisir de travailler avec Germain. Pédagogue et technique."

docs/github-pages/docs/getting-started/write-your-cv.mdx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,36 @@ education:
367367
The `Dates` field is a text field. You can use any format you want. The theme will not parse it.
368368
:::
369369

370+
### References
371+
372+
The references section is used to describe professional recommendations you have received.
373+
374+
| Field | Description |
375+
| --- | --- |
376+
| Name | The name of the person recommending you. |
377+
| Position | The position of the person. |
378+
| Company | The company of the person. |
379+
| Date | The date of the recommendation. |
380+
| Url | The URL to the person's profile (e.g., LinkedIn). |
381+
| SocialNetworks | The social networks of the person (see [Social Networks](#social-networks) for available fields). |
382+
| Description | The recommendation text. |
383+
384+
<details className="details-example">
385+
<summary><FontAwesomeIcon icon="fa-solid fa-paper-plane" /> &nbsp; **Example**</summary>
386+
```yaml
387+
references:
388+
- name: Jane Doe
389+
position: CTO
390+
company: TechCorp
391+
date: Jan 2024
392+
url: https://linkedin.com/in/janedoe
393+
socialNetworks:
394+
linkedin: janedoe
395+
github: janedoe-gh
396+
description: "Excellent engineer, highly skilled!"
397+
```
398+
</details>
399+
370400
## Full Example
371401

372402
Here is a full example in a `cv.yml` file:

docs/github-pages/docs/validation/schema-reference.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,43 @@ The validator uses a JSON Schema to define the CV structure. Key validation rule
3737

3838
- `career.missions` - At least 1 mission per company
3939
- `technicalSkills.domains.competencies` - At least 1 competency per domain
40+
41+
### References
42+
43+
La section `references` permet d'ajouter des recommandations professionnelles à votre CV.
44+
45+
#### Champs disponibles
46+
47+
| Champ | Type | Description |
48+
|-------|------|-------------|
49+
| `name` | string | Nom de la personne qui vous recommande |
50+
| `position` | string | Poste occupé par cette personne |
51+
| `company` | string | Entreprise de cette personne |
52+
| `date` | string | Date de la recommandation |
53+
| `url` | string | Lien vers le profil (ex: LinkedIn) |
54+
| `socialNetworks` | object | Réseaux sociaux de la personne |
55+
| `description` | string | Texte de la recommandation |
56+
57+
#### Structure de `socialNetworks`
58+
59+
| Champ | Type | Description |
60+
|-------|------|-------------|
61+
| `linkedin` | string | Identifiant LinkedIn |
62+
| `github` | string | Identifiant GitHub |
63+
| `twitter` | string | Identifiant Twitter |
64+
| `stackoverflow` | string | Identifiant Stack Overflow |
65+
66+
#### Exemple
67+
68+
```yaml
69+
references:
70+
- name: Jane Doe
71+
position: CTO
72+
company: TechCorp
73+
date: Jan 2024
74+
url: https://linkedin.com/in/janedoe
75+
socialNetworks:
76+
linkedin: janedoe
77+
github: janedoe-gh
78+
description: "Excellent ingénieur, très compétent !"
79+
```

docs/github-pages/static/cv.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,14 @@ education:
163163
location: Lens, France
164164
dates: 2019 - 2014
165165
link: https://ig2i.centralelille.fr
166+
167+
references:
168+
- name: Jane Doe
169+
position: CTO
170+
company: TechCorp
171+
date: Jan 2024
172+
url: https://linkedin.com/in/janedoe
173+
socialNetworks:
174+
linkedin: janedoe
175+
github: janedoe-gh
176+
description: "Germain est un excellent ingénieur, très compétent sur les sujets DevOps et Kubernetes. Je recommande vivement !"

internal/cvparser/parser_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,50 @@ func TestParseFile(t *testing.T) {
180180
}
181181
}
182182

183+
func TestReferenceUrlParsing(t *testing.T) {
184+
t.Run("Should parse Reference with Url and SocialNetworks fields", func(t *testing.T) {
185+
yamlContent := []byte(`
186+
references:
187+
- name: Jane Doe
188+
position: CTO
189+
company: TechCorp
190+
date: Jan 2024
191+
url: https://linkedin.com/in/janedoe
192+
socialNetworks:
193+
linkedin: janedoe
194+
github: janedoe-gh
195+
description: "Great engineer!"
196+
`)
197+
p := &ParserServices{}
198+
got := p.convertFileContentToStruct(yamlContent)
199+
200+
assert.Len(t, got.References, 1)
201+
assert.Equal(t, "Jane Doe", got.References[0].Name)
202+
assert.Equal(t, "https://linkedin.com/in/janedoe", got.References[0].Url)
203+
assert.Equal(t, "Great engineer!", got.References[0].Description)
204+
assert.Equal(t, "janedoe", got.References[0].SocialNetworks.Linkedin)
205+
assert.Equal(t, "janedoe-gh", got.References[0].SocialNetworks.Github)
206+
})
207+
208+
t.Run("Should parse Reference without Url field", func(t *testing.T) {
209+
yamlContent := []byte(`
210+
references:
211+
- name: John Smith
212+
position: Developer
213+
company: WebCorp
214+
date: Dec 2023
215+
description: "Talented developer"
216+
`)
217+
p := &ParserServices{}
218+
got := p.convertFileContentToStruct(yamlContent)
219+
220+
assert.Len(t, got.References, 1)
221+
assert.Equal(t, "John Smith", got.References[0].Name)
222+
assert.Equal(t, "", got.References[0].Url)
223+
assert.Equal(t, "Talented developer", got.References[0].Description)
224+
})
225+
}
226+
183227
func TestReadFile(t *testing.T) {
184228
testDirectory, _ := os.Getwd()
185229
baseDirectory, err := filepath.Abs(testDirectory + "/../..")

internal/fixtures/model.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,17 @@ education:
153153
location: Lens, France
154154
dates: 2019 - 2014
155155
link: https://ig2i.centralelille.fr
156+
157+
references:
158+
- name: Jane Smith
159+
position: CTO
160+
company: Tech Innovations
161+
date: Janvier 2024
162+
url: https://linkedin.com/in/janesmith
163+
socialNetworks:
164+
linkedin: janesmith
165+
github: janesmith
166+
description: "Une collaboration exceptionnelle. Germain a su transformer notre infrastructure."
156167
`)
157168

158169
var CvYamlGood03 = []byte(`
@@ -311,6 +322,20 @@ var CvModelGood02 = model.CV{
311322
Link: "https://ig2i.centralelille.fr",
312323
},
313324
},
325+
References: []model.Reference{
326+
{
327+
Name: "Jane Smith",
328+
Position: "CTO",
329+
Company: "Tech Innovations",
330+
Date: "Janvier 2024",
331+
Url: "https://linkedin.com/in/janesmith",
332+
SocialNetworks: model.SocialNetworks{
333+
Linkedin: "janesmith",
334+
Github: "janesmith",
335+
},
336+
Description: "Une collaboration exceptionnelle. Germain a su transformer notre infrastructure.",
337+
},
338+
},
314339
}
315340

316341
var CvModelGood03 = model.CV{}

internal/model/files_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ func TestBuildInputFile(t *testing.T) {
4040
t.Run("Should build InputFile with relative path", func(t *testing.T) {
4141
// Setup
4242
tempDir := t.TempDir()
43+
// Resolve symlinks for cross-platform compatibility (macOS /var -> /private/var)
44+
tempDir, err := filepath.EvalSymlinks(tempDir)
45+
require.NoError(t, err)
4346
testFile := filepath.Join(tempDir, "test.yml")
44-
err := os.WriteFile(testFile, []byte("test"), 0644)
47+
err = os.WriteFile(testFile, []byte("test"), 0644)
4548
require.NoError(t, err)
4649

4750
// Change to temp directory

internal/model/model.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ type CV struct {
1111
Certifications []Certification `yaml:"certifications"`
1212
Languages []Language `yaml:"languages"`
1313
Education []Education `yaml:"education"`
14+
References []Reference `yaml:"references"`
15+
}
16+
17+
type Reference struct {
18+
Name string `yaml:"name"`
19+
Position string `yaml:"position"`
20+
Company string `yaml:"company"`
21+
Date string `yaml:"date"`
22+
Url string `yaml:"url"`
23+
SocialNetworks SocialNetworks `yaml:"socialNetworks"`
24+
Description string `yaml:"description"`
1425
}
1526

1627
type Company struct {

0 commit comments

Comments
 (0)