Commit graph

1133 commits

Author SHA1 Message Date
Alexandre Brandizzi
e3afa182d6
Merge branch 'main' into fix/ab/sh-380-completion-pdf-post-upload-error 2026-09-18 19:09:44 -03:00
Alexandre Brandizzi
d7ee290b1d
Merge pull request #202 from Sea-Haven-Industries/fix/ab/sh-364-inline-technician-registration
Some checks failed
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy Web / Resolve target (push) Waiting to run
Deploy Web / Deploy SPA to (push) Blocked by required conditions
Terraform CI / terraform (push) Has been cancelled
SH-364, SH-365, SH-366: register inline technicians from work-order flows
2026-09-18 19:09:19 -03:00
Alexandre Brandizzi
4d3dd82afb
Merge branch 'main' into fix/ab/sh-364-inline-technician-registration 2026-09-18 18:58:01 -03:00
Alexandre Brandizzi
29caecd449
Merge branch 'main' into feat/ab/sh-304-services-registry-ui 2026-09-18 18:57:58 -03:00
Alexandre Brandizzi
e1b03dc151
Merge branch 'main' into feat/ab/sh-382-extra-doc-view 2026-09-18 18:57:56 -03:00
Alexandre Brandizzi
5766616cc0
Merge branch 'main' into fix/ab/sh-380-completion-pdf-post-upload-error 2026-09-18 18:57:53 -03:00
Adam Moussa
999f1f03fa
Merge branch 'main' into refactor/dispatch-detail-modal-split-v2 2026-09-18 17:49:02 -04:00
Adam Moussa
148f5f1823
Merge pull request #235 from Sea-Haven-Industries/chore/drop-pointer-cd-leftovers
chore(cd): drop leftover pointer-cd scripts and cutover docs
2026-09-18 17:25:35 -04:00
0c867e2cb4
chore(cd): drop leftover pointer-cd scripts and cutover docs
GitHub Actions already owns SPA bytes, so the unused pointer scripts
and the stale greenlight checklist should not stay in tree.
2026-09-18 17:13:32 -04:00
Adam Moussa
2600234b89
Merge pull request #233 from Sea-Haven-Industries/chore/staging-adoption-complete
Some checks are pending
Terraform CI / terraform (push) Waiting to run
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy Web / Resolve target (push) Waiting to run
Deploy Web / Deploy SPA to (push) Blocked by required conditions
chore(terraform): complete staging SPA adoption
2026-09-18 16:57:34 -04:00
Adam Moussa
1199252673
Merge branch 'main' into chore/staging-adoption-complete 2026-09-18 16:45:04 -04:00
Adam Moussa
daa590622b
Merge pull request #234 from Sea-Haven-Industries/fix/skip-sourcemaps-without-sentry-cli
fix(cd): skip source-map upload when sentry-cli is absent
2026-09-18 16:41:31 -04:00
ae852f15ea
fix(cd): skip source-map upload when sentry-cli is absent
August SPA trees have no @sentry/cli. Skipping that step lets a
workflow_dispatch of the live staging SHA finish the S3 sync.
2026-09-18 16:27:25 -04:00
Adam Moussa
fa9e60ce0b
Merge branch 'main' into chore/staging-adoption-complete 2026-09-18 16:23:41 -04:00
Adam Moussa
6f4b3d0e43
Merge pull request #232 from Sea-Haven-Industries/fix/deploy-scripts-from-workflow-sha
fix(cd): run deploy scripts from the workflow SHA
2026-09-18 16:23:16 -04:00
7b37529006
chore(terraform): complete staging SPA adoption
Pin staging adoption_complete to true so tags and the bucket policy
match the already-adopted dev root.
2026-09-18 16:14:10 -04:00
c99273d3fc
fix(cd): run deploy scripts from the workflow SHA
An old content ref has no upload/verify scripts. Copy those from
github.workflow_sha so dispatch of a live SHA can finish.
2026-09-18 16:09:58 -04:00
Alexandre Brandizzi
8d50c6f75e fix(work-orders): stop the stale-version docStatus patch after a signed PDF upload (SH-380)
The completion-doc upload endpoint sets DocStatus=Yes and bumps the work-order row
version in one transaction. Both signed-PDF upload paths then re-ran a "docStatus=Yes"
work-order patch using the pre-upload row version (the comp-doc dialog re-ran the whole
Generate flow; the slide-over posted docStatus directly). That patch always 409'd — and
in the dialog it also demanded a Date Work Completed — so a successful upload surfaced an
error to the user.

Both paths now stop after the upload settles: the mutation's onSuccess refreshes the
board and the UI reflects the generated state locally, with no second docStatus patch.
2026-09-18 16:59:24 -03:00
Adam Moussa
95f0342271
Merge pull request #229 from Sea-Haven-Industries/dev
Some checks are pending
Terraform CI / terraform (push) Waiting to run
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy Web / Resolve target (push) Waiting to run
Deploy Web / Deploy SPA to (push) Blocked by required conditions
chore: promote GitHub-owned SPA onto main
2026-09-18 15:44:21 -04:00
Alexandre Brandizzi
1a7a4ba58f fix(work-orders): open extra documents without credentialed CORS (SH-382)
Viewing a work-order extra document called the authorized content endpoint
with `credentials: "include"`. The API replies `Access-Control-Allow-Origin: *`,
and in credentialed mode the browser rejects a wildcard origin outright, so the
fetch threw, `openExtraDocContent` fell into its catch, closed the tab and
toasted "Unable to open this document." — QA CT-03.

The endpoint authenticates with the bearer token the ky beforeRequest hook
attaches, not cookies, so credentials mode was dead weight. List, upload and
delete never set it, which is why only viewing failed. Drop the option and
guard the request shape in a test (JSDOM cannot enforce CORS).
2026-09-18 16:35:01 -03:00
0bf834bb8e
fix(cd): keep .env.production Sentry DSN when the GitHub var is empty
An unset vars.VITE_SENTRY_DSN becomes an empty env value and Vite will
not let .env.production overwrite it, which would ship with Sentry off.
2026-09-18 15:26:55 -04:00
7ed0743b90
fix(terraform): pin SSM deploy parameter tier and data_type
HCP tried to replace the live parameters on refresh because those
attributes were computed. The apply role cannot DeleteParameter.
2026-09-18 15:09:56 -04:00
Adam Moussa
bd79617aa2
Merge branch 'main' into dev 2026-09-18 15:08:29 -04:00
ceecab5438
fix(cd): ignore githubdeploy description and retire leftover pointer CD
SCP denies UpdateRoleDescription on githubdeploy-*, so HCP apply cannot
rewrite the role description. Pointer workflows must not land on main.
2026-09-18 15:04:51 -04:00
Adam Moussa
c96a259365
refactor(cd): ship SPA content from GitHub on main (#220)
Some checks failed
Deploy dev content / Deploy shoc-frontend-new-dev through Terraform (push) Has been cancelled
* ci(cd): convert SPA hosting to handbook HCP and GitHub content CD

Give HCP the bucket and CloudFront with an empty origin path. GitHub owns
bucket-root sync and invalidation so merge-to-main and a human staging tag
can deploy without creating HCP runs. G13 fails PRs that mix terraform/
with deployable application files.

* ci: run Frontend checks and Terraform CI on PRs to main and dev

Match backend 148 so a PR targeting origin/dev still gets the required
checks. Push remains main only.

* refactor(terraform): keep live/dev and live/staging as HCP roots

Leave the adopted working directories in place so this CD PR does not
retarget two live HCP workspaces. Flattening stays a later change.

* style: prettier terraform-validate.mjs

* fix(terraform): pin githubdeploy assume-role policy in import checker

Reject controlled role updates whose trust document is not the rendered
GitHub OIDC policy, matching the bucket-policy pin.
2026-09-18 14:30:20 -04:00
Adam Moussa
ff79c9d56e
Merge pull request #221 from Sea-Haven-Industries/dev
Some checks are pending
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
chore: promote current dev onto main
2026-09-18 14:25:41 -04:00
Codex Review Integration
84568dd737 refactor(workorders): extract board patch api module
work-orders-api.ts exceeded the 500-line godfile cap after adding
updatePoc. Move patchBoardField/updatePoc and their shared response
handling into work-order-board-patch-api.ts and re-export through
workOrdersApi, mirroring workOrderBoardDocumentsApi.
2026-09-18 15:03:59 -03:00
Codex Review Integration
3b1da21abb fix(workorders): preserve partial POC edits 2026-09-18 15:00:01 -03:00
Codex Review Integration
ff1a946e74 Merge remote-tracking branch 'origin/feat/ab/sh-292-notification-center' into HEAD
# Conflicts:
#	src/app/(protected)/workorders/_hooks/use-work-orders-list-page.ts
2026-09-18 14:46:02 -03:00
Codex Review Integration
5b0c758a9f fix(workorders): persist manual POC edits via dedicated POC endpoint (SH-379)
The UI dropped manual POC edits before they reached the API: the patch
mapper listed pocName/pocPhone/pocNotes as local-only keys and the
slide-over draft excluded them from Save, so the optimistic edit vanished
on refetch and the completion freeze captured the Site contact instead.

- Emit one composite POC op from table patches and route it through a new
  workOrdersApi.updatePoc (PATCH workorders/{id}/poc), reusing the board
  patch row/error contract (409 conflict with currentState, 422 validation).
- Include POC scalars in slide-over edit keys so dirty state and Save carry
  them; site dialog and slide-over now both persist POC edits.
2026-09-18 14:44:06 -03:00
Codex Review Integration
8b122ad71c fix: satisfy governance hook line limits 2026-09-18 14:38:27 -03:00
Codex Review Integration
75c2c1c1fa Merge remote-tracking branch 'origin/feat/ab/sh-292-notification-center' into HEAD
# Conflicts:
#	src/app/(protected)/workorders/_components/detail/use-slide-over-edit-state.ts
#	src/app/(protected)/workorders/_components/detail/use-work-order-slide-over.ts
#	src/app/(protected)/workorders/_components/detail/work-order-slide-over.tsx
#	src/app/(protected)/workorders/_components/list/work-orders-list-page-panels.tsx
#	src/app/(protected)/workorders/_hooks/use-work-orders-list-page.ts
2026-09-18 14:35:17 -03:00
Codex Review Integration
062a1e26c8 fix: resolve notification review findings 2026-09-18 14:23:43 -03:00
albrand
74e7c526e8 fix(notifications): re-open tab and match API mentions for event highlights
Re-apply the requested slide-over tab on every open via an open counter, so a
second comment/mention notification for the work order already on screen still
switches to Comments and re-scrolls to the highlighted comment. Treat a board
comment's mentions id array (plain @Name text) as a mention alongside encoded
@[id:name] tokens so mention items highlight and comment items exclude them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-18 14:01:55 -03:00
Codex Review Integration
de1c23b118 Merge remote-tracking branch 'origin/feat/ab/sh-292-notification-center' into feat/ab/sh-288-event-notifications 2026-09-18 13:54:07 -03:00
Codex Review Integration
edd2e7efe2 test(visual): refresh mobile navigation baseline for the notification bell 2026-09-18 13:52:00 -03:00
Codex Review Integration
299f471612 Merge commit '988c96c' into feat/ab/sh-288-event-notifications
# Conflicts:
#	src/components/notifications/notification-row.tsx
#	src/components/notifications/use-notification-center.ts
#	src/domain/notifications/utils/notification-target-url.ts
2026-09-18 13:43:48 -03:00
Codex Review Integration
ae941bc93d feat(notifications): open comment, mention, assignment and uplift items where they happened
Comment and mention items open the work order on the Comments tab with the
comments they were raised for highlighted; a grouped assignment opens the
dispatcher's own open queue; uplift decisions open the work order's uplifts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 13:42:13 -03:00
Codex Review Integration
988c96c42d fix(notifications): keep vendor reminder actions and refresh header baselines
No Vendor opens the work order form on vendor assignment and Vendor Conflict
links each work order, as the vendor reminders did. Header baselines include the
notification bell, and the top bar user menu moves to its own component to stay
within the function-size gate. The vendor e2e now covers the feed contract.
2026-09-18 13:34:12 -03:00
Codex Review Integration
33d0ab4fd6 test(uplifts): scope modal permission and date assertions to what they prove
The permission spec asserts the work order renders from the queue item
and, separately, that only the approved-on-WO breakdown degrades to
Unavailable. The Requested At assertion derives the local calendar day
so it holds in every runner time zone.
2026-09-18 13:02:11 -03:00
Codex Review Integration
dcf944d7dc SH-292: Notification Center bell panel and feed page
Header bell panel and /notifications page share one feed from GET /api/notifications: labeled sections with live counts, unread styling, session-only dismiss and clear all (acknowledge rows excluded), and deep links to the unassigned queue and a work order's tab via ?wo=&tab=.
2026-09-18 12:55:54 -03:00
Codex Review Integration
3c84d851c0 feat(uplifts): align uplift detail modal with SH-209
Two sections, Work order and Uplift request, divided by a single rule.
Work order shows Service, Vendor / Technician, Assigned Dispatcher and
Scheduled from the queue item, so it no longer fetches the work order
and no longer degrades to Unavailable for account-scoped staff. Uplift
request shows Requested By, Requested At, the justification in a
bordered block, the approved-on-WO breakdown and a horizontal
attachment row whose chips open the evidence in a new tab. Every field
renders data or an explicit placeholder. The footer shows Reject and
Approve for pending uplifts, Revoke for approved ones and nothing for
read-only records; closing is the header X.
2026-09-18 12:53:55 -03:00
npal
62e5d46b0f fix: address PR #224 review findings and extract task-template copy (SH-378)
Three real behavior deltas flagged in review, each closing a gap
against the "no behavior change" claim:

- use-vendor-portal-session.ts: add retry:false and
  meta:{suppressErrorToast:true} so an invalid/expired token fails
  fast with a single request and no duplicate global toast (this was
  also the root cause of the failing e2e test - the toast and the
  inline error message both had role="alert", tripping a strict-mode
  locator match)
- task-template-schema.ts: trim the name before validating so a
  whitespace-only name is rejected, matching the old manual
  form.name.trim() check
- task-template-detail-form.tsx: block Enter-triggered implicit
  submission on the Template Name / Description inputs, since the
  original page had no <form> element and Enter did nothing
- task-template-items-field.tsx: surface a visible error when a
  loaded item has empty text, since the schema already blocked save
  in that case but gave no way to see why; use-task-template-editor.ts
  now eagerly validates after loading a template so this reflects
  reality immediately instead of only after an unrelated edit

Also extract every user-facing string in the task-templates feature
into TASK_TEMPLATE_COPY (task-template-constants.ts) instead of
inline literals scattered across 5 files.

6 new regression tests cover all of the above; full suite (36 tests
across the 2 refactored areas) still green.
2026-09-18 10:46:16 -05:00
Alexandre Brandizzi
c9562650ca
Merge branch 'dev' into fix/ab/sh-364-inline-technician-registration 2026-09-18 11:59:16 -03:00
Alexandre Brandizzi
e780bafdd8
Merge branch 'dev' into feat/ab/sh-304-services-registry-ui 2026-09-18 11:59:13 -03:00
npal
5645c7e02b Merge remote-tracking branch 'origin/dev' into refactor/dispatch-detail-modal-split-v2 2026-09-17 18:10:34 -05:00
npal
a93747f119 refactor(vendor-portal,settings): move state and fetch logic into hooks (SH-378)
vendor-portal-provider.tsx and task-templates.tsx mixed data-fetching,
state, and rendering in one file, with no caching and hand-rolled form
state. This is a pure refactor with no behavior change.

- vendor-portal-provider.tsx: replace manual useEffect/useState fetch
  with useVendorPortalSession (useQuery), closing the token race
  condition the old key={token} remount was working around
- task-templates.tsx: split into useTaskTemplateEditor hook plus 4
  presentational components; replace hand-rolled form state with
  react-hook-form + zod validation; replace the "new" string sentinel
  with a NEW_TEMPLATE_ID constant
- add 29 tests (hook, component, and full-page integration) confirming
  identical behavior to the original code
2026-09-17 18:05:06 -05:00
Alexandre Brandizzi
d6510b262e
Merge pull request #193 from Sea-Haven-Industries/fix/ab/sh-339-wizard-complete-image
Some checks failed
Deploy dev content / Deploy shoc-frontend-new-dev through Terraform (push) Waiting to run
Frontend checks / Build and test (push) Has been cancelled
Frontend checks / governance (push) Has been cancelled
Frontend checks / Visual regression (push) Has been cancelled
SH-339: Allow completing Reactive/Emergency WOs from the side panel after photo upload
2026-09-17 16:14:07 -03:00
Alexandre Brandizzi
5f2d120965
Merge branch 'dev' into fix/ab/sh-339-wizard-complete-image 2026-09-17 16:02:15 -03:00
Alexandre Brandizzi
29b75e18de
Merge pull request #203 from Sea-Haven-Industries/fix/ab/sh-368-completion-uploads
SH-368: preserve multipart upload Content-Type
2026-09-17 16:00:15 -03:00