feat(orders): add employee only internal order notes #14

Open
dsel wants to merge 1 commits from jd-feat/Add-internal-order-notes into master
Collaborator

Summary

Adds employee-only internal notes to order details so ops staff can record follow-up context directly on an order. Notes are persisted and visible when the order is reopened.

Ticket / Assignment

What changed

  • Added POST /api/orders/:orderId/notes for employee users to save internal notes.
  • Added backend validation to trim notes and reject whitespace-only or over-1,000-character submissions.
  • Added an internal notes form with a character count, disabled save states, and a quick scroll/focus action on the order detail page.
  • Added web API and page-level wiring for saving notes.
  • Added nullable order notes to the database schema and shared order detail contract, with initialization support for existing databases.
  • Verified the existing assignment tests covering employee access, persistence, customer rejection, empty notes, and length validation.

How to test

Executed successfully using Windows Bun:

bun.exe test apps/api/src/orders/order-notes-assignment-2.test.ts

Result: 5 passed, 0 failed, 10 assertions.

Additional automated checks completed using Windows Bun:

bun.exe run check
bun.exe run test
bun.exe run build:web
bun.exe test apps/api/src/orders/order-search-assignment-1.test.ts
  • API typecheck: fails with TS2322 at apps/api/src/orders/order-search-assignment-1.test.ts:28 because the existing cookie helper can return undefined. Assignment tests must not be modified; the temporary helper change is no longer present.
  • Web typecheck: passed separately with bun.exe run check:web.
  • Full test suite: 16 passed, 0 failed, 34 assertions across 4 files.
  • Web production build: passed.

The full suite passed with the original assignment test helper. The combined typecheck was rerun after confirming that helper was restored and still fails with TS2322. Tests use in-memory databases and request injection; no listening server was started.

Manual UI testing: passed, as confirmed by the PR author.

Manual checks:

  • Log in as an employee, open an order, add internal notes, and confirm they appear after saving.
  • Reload or revisit the order detail page and confirm saved notes persist.
  • Edit existing notes and confirm saving replaces the previous value.
  • Confirm whitespace-only notes and notes over 1,000 characters cannot be saved.

Screenshots or recordings

image.png

Risks / follow-ups

  • Saving replaces the current notes field rather than appending a note history.
  • Note changes are not currently written to the audit timeline.
  • Runtime tests resolve update-order-notes.ts successfully, and the latest API typecheck reports no missing-module diagnostic for it. The editor display itself has not been checked.
  • The combined typecheck remains blocked by the existing assignment test typing error; assignment tests are not to be modified.
  • Review line-ending-only changes before submitting and ensure the new apps/api/src/orders/update-order-notes.ts and apps/web/src/orders/order-notes-form.tsx files are included.
  • Existing-database upgrade behavior still needs verification. Manual browser/UI testing passed, as confirmed by the PR author.

PR checklist

  • change is scoped to one ticket or one small reviewable concern
  • acceptance criteria were checked
  • code follows CONTRIBUTING.md (reviewed notes feature layering and naming)
  • no unrelated refactor is mixed in
  • debug code and temporary logs are removed (none found in the reviewed feature changes)
  • relevant automated checks were run locally
  • changed behavior was manually tested when needed (PR author confirmed manual UI testing passed)
  • known risks or follow-ups are called out
## Summary Adds employee-only internal notes to order details so ops staff can record follow-up context directly on an order. Notes are persisted and visible when the order is reopened. ## Ticket / Assignment - Ticket: [Assignment 2 - Internal order notes](https://git.letphil.com/derrick/ai-wave-02/issues/9) ## What changed - Added `POST /api/orders/:orderId/notes` for employee users to save internal notes. - Added backend validation to trim notes and reject whitespace-only or over-1,000-character submissions. - Added an internal notes form with a character count, disabled save states, and a quick scroll/focus action on the order detail page. - Added web API and page-level wiring for saving notes. - Added nullable order notes to the database schema and shared order detail contract, with initialization support for existing databases. - Verified the existing assignment tests covering employee access, persistence, customer rejection, empty notes, and length validation. ## How to test Executed successfully using Windows Bun: ```bash bun.exe test apps/api/src/orders/order-notes-assignment-2.test.ts ``` Result: **5 passed, 0 failed, 10 assertions**. Additional automated checks completed using Windows Bun: ```bash bun.exe run check bun.exe run test bun.exe run build:web bun.exe test apps/api/src/orders/order-search-assignment-1.test.ts ``` - API typecheck: fails with TS2322 at `apps/api/src/orders/order-search-assignment-1.test.ts:28` because the existing cookie helper can return `undefined`. Assignment tests must not be modified; the temporary helper change is no longer present. - Web typecheck: passed separately with `bun.exe run check:web`. - Full test suite: 16 passed, 0 failed, 34 assertions across 4 files. - Web production build: passed. The full suite passed with the original assignment test helper. The combined typecheck was rerun after confirming that helper was restored and still fails with TS2322. Tests use in-memory databases and request injection; no listening server was started. Manual UI testing: **passed**, as confirmed by the PR author. Manual checks: - Log in as an employee, open an order, add internal notes, and confirm they appear after saving. - Reload or revisit the order detail page and confirm saved notes persist. - Edit existing notes and confirm saving replaces the previous value. - Confirm whitespace-only notes and notes over 1,000 characters cannot be saved. ## Screenshots or recordings ![image.png](/attachments/7032fbd7-155e-49dc-85f5-27a7d165cc34) ## Risks / follow-ups - Saving replaces the current notes field rather than appending a note history. - Note changes are not currently written to the audit timeline. - Runtime tests resolve `update-order-notes.ts` successfully, and the latest API typecheck reports no missing-module diagnostic for it. The editor display itself has not been checked. - The combined typecheck remains blocked by the existing assignment test typing error; assignment tests are not to be modified. - Review line-ending-only changes before submitting and ensure the new `apps/api/src/orders/update-order-notes.ts` and `apps/web/src/orders/order-notes-form.tsx` files are included. - Existing-database upgrade behavior still needs verification. Manual browser/UI testing passed, as confirmed by the PR author. ## PR checklist - [x] change is scoped to one ticket or one small reviewable concern - [x] acceptance criteria were checked - [x] code follows `CONTRIBUTING.md` (reviewed notes feature layering and naming) - [x] no unrelated refactor is mixed in - [x] debug code and temporary logs are removed (none found in the reviewed feature changes) - [x] relevant automated checks were run locally - [x] changed behavior was manually tested when needed (PR author confirmed manual UI testing passed) - [x] known risks or follow-ups are called out
dsel added 1 commit 2026-09-24 22:58:47 +00:00
Feat added internal notes
Runner Test / test (pull_request) Successful in 15s
Runner Test / test (push) Successful in 15s
bbf6a90e18
dsel changed title from Feat added internal notes to feat(orders): add employee only internal order notes 2026-09-24 22:59:36 +00:00
@@ -0,0 +4,4 @@
export async function changeOrderNotes(context: DatabaseContext, input: { orderId: string; notes: string }) {
const notes = input.notes.trim();
if (!notes || Array.from(input.notes).length > 1000) {
Owner

It would be better to not hard code values here.

It would be better to not hard code values here.
@@ -0,0 +19,4 @@
{notes ? <p className="mb-3 whitespace-pre-wrap break-words rounded-lg border border-slate-200 p-3 text-sm text-slate-700">{notes}</p> : null}
<form onSubmit={async (event) => {
event.preventDefault();
if (isSaving || !draft.trim() || length > 1000) return;
Owner

It would be better to not hard code values here, and the other spots in this component as well.

It would be better to not hard code values here, and the other spots in this component as well.
@@ -0,0 +31,4 @@
{notes ? "Edit internal notes" : "Add a note for your teammates"}
</label>
<textarea
id="internal-order-notes"
Owner

Should add a maxLength to the textarea for UX

Should add a `maxLength` to the textarea for UX
@@ -64,11 +64,13 @@ export function OrderPage() {
setOrder(nextOrder);
await refreshOrder(orderId);
setToast({ message: successMessage, variant: "success" });
return true;
Owner

A little unsure why these needed to be added.

A little unsure why these needed to be added.
Owner

PR is too wordy, a lot of the test information is not needed. Just give the reviewer short and concise instructions on the command for running tests, and how to test manually. Would be better to shorten several parts of the descriptions. I'd expect some back and forth at work with this PR, but it's a good learning opportunity if you receive a lot of comments. But good job on getting assignment 2 tests to pass.

PR is too wordy, a lot of the test information is not needed. Just give the reviewer short and concise instructions on the command for running tests, and how to test manually. Would be better to shorten several parts of the descriptions. I'd expect some back and forth at work with this PR, but it's a good learning opportunity if you receive a lot of comments. But good job on getting assignment 2 tests to pass.
All checks were successful
Runner Test / test (pull_request) Successful in 15s
Runner Test / test (push) Successful in 15s
This pull request has changes conflicting with the target branch.
  • apps/api/src/db/init-db.ts
  • apps/api/src/orders/order-routes.ts
  • apps/web/src/orders/order-detail-page.tsx
  • apps/web/src/orders/order-page.tsx
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin jd-feat/Add-internal-order-notes:jd-feat/Add-internal-order-notes
git checkout jd-feat/Add-internal-order-notes
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: derrick/ai-wave-02#14