toga-ai 1.0.598 → 1.0.599

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ project: TOGa Desk
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-07-09
9
+ updated: 2026-08-17
10
10
  owners: ["mhammontree"]
11
11
  files:
12
12
  - desk/includes/controllers/actions/tickets/add.php
@@ -52,6 +52,32 @@ downstream repair-order lifecycle (dispatch, scheduling, status) lives in
52
52
  `RepairOrder`. In the `TYPE_ONSITESERVICE` branch it reads optional per-asset fields
53
53
  (`installation`, `access-instructions`) — see the getVar gotcha below.
54
54
 
55
+ ### Schedule dates are mandatory for INSTALLATION (analyst workflow — TRUE-80338)
56
+ **Creating an Installation MSO now requires both Delivery Date (`duedate`) and Installation Date
57
+ (`install-date`).** Analysts can no longer create an unscheduled installation.
58
+
59
+ - **The Schedule toggle is not offered for installation tickets.** The installation ticket-type
60
+ handler (`addNew.php` ~L1919–1928) force-checks `#scheduler`, adds `.required` to `#duedate` and
61
+ `#install-date`, shows `.schedule-required-indicator`, and **hides** `.schedule-toggle` (a class
62
+ on both the "Schedule" caption label and the switch label). Picking Support / New Equipment /
63
+ Repair restores the toggle, hides the indicator, and removes `.required` — those types keep the
64
+ dates optional.
65
+ - **The asterisk is a toggled `<span class="schedule-required-indicator"> *</span>`**, not label
66
+ text, because the same Schedule block is shared with Repair, where the dates stay optional.
67
+ - **Server-side backstop, before the first `save()`.** `add.php` ~L49–55 computes
68
+ `$scheduleDatesRequired` from the ticket type and `$scheduleDatesProvided` from the two dates,
69
+ and folds the guard into the existing `if (isset($ticketType) && …)` — the single `if` that
70
+ encloses **every** `save()`. Rejection reuses the existing generic status code `21`
71
+ (add-failed); a precise message would need a `statuscodes` migration and was left out of scope.
72
+ - **The date writes no longer depend on `scheduler` being posted:** ~L361 is
73
+ `if ($scheduleDatesRequired || (App_Page::varIsSet('scheduler') && …))`, and both dates are read
74
+ with `getVarIfSet()`, per the getVar gotcha below.
75
+ - **Support Department (`#departmentid`) is genuinely required** and its label now says
76
+ "Support Department *". It is enforced three ways: `class="required"` on the select feeds the
77
+ `.required` sweep that gates the disabled Create button; that sweep carries an extra explicit
78
+ `$('#departmentid').val() != 0` check (~L1821); and `add.php` reads it with the **throwing**
79
+ `getVar('departmentid')`.
80
+
55
81
  ### Address sourcing — per-person vs. client location (important)
56
82
  There are **two** address sources, and they come from different tables:
57
83
  - **End User Address dropdown (`#userlocation`)** is per **person**. `getinfo.php` (uid branch,
@@ -96,11 +122,40 @@ End User dropdown. Dropping that UNION is **long-standing, not a recent regressi
96
122
  deadlock. **Fix:** the validator now also reads `newAddressCount = parseInt($('#newAddressCount')
97
123
  .val())||0` and only blocks when `selectedValue == 0 AND newAddressCount == 0`, since the server
98
124
  already supports the inline address.
125
+ - **Never `disable` a checkbox you still need posted.** For the forced-on Schedule case, `#scheduler`
126
+ is kept **checked and enabled** while hidden. A disabled checkbox does not post, so disabling it
127
+ would have silently stopped `scheduler=1` from reaching the server while everything still looked
128
+ correct in the UI. Hide, don't disable.
129
+ - **Validate before the first `save()`, not where the value is consumed.** The create block in
130
+ `add.php` writes people → addresses → managed service order → assets → repair orders in sequence
131
+ inside one `if`. Rejecting later (e.g. inside the per-asset loop at the `TYPE_ONSITESERVICE`
132
+ branch, where the dates are actually used) leaves **orphaned partial records**. There is no
133
+ transaction wrapping this flow.
134
+ - **`.required` classes toggled per ticket type must be cleared on every branch.** A pre-existing
135
+ leak added `.required` to `#duedate`/`#install-date` when Installation was picked but never
136
+ removed it, so it persisted after switching ticket type and wrongly gated the Create button. All
137
+ three non-installation handlers now `removeClass("required")`. Any new conditional required field
138
+ needs a matching clear in **every** sibling branch.
139
+ - **Label convention in this modal:** always-required fields append a literal `" *"` in the label
140
+ text (Ticket Type *, Contract *, End User *, Asset *, Repair Type *, First Name *, Support
141
+ Department *). **Conditionally**-required fields must instead use a toggled indicator span (see
142
+ `.schedule-required-indicator`) so the asterisk disappears with the requirement.
143
+ - **Known cosmetic bug (unfixed):** the Client radio-group label (`addNew.php` ~L27) is
144
+ `for="departmentid"` — a copy-paste leftover — so clicking "Client" moves focus to the Support
145
+ Department dropdown. A11y/cosmetic only; candidate follow-up ticket.
99
146
  - The addNew modal has **no `<form>` tag of its own** — it depends entirely on the global
100
147
  `#formModal` in `footer.php` and `$("form").submit()`. Anything that alters that global wrapper
101
148
  (attributes, nesting) affects this flow.
102
149
 
103
150
  ## Change history
151
+ - 2026-08-17 — TRUE-80338: **Delivery Date + Installation Date are now required for INSTALLATION
152
+ MSOs** (analyst workflow change — demoed to Skyler and approved). The Schedule toggle is hidden
153
+ and force-checked for installation tickets; the asterisks are a toggled
154
+ `.schedule-required-indicator` span; a server-side backstop in `add.php` validates both dates
155
+ before the first `save()` (reusing status code 21) so a rejection cannot orphan partial records.
156
+ Also fixed a pre-existing `.required` leak on the two date fields when switching ticket type, and
157
+ added the missing required asterisk to Support Department. Recorded the "hide, don't disable a
158
+ checkbox you need posted" trap and the modal's required-label convention. (mhammontree)
104
159
  - 2026-07-09 — TRUE-80100: documented the MSO create flow (entry, server action, per-person vs.
105
160
  client-location address sourcing) and folded in three fixes: `getVar` → `getVarIfSet` for
106
161
  optional request vars in the `TYPE_ONSITESERVICE` branch (server crash); `autocomplete` on
@@ -19,7 +19,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
19
19
  ## 2.0 framework
20
20
 
21
21
  - **_underscore** (_Underscore) _(framework core)_ — 58 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
22
- - **worker2** (Worker) — 50 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
22
+ - **worker2** (Worker) — 51 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
23
23
  - **api2** (API) — 24 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
24
24
  - **dbchanges2** (Database Changes) _(framework core)_ — 8 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
25
25
  - **toga2-supply** (TOGa Supply) — 6 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.598",
3
+ "version": "1.0.599",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",