feat(submissions): generated-doc filename <date> <keyword> (<case>) + user-replaceable keyword
Generated documents now download as "YYYY-MM-DD keyword (case number).docx" (date first/sortable, case number bracketed) instead of the old "rule-case-date.docx" shape. - submissionFileName: date-led frame; keyword = user override > lang-aware rule name > "submission"; case number always bracketed, placeholder "Az. folgt" (named const) when the project has no Aktenzeichen. - SanitiseSubmissionFileName hardened to fold the full Windows-reserved set (colon star question angle pipe) on top of slash/backslash, while preserving spaces + parentheses so the assembled frame stays human-facing yet filesystem-safe. - User-replaceable keyword stored in the draft's composer_meta jsonb (filename_keyword, no migration). Editor gains a "Stichwort (Dateiname)" input that placeholders the auto rule name and persists via the draft PATCH path. One-click /generate has no draft row -> keeps auto keyword. Tests: submissionFileName (full / no-AZ / override / EN / slash case-no / blank override / empty rule), submissionFilenameKeyword, extended sanitiser cases. t-paliad-354
This commit is contained in:
@@ -185,7 +185,12 @@ func SanitiseSubmissionFileName(s string) string {
|
||||
s = umlautFolder.Replace(s)
|
||||
s = strings.Map(func(r rune) rune {
|
||||
switch r {
|
||||
case '/', '\\':
|
||||
// Path separators and the rest of the Windows-reserved set —
|
||||
// fold to underscore so a case number like "UPC_CFI_123/2026"
|
||||
// stays one filesystem-safe segment. Spaces and parentheses are
|
||||
// intentionally preserved: the human-facing download name
|
||||
// "<date> <keyword> (<case>)" relies on them (t-paliad-354).
|
||||
case '/', '\\', ':', '*', '?', '<', '>', '|':
|
||||
return '_'
|
||||
case '"', '\'':
|
||||
return -1
|
||||
|
||||
@@ -241,9 +241,12 @@ func TestSanitiseSubmissionFileName(t *testing.T) {
|
||||
"Klageerwiderung": "Klageerwiderung",
|
||||
"Berufungsbegründung": "Berufungsbegruendung",
|
||||
"Schriftsatz/Anlage": "Schriftsatz_Anlage",
|
||||
`Statement of "Defence"`: "Statement of Defence",
|
||||
` Klage `: "Klage",
|
||||
"Größe": "Groesse",
|
||||
`Statement of "Defence"`: "Statement of Defence",
|
||||
` Klage `: "Klage",
|
||||
"Größe": "Groesse",
|
||||
"UPC_CFI_123/2026": "UPC_CFI_123_2026",
|
||||
"a:b*c?d<e>f|g": "a_b_c_d_e_f_g",
|
||||
"Klageerwiderung (Frist)": "Klageerwiderung (Frist)",
|
||||
}
|
||||
for in, want := range cases {
|
||||
t.Run(in, func(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user