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.
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
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

## 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
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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
POST /api/orders/:orderId/notesfor employee users to save internal notes.How to test
Executed successfully using Windows Bun:
Result: 5 passed, 0 failed, 10 assertions.
Additional automated checks completed using Windows Bun:
apps/api/src/orders/order-search-assignment-1.test.ts:28because the existing cookie helper can returnundefined. Assignment tests must not be modified; the temporary helper change is no longer present.bun.exe run check:web.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:
Screenshots or recordings
Risks / follow-ups
update-order-notes.tssuccessfully, and the latest API typecheck reports no missing-module diagnostic for it. The editor display itself has not been checked.apps/api/src/orders/update-order-notes.tsandapps/web/src/orders/order-notes-form.tsxfiles are included.PR checklist
CONTRIBUTING.md(reviewed notes feature layering and naming)Feat added internal notesto feat(orders): add employee only internal order notes@@ -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) {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;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><textareaid="internal-order-notes"Should add a
maxLengthto the textarea for UX@@ -64,11 +64,13 @@ export function OrderPage() {setOrder(nextOrder);await refreshOrder(orderId);setToast({ message: successMessage, variant: "success" });return true;A little unsure why these needed to be added.
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.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.