case 4761 - emailed report PDFs have the content type application/pdf

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 17:32:19 -07:00
parent 36fe2eaf53
commit 413af08918
3 changed files with 4 additions and 2 deletions

View File

@@ -284,7 +284,7 @@ Found during the port, out of scope. One line each.
- Found in the case 4727 droplet test (2026-10-26; John: later case, early in a future release so every other test exercises it): stopping the service sometimes logs `ObjectDisposedException` from `JobsBiz.ProcessJobsAsync`, and the server-problem notification it tries to raise fails the same way, so nothing is sent. Pre-existing: 8.2.4 on devtest logged it at 2 of its last 40 stops (2026-09-10, 2026-10-01). Cause: `GeneratorService.StopAsync` (`generator/Generate.cs`) is overridden to return at once without calling `base.StopAsync`, so the host neither signals the job loop nor waits for it, and disposes its services while a pass may still be running; `Task.Delay(1000)` also ignores the stopping token. Fix: remove the override (or call the base) and pass the token to `Task.Delay`; test stopping during a report render and a backup, since shutdown would then wait for the running pass - Found in the case 4727 droplet test (2026-10-26; John: later case, early in a future release so every other test exercises it): stopping the service sometimes logs `ObjectDisposedException` from `JobsBiz.ProcessJobsAsync`, and the server-problem notification it tries to raise fails the same way, so nothing is sent. Pre-existing: 8.2.4 on devtest logged it at 2 of its last 40 stops (2026-09-10, 2026-10-01). Cause: `GeneratorService.StopAsync` (`generator/Generate.cs`) is overridden to return at once without calling `base.StopAsync`, so the host neither signals the job loop nor waits for it, and disposes its services while a pass may still be running; `Task.Delay(1000)` also ignores the stopping token. Fix: remove the override (or call the base) and pass the token to `Task.Delay`; test stopping during a report render and a backup, since shutdown would then wait for the running pass
- From case 4755 (tidy-up, no behaviour change): `SetNextBackup` no longer reads `NextBackup`'s previous value, so the startup line `NextBackup = FileUtil.MostRecentAutomatedBackupFileDate()` (`util/ServerGlobalOpsSettingsCache.cs:50`), the reset to `DateTime.MinValue` in `GlobalOpsBackupSettingsBiz` and `FileUtil.MostRecentAutomatedBackupFileDate` itself are dead. Same in Sockeye - From case 4755 (tidy-up, no behaviour change): `SetNextBackup` no longer reads `NextBackup`'s previous value, so the startup line `NextBackup = FileUtil.MostRecentAutomatedBackupFileDate()` (`util/ServerGlobalOpsSettingsCache.cs:50`), the reset to `DateTime.MinValue` in `GlobalOpsBackupSettingsBiz` and `FileUtil.MostRecentAutomatedBackupFileDate` itself are dead. Same in Sockeye
- Found in case 4755's integration run (2026-10-31): a 500 response produced by the exception handler (e.g. `/` on a debug server whose `wwwroot` has no client) has none of the three safe headers from case 4727 (F35), because the handler clears headers set before it. Integration test `ApiRoute.SafeHeadersOnEveryResponse` fails for that reason on a debug server without the client in `wwwroot`; it passes on a release build - Found in case 4755's integration run (2026-10-31): a 500 response produced by the exception handler (e.g. `/` on a debug server whose `wwwroot` has no client) has none of the three safe headers from case 4727 (F35), because the handler clears headers set before it. Integration test `ApiRoute.SafeHeadersOnEveryResponse` fails for that reason on a debug server without the client in `wwwroot`; it passes on a release build
- Pre-existing (found in the 4632 IIS test, John: Deferred): emailed report attachments have the content type `application/pdf/pdf`, because `Mailer.cs:51` builds `new MimePart("application/pdf", "pdf")` (media type and subtype) instead of `new MimePart("application", "pdf")`. Mail programs still open the file by its `.pdf` name - **Fixed in case 4761.** Pre-existing (found in the 4632 IIS test, John: Deferred): emailed report attachments have the content type `application/pdf/pdf`, because `Mailer.cs:51` builds `new MimePart("application/pdf", "pdf")` (media type and subtype) instead of `new MimePart("application", "pdf")`. Mail programs still open the file by its `.pdf` name
- Found in case 4653 (pre-existing): `CustomerBiz.ValidateCanDeleteAsync` refuses to delete a customer that has contacts (users), yet `DeleteAsync` then has code to delete the customer's contacts, which can never run. Its comment says contacts were meant to be deleted with the customer, and that the check is there "for now". Decide which behaviour is wanted; same in Sockeye - Found in case 4653 (pre-existing): `CustomerBiz.ValidateCanDeleteAsync` refuses to delete a customer that has contacts (users), yet `DeleteAsync` then has code to delete the customer's contacts, which can never run. Its comment says contacts were meant to be deleted with the customer, and that the check is there "for now". Decide which behaviour is wanted; same in Sockeye
- Found in case 4739: reports rendered by the server for customer notifications use the subscription's time zone, and when it is empty `resource/rpt/ay-report.js` falls back to `America/Winnipeg` (date, time and date-time helpers), an arbitrary zone like the client's old New York default. Decide on a better default (the server's own zone?) - Found in case 4739: reports rendered by the server for customer notifications use the subscription's time zone, and when it is empty `resource/rpt/ay-report.js` falls back to `America/Winnipeg` (date, time and date-time helpers), an arbitrary zone like the client's old New York default. Decide on a better default (the server's own zone?)
- Found in case 4683 (pre-existing, raven-client and sockeye-client): the **Today** and **Now** buttons of the date, date-time and time pickers (`components/date-time-control.vue`, `time-control.vue`) take the date and time from the browser's own clock (`DateTime.local()`), not from the user's time zone override. The moment set by Now is still right (the time carries the browser's offset), but for a user whose override zone is far from the browser's zone, Today near midnight can pick the neighbouring day - Found in case 4683 (pre-existing, raven-client and sockeye-client): the **Today** and **Now** buttons of the date, date-time and time pickers (`components/date-time-control.vue`, `time-control.vue`) take the date and time from the browser's own clock (`DateTime.local()`), not from the user's time zone override. The moment set by Now is still right (the time carries the browser's offset), but for a user whose override zone is far from the browser's zone, Today near midnight can pick the neighbouring day

View File

@@ -22,6 +22,7 @@ IN PROGRESS
- Server: the server log now records the next automatic backup time (or that automatic backup is off) each time the server starts. - Server: the server log now records the next automatic backup time (or that automatic backup is off) each time the server starts.
- Backup: the [number of backups to keep](ops-form-backup.md#number-of-backups-to-keep) can no longer be set below 1; a setting of 0 already kept the most recent backup, the same as 1. - Backup: the [number of backups to keep](ops-form-backup.md#number-of-backups-to-keep) can no longer be set below 1; a setting of 0 already kept the most recent backup, the same as 1.
- User interface: in some cases, when the web browser could not identify its time zone, dates and times were shown and entered in New York time; the browser's own offset from UTC is now used instead. A [time zone override](ay-start-localization.md#time-zone-override) in user options always takes precedence. - User interface: in some cases, when the web browser could not identify its time zone, dates and times were shown and entered in New York time; the browser's own offset from UTC is now used instead. A [time zone override](ay-start-localization.md#time-zone-override) in user options always takes precedence.
- Email: report PDF files attached to customer notification emails now have the standard PDF content type; mail programs already opened them by their .pdf name.
### AyaNova 8.3.0 ### AyaNova 8.3.0

View File

@@ -48,7 +48,8 @@ namespace AyaNova.Util
if (!string.IsNullOrWhiteSpace(attachPDFPath)) if (!string.IsNullOrWhiteSpace(attachPDFPath))
{ {
var attachment = new MimePart("application/pdf", "pdf") //case 4761: media type and subtype, was ("application/pdf", "pdf") which made the content type application/pdf/pdf
var attachment = new MimePart("application", "pdf")
{ {
Content = new MimeContent(File.OpenRead(attachPDFPath), ContentEncoding.Default), Content = new MimeContent(File.OpenRead(attachPDFPath), ContentEncoding.Default),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),