diff --git a/devdocs/modernization/NET10-PORT.md b/devdocs/modernization/NET10-PORT.md index ab0ace78..8451c9fb 100644 --- a/devdocs/modernization/NET10-PORT.md +++ b/devdocs/modernization/NET10-PORT.md @@ -277,7 +277,7 @@ Found during the port, out of scope. One line each. - **Done in case 4703.** **Improvement, own case after the port (John to create):** bring back logging of JavaScript error details from report page console errors, as Sockeye's port did. AyaNova logs only `ERROR: {message text}`; the per-argument detail (`arg instanceof Error ? arg.message : arg`) is commented out at `biz/ReportBiz.cs:873-876` since case 4586, because `IJSHandle.ExecutionContext` was removed. Sockeye 8.1.0 (`server/biz/ReportBiz.cs:575`) evaluates on the handle instead: `args.Message.Args.Select(arg => arg.EvaluateFunctionAsync("(arg) => arg instanceof Error ? arg.message : arg"))`, which also needs the console handler to be `async` again - **Fixed in case 4652** (work orders, quotes and PMs now leave the missing record out; the other object types already did). Pre-existing, same in 8.2.4 (found in the 4579 sandbox test, John: Deferred): rendering a report for a record that does not exist (e.g. work order ids 1 and 2 in a trial without sample data) fails the job with a generic `ArgumentNullException` ("Value cannot be null. (Parameter 'o')") from `JObject.FromObject` in `WorkOrderBiz.GetReportData` (`WorkOrderBiz.cs:1030`), instead of skipping the missing record or saying it is not found. Other object types' `GetReportData` likely do the same - **Roles audit, case 4735 (John, 2026-10-25, this release; found in 4719):** check every object's rights as documented in the manual (each page's "Authorization Roles required" section and `ay-biz-admin-roles.md`) against `biz/BizRoles.cs`. Report templates were changeable by Business administration - restricted although the roles page uses exactly that case as its example of a view-only restricted role (fixed in 4719). If that slipped through there could be others; for each mismatch decide whether the code or the page is wrong -- Found 2026-10-27 (John: later case, no BC customers): when the browser cannot name its time zone, the client uses `America/New_York` (`raven-client` `api/locale.js` `getResolvedTimeZoneName`; Sockeye's client the same), so every date and time is shown, entered and sent to reports in New York time. Windows' new "British Columbia Standard Time" zone (BC permanent UTC−7 from November 2026) does this: Chrome returns `undefined` for it, although it knows `America/Vancouver`'s new rules. Seen on John's PC as backup times three hours late on devtest and Sockeye (the servers were right). Workaround: the time zone override in user settings. Fix: fall back to the browser's current UTC offset (fixed-offset zone) instead of New York +- **Fixed in case 4739** (the fallback is now the browser's own offset as an `Etc/GMT` zone in whole hours; Chrome and Edge 156 already name the BC zone `America/Vancouver`, and Chrome 155, which does not, also uses offset -8 for it, so a BC user on such a browser is one hour off instead of three: the time zone override remains the fix for them). Found 2026-10-27 (John: later case, no BC customers): when the browser cannot name its time zone, the client uses `America/New_York` (`raven-client` `api/locale.js` `getResolvedTimeZoneName`; Sockeye's client the same), so every date and time is shown, entered and sent to reports in New York time. Windows' new "British Columbia Standard Time" zone (BC permanent UTC−7 from November 2026) does this: Chrome returns `undefined` for it, although it knows `America/Vancouver`'s new rules. Seen on John's PC as backup times three hours late on devtest and Sockeye (the servers were right). Workaround: the time zone override in user settings. Fix: fall back to the browser's current UTC offset (fixed-offset zone) instead of New York - Found in the 8.3.0 Cypress runs (2026-10-26; pre-existing, 8.2.4 too): on a first visit over a slow connection the login page can move the keyboard focus back to the username field while it settles (the field has `v-focus` and is re-inserted when the page redraws), so part of a password typed early lands in the username field in plain view; and the service worker reloads the page once when it takes control (`App.vue`, `controllerchange`), clearing both fields. Both within the first seconds of a first visit - From case 4697 (John: Deferred): (1) a relative date range that crosses a daylight saving change can be an hour off at its far end, because the client sends only its current offset with list requests; exact would need the client to send its IANA time zone name too (front-end change). (2) Dashboard widgets group by day, week or month with `date_trunc` on the stored UTC times, so for a user far from UTC an item near midnight lands in the neighbouring bar; same need for the time zone name - From case 4727 (John: later hardening case, 2026-10-26): AyaNova runs as `www-data` on droplets and in the Linux manual (as in Microsoft's ASP.NET Core with NGINX guide), the same account as NGINX's workers, so NGINX can read `config.json` (database password) and write `data`. A dedicated `ayanova` system account isolates them: service `User=`, ownership, the setup script and the manual, plus a migration for existing droplets and self-hosted installs @@ -286,6 +286,7 @@ Found during the port, out of scope. One line each. - 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 - 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?) ## Log diff --git a/docs/8.0/ayanova/docs/changelog.md b/docs/8.0/ayanova/docs/changelog.md index 213126cd..2b94bcff 100644 --- a/docs/8.0/ayanova/docs/changelog.md +++ b/docs/8.0/ayanova/docs/changelog.md @@ -21,6 +21,7 @@ IN PROGRESS - Server: in some cases deleting a record that is still in use elsewhere (for example a customer, unit, part or rate used on a work order, quote or PM) gave a server error; it now always says which kind of record is using it. - 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. +- 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. ### AyaNova 8.3.0