Commit Graph
171 Commits
Author SHA1 Message Date
Amruth Pillai 2506509538 feat: make cover letters documents of their own
Resumes no longer hold cover-letter sections. A migration saves every
letter a resume carried as a letter linked to that resume's details and
design, hands a resume's only letter to its only letter-less application,
then removes the sections from resumes and their layouts. rollback.sql
puts them back.

Every resume write on the server moves any letter it still carries into
a saved letter in the same transaction, so stale tabs, older files, API
clients and restored versions keep working without duplicating letters.

The resume editor no longer adds or imports letters, the resume download
drops its Cover letter tab, and resume PDF downloads (API, signed links,
MCP) no longer take a cover-letter target. copy_embedded_cover_letter and
POST /cover-letters/from-resume are removed.
2026-09-29 09:30:07 +02:00
Amruth Pillai 48793e04be chore(pdf): drop what the Forme port left unused 2026-09-29 08:40:22 +02:00
Amruth Pillai 29ab0326b2 fix(pdf): mirror the award title and date right to left 2026-09-29 08:27:24 +02:00
Amruth Pillai 3405200cf4 fix(pdf): keep a list marker with its item's first line 2026-09-29 08:25:06 +02:00
Amruth Pillai 17d25c5ffa test(pdf): letters print the sender's header in every template 2026-09-29 08:08:12 +02:00
Amruth Pillai 098df60230 feat: choose which side the sidebar sits on
Two-column templates take a sidebarSide from the layout (left or right).
Without one, each template keeps its own side and right-to-left pages
mirror it. The PDF templates reverse only their columns, header band
and sidebar background, and the DOCX export follows the same choice.
Design's Sidebar panel offers Left and Right.
2026-09-29 08:00:33 +02:00
Amruth Pillai 722f5fa14c fix(pdf): close the remaining gaps in the forme port
Work around more Forme 0.25 layout defects in the converter: row-reverse
laid out as row, min and max widths ignored along a row, text dropping
view children, empty text taking a line, overflowing optimal line
breaks, a text in a splitting row wrecking later pages, page breaks on
row items, four equal border sides, percentage corner radii, pictures
under their shadow, and imported table rows. Rotation is left out while
Forme misplaces rotated boxes; the stylesheet editor warns about it and
about percentage padding.

The page map rebuilds blocks Forme drops from its layout, the browser
renderer rejects documents whose fonts can't load so callers fall back
to the server PDF, and every render gets fresh font entries. Glalie's
sidebar is one band at the combined tint.

Tests are re-baselined where they encoded react-pdf metrics, and engine
limits (list marker keep-together, RTL line order, characters above
U+FFFF, percentage padding) are expected failures. The plan logs the
migration in section 13.
2026-09-29 07:37:25 +02:00
Amruth Pillai c0bf1aebaf feat(pdf): remove react-pdf and move every consumer to forme
The web preview, downloads, template gallery, server export and public
PDF render through Forme. react-pdf, react-pdf-html, the react-pdf
hyphenation package, the Phosphor react-pdf icons and the four patches
are gone. Hyphenation now follows the page language for every language
Forme has patterns for.

Semantic CSS keeps its language; declarations Forme can't draw raise an
ENGINE_UNSUPPORTED warning in the editor. The page map rebuilds blocks
Forme leaves out of its layout when they break across pages, and a
render that misplaces a box is repeated with nested rows kept whole.

Tests move to a small shim with the react-pdf calls they were written
against; tests of react-pdf internals are dropped. Forme limits are
recorded as expected failures (RTL line order, characters above
U+FFFF).
2026-09-29 07:11:40 +02:00
Amruth Pillai bc28441b66 feat(pdf): render resumes with the forme engine
Templates keep their react-pdf-style primitives. A small React renderer
records what they draw, and the result is converted to a Forme document:
styles, fonts (with ligatures disabled for text extraction), Phosphor
icons as SVG paths, pictures fitted by object-fit, and the page map from
source locations. Workarounds for Forme 0.25 layout defects live in the
converter: opaque translucent colours, border insets, row splitting,
column gaps across pages, absolute positioning and repeated backgrounds.

Consumers, the Semantic CSS adapter and the old react-pdf dependencies
follow in later commits.
2026-09-29 06:22:38 +02:00
Amruth Pillai aa9a5113c0 fix(pdf): keep the letter's header when the page tree is built 2026-09-28 23:08:10 +02:00
Amruth Pillai f73238ba3b feat(pdf): pass the page map through the browser renderer 2026-09-28 17:17:56 +02:00
Amruth Pillai def4f72169 feat(pdf): map rendered header, section and item boxes
Templates tag the views that own the header, each section and each item
with data-resume-node. ResumeDocument's new onPageMap callback reads React
PDF's layout tree after each render and returns page-relative boxes, so the
editor can link lines on the page to entries in the panel. The attribute
stays on layout nodes and never reaches the PDF.
2026-09-28 16:01:16 +02:00
Amruth Pillai 328bf73cee chore(i18n): drop unregistered ckb-IR catalog
Crowdin shipped an empty Central Kurdish (ckb-IR) catalog with no translated
strings. The locale is not registered in the Lingui config or locale schema,
so remove the file and its PDF section title entry.
2026-09-28 08:59:38 +02:00
Amruth Pillai 6db26e9b5c chore(pdf): regenerate section title catalog for ckb-IR locale 2026-09-28 08:07:15 +02:00
Santhi PrakashandAmruth Pillai 28d0170b05 fix(resume): detect section headings set in a side column (#3521)
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-09-21 19:46:46 +02:00
Amruth Pillai b5ff720f9d chore: update translations 2026-09-17 22:27:22 +02:00
Amruth Pillai b953435f2c fix: audit code for reduction 2026-09-17 22:16:44 +02:00
Amruth Pillai 96c7142fbc chore: update dependencies 2026-09-16 18:36:50 +02:00
Amruth Pillai f89acb4368 chore: migrate repository links to reactive-resume/reactive-resume 2026-09-12 11:18:32 +02:00
Amruth Pillai 730f795073 fix(pdf): pin @napi-rs/canvas to 1.0.8
1.0.9 rejects the Path2D objects pdfjs-dist 6.3.289 passes to fill/clip,
failing every raster test with "Value is none of these types `String`, `Path`".
2026-09-10 00:07:23 +02:00
Amruth Pillai dc8f9787a4 chore: update dependencies 2026-09-09 23:57:37 +02:00
Amruth Pillai 812d396120 test(pdf): compare raster baselines only on their authoring platform
Adding packages/pdf to CI turned it red on ubuntu-latest for two reasons,
neither of which is a real regression.

Rasterized pixels depend on the host font rasterizer. The chikorita, ditto
and all-template baselines differ on Linux in rasterSha256 alone: every page
count, item count and text coordinate is byte-identical to the macOS-authored
baseline. Compare the portable geometry on every host and the pixels only on
the platform the PNGs were generated on, so the characterization keeps
protecting layout without asserting another machine's antialiasing.

The picture-fit override case rasterizes twice and timed out at Vitest's 5s
default on a CI runner, with the date suite landing at 3.5-4.7s. Give the
package a 30s timeout rather than leaving every rendering test a runner
slowdown away from failing.

Verified on linux/amd64 in Docker: both files pass, 18/18.
2026-09-09 12:46:41 +02:00
Amruth Pillai 1106562169 test(pdf): refresh Lapras date-layout baseline and run all packages in CI
The Lapras section marginTop added in c0c658c0 shifted every date marker in
that template down the page, but the date-layout characterization baseline
was not regenerated, so packages/pdf has been failing on main since. The
delta is geometry-only: same page count (2), same text item count (87), same
markers, x and width unchanged; 17 markers move on y and the raster hashes
follow.

Nothing caught it because the workflow ran test:ci for only server and
tooling, leaving 17 packages uncovered. Replace that filter list with the
full workspace run so a package cannot silently lose coverage again, and
move it after the migration and storage steps that the api suite needs.

Serial execution is deliberate. Running the packages in parallel oversubscribes
the runner and starves the PDF rasterization and API rate-limit suites past
their timeouts; 19/19 pass consistently at --concurrency=1.
2026-09-09 12:33:04 +02:00
Santhi Prakashcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>Amruth Pillai
51ac77295e fix(pdf): preserve list indentation on continuation pages (#3495) (#3497)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-09-09 11:55:48 +02:00
Diego Vega Centeno c0c658c00c fix(pdf): add marginTop to style of "section" in "Lapras" template (#3498) 2026-09-09 11:35:23 +02:00
Amruth Pillai 6416da28a4 feat(homepage): rebuild landing page and fix untranslated homepage strings in 16 locales (#3496) 2026-09-08 18:01:59 +02:00
Amruth Pillai 77a5499881 Merge remote-tracking branch 'origin/main' into codex/issue-3155-date-layout-characterization 2026-09-06 06:06:19 +02:00
Amruth Pillai 1232d5dfb2 test(pdf): enforce date layout baselines 2026-09-06 06:05:04 +02:00
Amruth Pillai f2769dce54 test(pdf): strengthen item pagination coverage 2026-09-06 05:56:20 +02:00
Amruth Pillai 30f4edf45d test(pdf): characterize item pagination blocker 2026-09-06 05:47:56 +02:00
Amruth Pillai 58ee4eead7 Merge remote-tracking branch 'origin/main' into codex/issue-3155-date-layout-characterization 2026-09-06 05:47:24 +02:00
Amruth Pillai f97d1b736e test(pdf): characterize date layout issues 3155 2841 2026-09-06 05:46:38 +02:00
Amruth Pillai 368858a56f feat(resume): add per-section heading visibility (#3477) 2026-09-05 20:34:21 -07:00
Amruth Pillai 97f34b7ccd fix(editor): avoid unsafe clipboard parsing pattern (#3474) 2026-09-05 20:06:23 -07:00
Amruth Pillai 2a4a1583be fix(pdf): restore Gengar skill rating order (#3473) 2026-09-05 20:00:19 -07:00
Amruth Pillai ea97de5ec4 fix(editor): preserve literal rich-text whitespace (#3472)
* fix(web): preserve imported rich-text tables

* fix(web): harden imported table preservation

* fix(web): fail closed on lossy table markup

* chore: remove plan 16 evidence reports

* fix(web): close imported table preservation gaps

* fix(editor): preserve literal rich-text whitespace

* chore: remove plan 19 evidence report

* fix: preserve literal whitespace through layout and editor transforms

* fix: preserve whitespace in bare table cells

* chore: keep orchestration evidence untracked
2026-09-05 19:57:50 -07:00
Amruth Pillai 870388192e feat(resume): add skill keyword list presentation (#3469)
* feat(resume): add skill keyword list presentation

* test(schema): refresh generated references
2026-09-05 19:41:14 -07:00
Amruth Pillai 38832014b9 fix(stylesheet): improve unsupported-gradient diagnostics (#3468)
* test(stylesheet): strengthen basics diagnostics

* fix(css): tighten gradient diagnostics
2026-09-05 19:29:21 -07:00
Amruth Pillai 0fbeeeb4c4 feat(builder): explain authored page overflow (#3467)
* feat(web): explain authored page overflow

* docs: record plan 23A verification

* chore: remove plan 23A evidence report

* test(pdf): assert authored continuation placement
2026-09-05 19:26:50 -07:00
Amruth Pillai 999cd618cb feat(web): preserve editable imported tables (#3464)
* fix(web): preserve imported rich-text tables

* fix(web): harden imported table preservation

* fix(web): fail closed on lossy table markup

* chore: remove plan 16 evidence reports

* fix(web): close imported table preservation gaps
2026-09-05 18:41:38 -07:00
Amruth Pillai ab67831e4b feat: add cover and contain picture fitting (#3461)
* feat: add picture fit options

* fix: harden picture fit regressions

* fix: address picture fit review findings
2026-09-05 18:33:35 -07:00
Amruth Pillai 05e48a7cbc fix(pdf): preserve authored Unicode spaces in rich text (#3451) 2026-09-05 11:31:03 -07:00
Amruth Pillai d10eb4a55d fix(pdf): isolate cached glyph character metadata (#3450)
* fix(pdf): isolate character metadata for cached font glyphs

* test(pdf): verify glyph aliases do not grow cache

* test(pdf): assert glyph aliases are unique
2026-09-05 11:22:05 -07:00
Amruth Pillai 8d4cf8a2f8 fix(pdf): keep ordered list markers clear of body text (#3449)
* fix(pdf): keep ordered list markers clear of body text

* perf(pdf): cache ordered list marker sizing
2026-09-05 10:53:34 -07:00
Amruth Pillai f468651c79 feat(editor): support whole-paragraph indentation (#3448)
* feat(editor): support whole-paragraph indentation

* fix(docx): retain indentation in quotes and RTL documents

* fix(exports): bound paragraph insets in narrow PDF columns

* fix(pdf): type bounded paragraph rendering consistently

* test(editor): use explicit list conversion commands

* fix(docx): preserve quote inset on list items
2026-09-05 10:41:30 -07:00
Amruth Pillai 873835a571 fix(pdf): align Ditgar item headers with body text (#3445)
* fix(pdf): align Ditgar item headers with body text

* refactor(pdf): share Ditgar header border width
2026-09-05 10:14:12 -07:00
Diego Vega CentenoandAmruth Pillai 8df1b25550 feat(skills): add inline layout option for skill items (#3358)
* feat(skills): add inline layout option for skill items

* fix: restore default skills layout (regressed by inline feature)

- Restore metrics rowGap style for default layout
- Only render LevelDisplay inside the row for inline layout, not default

* refactor(pdf):  Extract inline skills style logic from JSX to reusable function

* test(pdf): add test coverage for inline skills item layout

- Add test suite SkillsSectionInlineFormat to verify isInlineSkillsItem and getSkillsItemStyle behavior

* test(pdf): add comprehensive test coverage for inline skills item style logic

- Test combinations of proficiency, level, and keywords fields (0, 1, 3 fields)

* test(schema): add test coverage for column equals 1 when layout is inline

* test(web): add component-level tests for inline and columns layouts

* test(import): add v4 parser-level test for missing skills layout

* docs: regenerate skills layout references

* test(docx): include skills layout in section fixtures

---------

Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-09-05 09:51:14 -07:00
Amruth Pillai ea2beb8450 fix(pdf): keep list markers with their first text fragment (#3443)
* fix(pdf): keep list markers with their first text fragment

* fix(pdf): preserve page breaks while rewinding list companions

* fix(pdf): consume oversized list marker presence hints

* test(pdf): allow cold startup for pagination process guard

* fix(pdf): key list presence spacer
2026-09-05 09:51:09 -07:00
Santhi PrakashandAmruth Pillai e0c2f6d88a fix(pdf): preserve first character of section headings by adding left padding (#3386)
* fix(pdf): add left padding to section heading text to prevent first-character clipping

Closes #3380

* fix(pdf): apply heading padding default after style composition

Apply paddingLeft: 1 only when no composed style fragment already defines it, so an explicit paddingLeft from a template or style rule is preserved. Keep the fallback for an empty style list.

* fix(pdf): keep heading safety padding on text only

---------

Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
2026-09-05 09:35:06 -07:00
Amruth Pillai bf71253ca4 fix: preserve margins on PDF overflow pages (#3422)
* fix: preserve page margins across PDF overflow pages

* test(pdf): preserve styled and full-width Glalie backgrounds

* test(pdf): assert exact semantic margin colors
2026-09-05 09:33:13 -07:00