feat: suggest date, sender and title from structured filename (#69) #78

Merged
marcel merged 8 commits from feat/filename-parsing into main 2026-03-26 16:48:45 +01:00
Owner

Summary

Closes #69

  • New parseFilename() utility (src/lib/utils/filename.ts) — full-match-only regex for four patterns: YYYY-MM-DD_Lastname_Firstname, YYYYMMDD_Lastname_Firstname, and both reversed. Partial matches return {}, unstructured names fall through unchanged.
  • New document form pre-fill — selecting a file triggers parsing; date, sender typeahead and title are suggested only while the respective field is still clean (never overwrites user input).
  • DropZone hint — a concrete example (2024-03-15_Mueller_Hans.pdf) is shown below the accepted types line so users know the supported naming convention.
  • Backend titleFromFilename() — mirrors the same four patterns in DocumentService; dropzone quick-uploads now land with a formatted title (Hans Mueller (12.03.1965)) instead of the raw stripped filename. No sender auto-assignment (requires person to exist).

Test plan

  • 13 Vitest tests in filename.spec.ts — all patterns, umlaut names, non-matching filenames
  • 6 new DocumentServiceTest cases for titleFromFilename() — all 4 patterns + null + fallback
  • Manual: select 1965-03-12_Mueller_Hans.pdf on /documents/new → date shows 12.03.1965, sender shows Hans Mueller, title shows Hans Mueller (12.03.1965)
  • Manual: type a title first, then select a file → title is NOT overwritten
  • Manual: DropZone hint text is visible
  • Manual: dropzone upload of 19650312_Mueller_Hans.pdf → document title is Hans Mueller (12.03.1965)

🤖 Generated with Claude Code

## Summary Closes #69 - **New `parseFilename()` utility** (`src/lib/utils/filename.ts`) — full-match-only regex for four patterns: `YYYY-MM-DD_Lastname_Firstname`, `YYYYMMDD_Lastname_Firstname`, and both reversed. Partial matches return `{}`, unstructured names fall through unchanged. - **New document form pre-fill** — selecting a file triggers parsing; date, sender typeahead and title are suggested only while the respective field is still clean (never overwrites user input). - **DropZone hint** — a concrete example (`2024-03-15_Mueller_Hans.pdf`) is shown below the accepted types line so users know the supported naming convention. - **Backend `titleFromFilename()`** — mirrors the same four patterns in `DocumentService`; dropzone quick-uploads now land with a formatted title (`Hans Mueller (12.03.1965)`) instead of the raw stripped filename. No sender auto-assignment (requires person to exist). ## Test plan - [ ] 13 Vitest tests in `filename.spec.ts` — all patterns, umlaut names, non-matching filenames - [ ] 6 new `DocumentServiceTest` cases for `titleFromFilename()` — all 4 patterns + null + fallback - [ ] Manual: select `1965-03-12_Mueller_Hans.pdf` on `/documents/new` → date shows `12.03.1965`, sender shows `Hans Mueller`, title shows `Hans Mueller (12.03.1965)` - [ ] Manual: type a title first, then select a file → title is NOT overwritten - [ ] Manual: DropZone hint text is visible - [ ] Manual: dropzone upload of `19650312_Mueller_Hans.pdf` → document title is `Hans Mueller (12.03.1965)` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
marcel added 4 commits 2026-03-26 15:20:26 +01:00
Supports four patterns: date_lastname_firstname and lastname_firstname_date,
both with ISO (YYYY-MM-DD) and compact (YYYYMMDD) date formats.
Returns dateIso, personName and a formatted suggestedTitle.
Partial matches are rejected — unrecognised filenames return {}.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a file is selected on the new document page, parseFilename runs
on the filename and suggests date, sender name and title via the new
suggestedDateIso / suggestedSenderName / suggestedTitle props. Each
suggestion is applied only while the respective field is still clean
(not dirty), so manual input is never overwritten.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows a concrete example (2024-03-15_Mueller_Hans.pdf) so users know
which filenames will be auto-parsed during bulk upload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(quick-upload): generate better title from structured filename
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 2m16s
CI / Backend Unit Tests (pull_request) Successful in 2m8s
CI / E2E Tests (pull_request) Failing after 26m22s
a302f96560
titleFromFilename() mirrors the same four patterns as the frontend
parseFilename() utility. Dropzone uploads to Mueller_Hans_19650312.pdf
now land with title "Hans Mueller (12.03.1965)" instead of the raw
stripped filename.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
marcel added 1 commit 2026-03-26 15:33:44 +01:00
feat(filename): support compound last names like de Gruyter
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 2m17s
CI / Backend Unit Tests (pull_request) Successful in 2m13s
CI / E2E Tests (pull_request) Failing after 25m0s
f0940524e7
Replace the four fixed regexes with a split-based algorithm:
- first segment = date → last segment = firstName, rest = lastName parts
- last segment = date → second-to-last = firstName, rest = lastName parts

18881025_de_Gruyter_Walter.pdf now correctly yields "Walter de Gruyter".
Simple two-segment names behave identically to before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
marcel added 1 commit 2026-03-26 15:43:58 +01:00
feat(quick-upload): pre-fill date and sender from structured filename
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 2m28s
CI / Backend Unit Tests (pull_request) Successful in 2m14s
CI / E2E Tests (pull_request) Failing after 28m25s
99e3163c0e
storeDocument() now uses the ParsedFilename record to also set
documentDate and sender on new quick-uploads. Sender lookup is
an exact case-insensitive first+last name match — no new persons
are created. Unmatched filenames behave as before.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
marcel added 1 commit 2026-03-26 15:51:28 +01:00
fix(enrich): restore fixed-position layout and done icon
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 3m39s
CI / Backend Unit Tests (pull_request) Successful in 2m39s
CI / E2E Tests (pull_request) Failing after 30m26s
648bdffe4f
Re-applies the scroll fix from 0d3c557 which was missing from this branch:
- measure header height at mount, use it as top offset instead of hardcoded 68px
- fix done page icon to Check-Double-LG

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
marcel added 1 commit 2026-03-26 15:52:49 +01:00
Revert "fix(enrich): restore fixed-position layout and done icon"
Some checks failed
CI / Unit & Component Tests (pull_request) Successful in 2m28s
CI / Backend Unit Tests (pull_request) Successful in 2m13s
CI / E2E Tests (pull_request) Failing after 27m56s
CI / Unit & Component Tests (push) Successful in 2m24s
CI / Backend Unit Tests (push) Successful in 2m12s
CI / E2E Tests (push) Failing after 28m17s
2efa790243
This reverts commit 648bdffe4f.
marcel merged commit 2efa790243 into main 2026-03-26 16:48:45 +01:00
marcel deleted branch feat/filename-parsing 2026-03-26 16:48:46 +01:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#78