ajustacv-resume-schema 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/package.json +1 -1
- package/src/fixtures.ts +39 -2
- package/src/schema.ts +21 -0
package/README.md
CHANGED
|
@@ -51,13 +51,16 @@ import { FULL_RESUME, RESUME_FIXTURES } from "ajustacv-resume-schema/fixtures";
|
|
|
51
51
|
```
|
|
52
52
|
ResumeDocument
|
|
53
53
|
├── header ResumeHeader name, headline, contacts, links, optional photo
|
|
54
|
-
├── sections ResumeSection[] ordered; discriminated union over
|
|
54
|
+
├── sections ResumeSection[] ordered; discriminated union over 10 types
|
|
55
55
|
├── design DesignSettings templateId, free-hex accent, curated fontId, A4
|
|
56
56
|
└── meta DocumentMeta schemaVersion, targetRole, nullable ownerId
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
The
|
|
60
|
-
`languages`, `certifications`, `projects
|
|
59
|
+
The ten section types are `summary`, `experience`, `education`, `skills`,
|
|
60
|
+
`languages`, `certifications`, `projects`, `achievements`, `strengths` and
|
|
61
|
+
`custom`. `achievements` and `strengths` share one entry shape — a title and a
|
|
62
|
+
one-line description — and exist as their own types so a template can set them
|
|
63
|
+
apart and an ATS can read them as what they are. `custom` is the
|
|
61
64
|
catch-all that keeps parsing lossless — content an extractor cannot classify
|
|
62
65
|
lands there rather than being dropped. Duplicates are allowed: a resume may
|
|
63
66
|
carry two `custom` sections, or two `experience` ones.
|
package/package.json
CHANGED
package/src/fixtures.ts
CHANGED
|
@@ -18,7 +18,7 @@ function fixture(input: ResumeDocumentInput): ResumeDocument {
|
|
|
18
18
|
return assertResumeDocument(input);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
// A realistic pt-BR resume exercising all
|
|
21
|
+
// A realistic pt-BR resume exercising all ten section types, inline
|
|
22
22
|
// markdown, dates with and without a month, an ongoing role, a hidden field
|
|
23
23
|
// and a manual page break — the document template work is developed against.
|
|
24
24
|
export const FULL_RESUME: ResumeDocument = fixture({
|
|
@@ -181,6 +181,29 @@ export const FULL_RESUME: ResumeDocument = fixture({
|
|
|
181
181
|
},
|
|
182
182
|
],
|
|
183
183
|
},
|
|
184
|
+
{
|
|
185
|
+
id: "s-achv",
|
|
186
|
+
type: "achievements",
|
|
187
|
+
title: "Conquistas",
|
|
188
|
+
visible: true,
|
|
189
|
+
entries: [
|
|
190
|
+
{
|
|
191
|
+
id: "a1",
|
|
192
|
+
title: "Prêmio Inovação 2023",
|
|
193
|
+
description: "Reconhecimento interno pela automação que **cortou 40%** do tempo de deploy.",
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: "s-str",
|
|
199
|
+
type: "strengths",
|
|
200
|
+
title: "Pontos fortes",
|
|
201
|
+
visible: true,
|
|
202
|
+
entries: [
|
|
203
|
+
{ id: "st1", title: "Liderança técnica", description: "Conduzi 3 squads em migrações sem downtime." },
|
|
204
|
+
{ id: "st2", title: "Comunicação", description: "Traduzo decisões técnicas para o negócio." },
|
|
205
|
+
],
|
|
206
|
+
},
|
|
184
207
|
{
|
|
185
208
|
id: "s-custom",
|
|
186
209
|
type: "custom",
|
|
@@ -292,12 +315,26 @@ export const ALL_SECTION_TYPES_RESUME: ResumeDocument = fixture({
|
|
|
292
315
|
visible: true,
|
|
293
316
|
entries: [{ id: "t-proj-1", name: "Painel COVID-RJ", description: "Painel público de indicadores." }],
|
|
294
317
|
},
|
|
318
|
+
{
|
|
319
|
+
id: "t-achv",
|
|
320
|
+
type: "achievements",
|
|
321
|
+
title: "Conquistas",
|
|
322
|
+
visible: true,
|
|
323
|
+
entries: [{ id: "t-achv-1", title: "Menção honrosa", description: "Hackathon de dados abertos, 2021." }],
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
id: "t-str",
|
|
327
|
+
type: "strengths",
|
|
328
|
+
title: "Pontos fortes",
|
|
329
|
+
visible: true,
|
|
330
|
+
entries: [{ id: "t-str-1", title: "Rigor analítico", description: "Valido toda hipótese contra os dados." }],
|
|
331
|
+
},
|
|
295
332
|
{
|
|
296
333
|
id: "t-custom",
|
|
297
334
|
type: "custom",
|
|
298
335
|
title: "Prêmios",
|
|
299
336
|
visible: true,
|
|
300
|
-
entries: [{ id: "t-custom-1", title: "
|
|
337
|
+
entries: [{ id: "t-custom-1", title: "Finalista do Prêmio Nacional de Dados", bullets: [] }],
|
|
301
338
|
},
|
|
302
339
|
// A renamed, hidden section: the content survives, templates skip it.
|
|
303
340
|
{
|
package/src/schema.ts
CHANGED
|
@@ -197,6 +197,21 @@ export const ProjectEntrySchema = z.object({
|
|
|
197
197
|
dateRange: DateRangeSchema.nullable().default(null),
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
+
// Achievements and strengths (#69) share one shape — a short title and one
|
|
201
|
+
// line of prose — but are distinct types: a template may set "Conquistas"
|
|
202
|
+
// apart, and an ATS reads "Prêmios" and "Pontos fortes" as different signals.
|
|
203
|
+
export const AchievementEntrySchema = z.object({
|
|
204
|
+
...entryBase,
|
|
205
|
+
title: shortText,
|
|
206
|
+
description: RichLineSchema,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
export const StrengthEntrySchema = z.object({
|
|
210
|
+
...entryBase,
|
|
211
|
+
title: shortText,
|
|
212
|
+
description: RichLineSchema,
|
|
213
|
+
});
|
|
214
|
+
|
|
200
215
|
// The catch-all that keeps parsing lossless: anything the extractor cannot
|
|
201
216
|
// map to a typed section still lands here rather than being dropped.
|
|
202
217
|
export const CustomEntrySchema = z.object({
|
|
@@ -217,6 +232,8 @@ export const SECTION_TYPES = [
|
|
|
217
232
|
"languages",
|
|
218
233
|
"certifications",
|
|
219
234
|
"projects",
|
|
235
|
+
"achievements",
|
|
236
|
+
"strengths",
|
|
220
237
|
"custom",
|
|
221
238
|
] as const;
|
|
222
239
|
|
|
@@ -242,6 +259,8 @@ export const ResumeSectionSchema = z.discriminatedUnion("type", [
|
|
|
242
259
|
z.object({ ...sectionBase, type: z.literal("languages"), entries: entryList(LanguageEntrySchema) }),
|
|
243
260
|
z.object({ ...sectionBase, type: z.literal("certifications"), entries: entryList(CertificationEntrySchema) }),
|
|
244
261
|
z.object({ ...sectionBase, type: z.literal("projects"), entries: entryList(ProjectEntrySchema) }),
|
|
262
|
+
z.object({ ...sectionBase, type: z.literal("achievements"), entries: entryList(AchievementEntrySchema) }),
|
|
263
|
+
z.object({ ...sectionBase, type: z.literal("strengths"), entries: entryList(StrengthEntrySchema) }),
|
|
245
264
|
z.object({ ...sectionBase, type: z.literal("custom"), entries: entryList(CustomEntrySchema) }),
|
|
246
265
|
]);
|
|
247
266
|
|
|
@@ -306,6 +325,8 @@ export type SkillGroup = z.infer<typeof SkillGroupSchema>;
|
|
|
306
325
|
export type LanguageEntry = z.infer<typeof LanguageEntrySchema>;
|
|
307
326
|
export type CertificationEntry = z.infer<typeof CertificationEntrySchema>;
|
|
308
327
|
export type ProjectEntry = z.infer<typeof ProjectEntrySchema>;
|
|
328
|
+
export type AchievementEntry = z.infer<typeof AchievementEntrySchema>;
|
|
329
|
+
export type StrengthEntry = z.infer<typeof StrengthEntrySchema>;
|
|
309
330
|
export type CustomEntry = z.infer<typeof CustomEntrySchema>;
|
|
310
331
|
export type SectionType = z.infer<typeof SectionTypeSchema>;
|
|
311
332
|
export type ResumeSection = z.infer<typeof ResumeSectionSchema>;
|