Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
315 commits
Select commit Hold shift + click to select a range
462832c
Merge pull request #1086 from waritctd/feat/quotation-deal-link-s1-ba…
waritctd Sep 30, 2026
c3d5c46
feat(tickets): route the deal pipeline by entry channel
waritctd Sep 30, 2026
ec3ab2b
feat(tickets): make the deal stage panel and stepper route-aware
waritctd Sep 30, 2026
123b1e0
fix(tickets): stop the header, list and overflow menu contradicting t…
waritctd Sep 30, 2026
0de11be
feat(tickets): add the แก้ช่องทางดีล remedy where the route refusal i…
waritctd Sep 30, 2026
dbb683f
feat(tickets): serve the deal route from GET /api/meta/deal-stages
waritctd Sep 30, 2026
8923f8d
test(mock): mirror onRoute in mockStageDecisions
waritctd Sep 30, 2026
692b18a
docs(design): IA for route-aware deal staging
waritctd Sep 30, 2026
b0a5475
fix(tickets): pass the viewer role as an expression in the header test
waritctd Sep 30, 2026
dd46ebb
feat(login): dev-server quick-login row for the seeded demo accounts
waritctd Sep 30, 2026
2f30578
feat(import): import-only per-deal view + cut import off the whole de…
waritctd Sep 30, 2026
2630408
Merge pull request #1088 from waritctd/feat/deal-route-staging
waritctd Sep 30, 2026
bb3f879
wip(sales): slice 2 flow-A frontend — checkpoint before develop merge…
waritctd Sep 30, 2026
22fd171
Merge origin/develop (26304083: #1086 + #1088) into slice 2
waritctd Sep 30, 2026
949540a
feat(import): null customer money totals for import on shared summaries
waritctd Sep 30, 2026
7c41d0d
Merge remote-tracking branch 'origin/develop' into feat/import-own-page
waritctd Sep 30, 2026
5512735
fix(import): sync isInImportScope with develop's list after route-sta…
waritctd Sep 30, 2026
220ce09
feat(import): wire GET /api/import/deals/{id} into the frontend api l…
waritctd Sep 30, 2026
dd2cf7b
feat(import): port Yang's compact per-factory visual onto the deal fu…
waritctd Sep 30, 2026
1c2b937
feat(sales): slice 2 flow A — off-route recipient note, channel pre-f…
waritctd Sep 30, 2026
7024417
feat(import): import own per-deal page (ImportDealPage) + route + syn…
waritctd Sep 30, 2026
596d520
feat(import): show per-factory ETA on the tracker (deal tab + import …
waritctd Sep 30, 2026
4eb5472
fix(sales): confirm-order keyed on deal status, renamed ยืนยันคำสั่งซ…
waritctd Sep 30, 2026
c753f38
refactor(import): hallmark redesign of the import-tracking surfaces (…
waritctd Sep 30, 2026
11eda56
polish(import): impeccable polish pass on the import-tracking surfaces
waritctd Sep 30, 2026
ce86ccf
feat(import): surface per-factory ใบขอซื้อ PDF download on the import…
waritctd Sep 30, 2026
e09a997
test(e2e-real): pick สร้างดีลใหม่ before the customer search on /quot…
waritctd Sep 30, 2026
1f2b8b2
Merge pull request #1090 from waritctd/feat/quotation-deal-link-s2-fr…
waritctd Sep 30, 2026
8916738
test(e2e-real): count deny-via-redirect as a clean refusal in route-c…
waritctd Sep 30, 2026
7557585
Merge pull request #1091 from waritctd/feat/import-own-page
waritctd Sep 30, 2026
e814b7d
test: derive special-money payroll month from Bangkok zone, not JVM d…
claude Sep 30, 2026
1b4fb96
Merge pull request #1098 from waritctd/claude/hopeful-albattani-qmaqtn
waritctd Sep 30, 2026
e78661a
feat(finance): account finance-scoped, stage-synced view + VAT-inclus…
waritctd Sep 30, 2026
4692e91
Merge pull request #1095 from waritctd/claude/account-finance-scope-s…
waritctd Sep 30, 2026
e1f81ab
feat(tickets): require a real ช่องทางดีล when creating a deal
waritctd Sep 30, 2026
ee9c5ac
test(mock): mirror the entry-channel rule in mockApi.tickets.create
waritctd Sep 30, 2026
527c48b
test(mock): give quotationDealLink's deals a real entry channel
waritctd Sep 30, 2026
0e54609
test(mock): give importDeals and promoteToDeal a real entry channel
waritctd Sep 30, 2026
d27328f
Merge pull request #1092 from waritctd/feat/require-entry-channel-on-…
waritctd Sep 30, 2026
7e0dd1a
refactor(tickets): label the deal's entry-channel field เสนอแก่
waritctd Sep 30, 2026
8b71f50
Merge pull request #1093 from waritctd/feat/rename-entry-channel-sano…
waritctd Sep 30, 2026
227e13e
feat(pricing): stock lines on pricing requests — slice 1 backend (WIP)
waritctd Sep 30, 2026
d56a737
Merge pull request #1094 from waritctd/feat/pcr-stock-lines-backend
waritctd Sep 30, 2026
918fa1a
chore(ci): run only diff-related tests on PRs; full suite on push
waritctd Sep 30, 2026
2e5fd7a
fix(pricing): mirror the IMPORT_REVIEWING -> READY_FOR_CEO_REVIEW edg…
waritctd Sep 30, 2026
1a130c0
Merge pull request #1100 from waritctd/fix/pcr-meta-import-to-ceo-edge
waritctd Sep 30, 2026
159c399
Merge remote-tracking branch 'origin/develop' into chore/ci-selective…
waritctd Sep 30, 2026
1a5f4b3
feat(sales): slice 2 backend — direct-quotation recipient, one pricin…
waritctd Sep 30, 2026
ec38cc8
perf(tickets): read liveDirectQuotation in the commission-flag statement
waritctd Sep 30, 2026
113f744
test(dealquotation): adapt develop's newer fixtures to slice 2's reci…
waritctd Sep 30, 2026
99cf4ff
refactor(tickets): word S1 by the channel the deal entered through
waritctd Sep 30, 2026
517f095
Merge pull request #1097 from waritctd/feat/quotation-deal-link-s2-ba…
waritctd Sep 30, 2026
45615f0
test: red tests for finance-page invoice recording and manager item-w…
claude Sep 30, 2026
1315c14
feat(finance): record the tax invoice on the finance deal page; manag…
claude Sep 30, 2026
966714a
feat(commission): finance-view invoice block + manager per-item weigh…
claude Sep 30, 2026
91b8601
style(finance,commissions): hallmark redesign of the touched finance …
claude Sep 30, 2026
7563e05
test: HTTP wiring test + real-stack e2e for invoice recording and man…
claude Sep 30, 2026
55df165
test(e2e): send recipientType on the fixture's direct quotation (requ…
claude Sep 30, 2026
97cd371
Merge pull request #1101 from waritctd/claude/happy-dijkstra-xh991l
waritctd Sep 30, 2026
be9bfd2
fix(ci): frontend picker always includes serverContract.test.js and t…
waritctd Sep 30, 2026
a1f6eac
wip(pricing): CR-1 factory contact flow, currency lock, lead-time cha…
waritctd Sep 30, 2026
058a40c
merge: bring develop into feat/gla129-billing-note-api (resolve permi…
waritctd Sep 30, 2026
10b85f0
test(commission): team override + full monthly breakdown — tests firs…
waritctd Sep 30, 2026
4cc500c
feat(commissions): Hallmark redesign — weighting desk, rep statement,…
waritctd Sep 30, 2026
6c95fd3
fix(commissions): review round — entry-level save lock, focus, void/r…
waritctd Sep 30, 2026
c77b299
feat(commission): auto-computed team override (V197) + full monthly b…
waritctd Sep 30, 2026
06aa260
Merge origin/develop into claude/competent-williams-889ee1
waritctd Sep 30, 2026
a9ff1aa
test(commission): pin the Thai stage name (not "[object Object]") in …
waritctd Sep 30, 2026
da81fee
merge: bring feat/gla129-billing-note-api (with develop) into feat/gl…
waritctd Sep 30, 2026
cac9e60
feat(pricing): CEO prices inside รายการสินค้าและราคาตั้งต้น, types รา…
waritctd Sep 30, 2026
cf0ba8e
fix(pricing): stock ราคาตั้ง in every mode, drop ประเภทสินค้า, margin…
waritctd Sep 30, 2026
3c19e19
fix(pricing): guard stock ราคาตั้ง-only saves and early start-review …
waritctd Sep 30, 2026
ec83937
fix(commission): lock the record while re-weighting deal lines so con…
waritctd Sep 30, 2026
89fe654
Merge branch 'feat/commission-page-redesign' into claude/commission-l…
waritctd Sep 30, 2026
abf0205
fix(pricing-decisions): accept item updates that omit the clear* bool…
waritctd Sep 30, 2026
767a3df
test(pricing-decisions): round-trip all four clear* flags explicitly
waritctd Sep 30, 2026
33197d3
feat(pricing): default margin 20% -> 30% (V198, owner-requested)
waritctd Sep 30, 2026
359cacd
fix(commissions): label a negative stock uplift as a deduction, not '+'
waritctd Sep 30, 2026
cb6f305
fix(pricing): CR-1 review round — contacted fields on revision, carry…
waritctd Sep 30, 2026
3b64bac
fix(commission): null company base when no override applies; pin new …
waritctd Oct 1, 2026
62e650f
fix(commissions): hide HR team-override column and footer when no ove…
waritctd Oct 1, 2026
eea81b6
Merge branch 'feat/commission-page-redesign' into claude/commission-l…
waritctd Oct 1, 2026
6d3b3f4
chore(commission): keep employee names out of the V197 comment and te…
waritctd Oct 1, 2026
0affc11
fix(pricing): CR-1 review round 3 — IR revise from country default, u…
waritctd Oct 1, 2026
4737ab6
feat(pricing): CR-1 frontend — factory contact flow, lead-time change…
waritctd Oct 1, 2026
cd5d5d0
fix(pricing): CR-1 frontend — no horizontal scroll on factory cards, …
waritctd Oct 1, 2026
25b36c6
Merge pull request #1102 from waritctd/feat/lead-approach-label-by-ch…
waritctd Oct 1, 2026
0220191
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
0c2fef6
Merge pull request #1089 from waritctd/feat/dev-quick-login
waritctd Oct 1, 2026
866717e
Merge pull request #1099 from waritctd/chore/ci-selective-tests
waritctd Oct 1, 2026
f7c753b
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
933aaf0
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
1d883e1
fix(pricing): CR-1 seed factory-quote draft items with the requested …
waritctd Oct 1, 2026
06899b3
Merge pull request #1027 from waritctd/feat/gla129-billing-note-api
waritctd Oct 1, 2026
759c097
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
b68253a
Merge pull request #1028 from waritctd/feat/gla129-money-tab
waritctd Oct 1, 2026
281f05e
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
f0f0d62
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
9f02e65
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
d701aa1
fix(pricing): CR-1 frontend review — locked terms precedence test, op…
waritctd Oct 1, 2026
fb25a3c
chore(db): renumber CR-1 migration V196 -> V195 (stock-lines V195 pau…
waritctd Oct 1, 2026
f0229b3
chore(migration): renumber V198 -> V197 (owner ruling 2026-10-01)
waritctd Oct 1, 2026
caa631e
chore(commission): renumber team-override migration V197 -> V196 (own…
waritctd Oct 1, 2026
26f36e8
Merge remote-tracking branch 'origin/develop' into feat/gla-167-facto…
waritctd Oct 1, 2026
6a6ce17
Merge pull request #1087 from waritctd/claude/competent-williams-889ee1
waritctd Oct 1, 2026
23e2ac8
Merge remote-tracking branch 'origin/develop' into claude/commission-…
waritctd Oct 1, 2026
eda900c
test(contract): declare product-type-override unreachable from UI aft…
waritctd Oct 1, 2026
e7f1d26
Merge pull request #1104 from waritctd/fix/pricing-decision-item-requ…
waritctd Oct 1, 2026
c592232
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
3c7d8f7
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
1bfaa47
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
b7418f7
fix(sales): explain the DRAFT ใบขอซื้อ handoff per factory (QA BUG-21…
YXmaze Oct 1, 2026
b7c2960
Merge pull request #1103 from waritctd/claude/ceo-pricing-page-redesi…
waritctd Oct 1, 2026
e0a48cc
Merge remote-tracking branch 'origin/develop' into HEAD
waritctd Oct 1, 2026
e64c92c
Merge pull request #1105 from waritctd/feat/default-margin-30pct
waritctd Oct 1, 2026
415b816
chore(commission): renumber team-override migration V196 -> V199 (own…
waritctd Oct 1, 2026
8e43501
merge: bring develop (#1103 CEO pricing redesign) into feat/gla-167-f…
waritctd Oct 1, 2026
6b1e649
chore(db): renumber CR-1 migration to V198 (above V197 on develop); r…
waritctd Oct 1, 2026
30ce90a
Merge remote-tracking branch 'origin/develop' into feat/gla-167-facto…
waritctd Oct 1, 2026
478fef6
Merge remote-tracking branch 'origin/develop' into claude/commission-…
waritctd Oct 1, 2026
399ad4d
Merge pull request #1107 from waritctd/feat/gla-167-factory-contact-flow
waritctd Oct 1, 2026
32ee389
Merge remote-tracking branch 'origin/develop' into claude/commission-…
waritctd Oct 1, 2026
4f88e68
Merge pull request #1106 from waritctd/claude/commission-logic-deduct…
waritctd Oct 1, 2026
e30be6d
feat(pricing): auto-fill ตร.ม./หน่วย from item and use text inputs fo…
waritctd Oct 1, 2026
a1600d7
Merge pull request #1109 from waritctd/claude/confirm-button-text-bug…
waritctd Oct 1, 2026
1dc7c61
feat(pricing): show catalogue price in baht for the requested quantit…
waritctd Oct 1, 2026
e645ca0
feat(pricing): import's price in baht, ตร.ม./แผ่น switch and auto-cal…
waritctd Oct 1, 2026
b67aa6b
test(mock): pin the ตร.ม./แผ่น switch in the mock's unit lock
waritctd Oct 1, 2026
0e70b22
feat(pricing): CEO pre-fills ราคาพิเศษ from the formula price; ต้นทุน…
waritctd Oct 1, 2026
dbcc3e2
Merge pull request #1110 from waritctd/feat/pcr-catalogue-price-thb
waritctd Oct 1, 2026
f8ebbcc
fix(pricing): label ต้นทุน as coming from Import's price
waritctd Oct 1, 2026
475aea6
Merge pull request #1113 from waritctd/fix/pcr-cost-label
waritctd Oct 1, 2026
538b840
fix(pricing): label the CEO cost as the landed cost incl. freight and…
waritctd Oct 1, 2026
2e50226
fix(sales): gate ยืนยันคำสั่งซื้อ on ticket status before the 409 can…
waritctd Oct 1, 2026
c4061ff
Merge pull request #1114 from waritctd/fix/pcr-cost-includes-duty-fre…
waritctd Oct 1, 2026
edff089
Merge pull request #1115 from waritctd/claude/ticket-status-mismatch-…
waritctd Oct 1, 2026
5560009
feat(sales): แก้ใบเสนอราคา sticky CTA; remove deal-page quotation panel
waritctd Oct 1, 2026
8ac7644
feat(sales): offer แก้ใบเสนอราคา as a secondary action at owner/buyer…
waritctd Oct 1, 2026
4dfd40c
Merge pull request #1116 from waritctd/feat/deal-quotation-cta-cleanup
waritctd Oct 1, 2026
92f316d
fix(sales): gate import request on deposit received only, not quotati…
waritctd Oct 1, 2026
48021b8
Merge pull request #1118 from waritctd/fix/import-request-deposit-onl…
waritctd Oct 1, 2026
a5126eb
fix(import): keep legacy IR steps advanceable once the IR is out
waritctd Oct 1, 2026
d060d0e
Merge pull request #1120 from waritctd/fix/fulfillment-import-request…
waritctd Oct 1, 2026
f5d2a79
fix(import): legacy advance stays available when the only per-factory…
waritctd Oct 1, 2026
107a36e
Merge pull request #1121 from waritctd/fix/import-legacy-advance-with…
waritctd Oct 1, 2026
84ebf7e
feat(sales): let the owning rep revise an issued pricing-request quot…
waritctd Oct 1, 2026
bba42be
Merge pull request #1122 from waritctd/feat/revise-pricing-request-qu…
waritctd Oct 1, 2026
23d5878
Trigger Sonar analysis
waritctd Oct 2, 2026
ee3fc57
Trigger Sonar analysis
waritctd Oct 2, 2026
fa61b62
chore: clear 8 SonarCloud blocker issues
waritctd Oct 2, 2026
462d31e
Merge pull request #1123 from waritctd/chore/sonar-blockers
waritctd Oct 2, 2026
26286b4
Merge develop into fix/import-step-advance-wiring
waritctd Oct 10, 2026
f674beb
fix(sales): explain a DRAFT ใบขอซื้อ in words that hold in every stat…
waritctd Oct 10, 2026
b0dbcf7
fix(sales): stop two stale-form writes on the ใบขอซื้อ card
waritctd Oct 10, 2026
1b21665
Merge pull request #1108 from waritctd/fix/import-step-advance-wiring
waritctd Oct 10, 2026
b14cb22
test(sales): run the แก้ใบเสนอราคา page tests on the real revise pred…
waritctd Oct 10, 2026
635d9f5
chore(deps): bump source-map-js 1.2.1 -> 1.2.2 (npm audit)
waritctd Oct 10, 2026
914d93c
chore: remove UX_BLOCKED_DECISIONS.md
waritctd Oct 10, 2026
8e8c734
chore: stop tracking internal agent and design docs
waritctd Oct 10, 2026
bcf88c6
chore(skills): add the ui-revamp skill
waritctd Oct 10, 2026
372f43d
test(sales): keep the sales_manager revise negative on the page's own…
waritctd Oct 10, 2026
f117479
Merge pull request #1126 from waritctd/fix/develop-red-ci-checks
waritctd Oct 10, 2026
dc5e9af
chore: gitignore graphify output and the backend graph vault
waritctd Oct 11, 2026
bb393de
chore: gitignore the integration-map vault too
waritctd Oct 11, 2026
9bc0d50
fix(ui): reset browser-default buttons and lists outside quotations
waritctd Oct 12, 2026
258a7c9
fix(ui): review follow-ups for the browser-default sweep
waritctd Oct 12, 2026
fbc202e
Merge pull request #1131 from waritctd/fix/browser-default-buttons-lists
waritctd Oct 12, 2026
8fa1160
test(ci): locate the repository root by backend/pom.xml and docs/api,…
waritctd Oct 12, 2026
ce9501c
fix(ui): FieldList drops the browser's bottom margin
waritctd Oct 12, 2026
2e55375
Merge pull request #1133 from waritctd/fix/ci-repo-root-marker
waritctd Oct 12, 2026
f051d61
fix(ui): fail loudly on an unknown Button variant
waritctd Oct 12, 2026
28b2b39
test(ui): pin false as an unknown Button variant
waritctd Oct 12, 2026
a5df1ce
Merge pull request #1136 from waritctd/fix/button-unknown-variant-guard
waritctd Oct 12, 2026
d688ca0
chore(lint): report an unknown Button variant at lint time
waritctd Oct 13, 2026
b4a0550
test(lint): close the review's gaps in the Button variant rule
waritctd Oct 13, 2026
4b8901c
Merge pull request #1141 from waritctd/chore/button-variant-lint
waritctd Oct 13, 2026
f576d17
Merge pull request #1134 from waritctd/fix/fieldlist-dl-bottom-margin
waritctd Oct 13, 2026
effc71e
Merge main into develop: forward-port the October quotation releases
waritctd Oct 14, 2026
8b9380b
fix(sales): a copied quotation keeps its rows when a deal is picked, …
waritctd Oct 14, 2026
3bf6c80
Merge pull request #1145 from waritctd/port/main-to-develop-2026-10-14
waritctd Oct 14, 2026
daa6314
fix(sales): สร้างคำขอราคา leads the deal page only from ขั้น 3
waritctd Oct 15, 2026
ef9b17d
fix(sales): ขั้น 1–2 lead with เลื่อนไป; price requests start at ขั้น 3
waritctd Oct 15, 2026
e0d573d
Merge main into develop: forward-port #1148 SenseFace CVAccess agent
waritctd Oct 16, 2026
48cfb51
Merge pull request #1152 from waritctd/port/main-to-develop-2026-10-16
waritctd Oct 16, 2026
f8b98dc
feat(sales): quote stages arrive by quoting, and one quotation number…
waritctd Oct 17, 2026
8648e65
refactor(sales): sweep comments made stale by the quote-stage and num…
waritctd Oct 17, 2026
51b729e
refactor(sales): one numbering step for both quotation create paths
waritctd Oct 17, 2026
036dd01
test(sales): share the quotationOnDeal fixture, drop duplicates and i…
waritctd Oct 17, 2026
2c4c07e
refactor(mock): drop dead origin filter, reuse the recipient-stage he…
waritctd Oct 17, 2026
87b586f
docs(design): bring quote-stage-gates docs in line with what shipped
waritctd Oct 17, 2026
3deb641
docs(sales): fix four comments left stale by the reorder-guard rename…
waritctd Oct 17, 2026
36b62a1
feat(sales): a revision keeps its parent's recipient (D-5 step 2, opt…
waritctd Oct 17, 2026
bf47969
test(e2e-real): quote-stage rulings on the real stack — UI walk, inve…
waritctd Oct 17, 2026
b2b72a2
refactor(sales): quotedRecipients stays server-side; route is checked…
waritctd Oct 17, 2026
b0e5aac
test(e2e-real): screenshot dir for the quote-stage UI walk is env-ove…
waritctd Oct 17, 2026
290fd89
Merge pull request #1153 from waritctd/feat/quote-stage-gates-and-ver…
waritctd Oct 18, 2026
a796db1
chore(lint): ESLint covers frontend/e2e-real and the Playwright config
waritctd Oct 18, 2026
b2f799a
Merge pull request #1154 from waritctd/fix/lint-e2e-real
waritctd Oct 18, 2026
808cc99
fix(sales): import PCR page — no reload on บันทึกโรงงาน, dashboard รั…
waritctd Oct 18, 2026
28a7f67
fix(sales): import PCR page — overlapping ยืนยันราคาเสนอ keep their o…
waritctd Oct 18, 2026
8386c74
test(e2e-real): quote-stage walk reads the stage badge, not the route…
waritctd Oct 18, 2026
65cc987
Merge pull request #1155 from waritctd/fix/import-pcr-page
waritctd Oct 18, 2026
f658a44
feat(sales): deal items carry catalogue thickness/pcs-per-box/origin;…
waritctd Oct 18, 2026
5773155
chore(mock): mirror the pricing-request lead-time rules and the deal …
waritctd Oct 18, 2026
2ef8440
fix(sales): สร้างคำขอราคา form — add-row focus, lone-row ✕, duplicate…
waritctd Oct 18, 2026
afae5c3
test(sales): drop the stock-line pin that required lead time on an im…
waritctd Oct 18, 2026
e5603b2
Merge pull request #1156 from waritctd/fix/pcr-create-form
waritctd Oct 18, 2026
992c804
feat(sales): quotation ผู้ติดต่อ resolves request → existing → none; …
waritctd Oct 18, 2026
d38ce54
feat(sales): quotation editor ผู้ติดต่อ picker — add-first dropdown, …
waritctd Oct 18, 2026
c5e31de
chore(mock): mirror quotation contact precedence, derived ordered_by_…
waritctd Oct 18, 2026
be3e9b5
test(e2e): write-quotation — ผู้ติดต่อ snapshot frozen on create; no-…
waritctd Oct 18, 2026
397de99
docs(design): quotation ผู้ติดต่อ picker + one-page deal form — desig…
waritctd Oct 18, 2026
e326a84
test(sales): picker modal — pin that the created contact becomes the …
waritctd Oct 18, 2026
457da55
Merge pull request #1157 from waritctd/feat/quotation-contact-picker
waritctd Oct 18, 2026
5f6af6c
feat(sales): deal form is one page — accordion sections, no ผู้ติดต่อ…
waritctd Oct 19, 2026
b537838
fix(sales): deal page, finance header and สร้างคำขอราคา stop reading …
waritctd Oct 19, 2026
44fd526
fix(sales): quotation customer phone/email boxes read โทร. / อีเมล (M-8)
waritctd Oct 19, 2026
8ac0b1f
refactor(sales): trim the M-8 relabel comments to the ruling and the …
waritctd Oct 19, 2026
c64a6e8
Merge pull request #1160 from waritctd/fix/quotation-customer-phone-l…
waritctd Oct 19, 2026
f4fc310
test(sales): pin the มัดจำ draft from a new-engine pricing-request qu…
waritctd Oct 19, 2026
d247e6a
fix(sales): มัดจำ draft from the pricing-request route accepts a new-…
waritctd Oct 19, 2026
57498fa
test(sales): pin the pricing-request มัดจำ draft to THIS pricing requ…
waritctd Oct 19, 2026
0d2548e
fix(sales): pricing-request มัดจำ draft reads the accepted quotation …
waritctd Oct 19, 2026
18aeabe
test(mock): pin the pricing-request มัดจำ draft from a new-engine ACC…
waritctd Oct 19, 2026
40d10c7
chore(mock): pricing-request deposit route and ticket draft fallback …
waritctd Oct 19, 2026
ff7b555
chore(mock): deposit mapper mirrors findDealQuotationItems' own colum…
waritctd Oct 19, 2026
9dcc789
test(mock): pin the deposit mapper's column picks with a discounted l…
waritctd Oct 19, 2026
daa5628
refactor(sales): correct two comments the deposit fix made false; tri…
waritctd Oct 19, 2026
39b826b
refactor(mock): trim the deposit mirror comments to pointers; drop th…
waritctd Oct 19, 2026
0d4a136
Merge pull request #1159 from waritctd/feat/deal-form-onepage
waritctd Oct 20, 2026
a32b02b
docs(plan): deposit notice from a new-engine pricing-request quotatio…
waritctd Oct 20, 2026
e927410
test(sales): pin the pricing-request มัดจำ draft's percent to THIS pr…
waritctd Oct 20, 2026
1c76cfb
test(mock): pin the pricing-request มัดจำ draft's percent to the acce…
waritctd Oct 20, 2026
316a37a
fix(sales): pricing-request มัดจำ draft bills THIS pricing request's …
waritctd Oct 20, 2026
1d390bf
test(sales): mixed-ticket deposit test asserts its legacy seed applie…
waritctd Oct 20, 2026
c0cb183
chore(deps-dev): bump vite from 8.2.1 to 8.3.4 in /frontend
dependabot[bot] Oct 20, 2026
9ff4283
Merge pull request #1163 from waritctd/dependabot/npm_and_yarn/fronte…
waritctd Oct 22, 2026
81d00c3
chore(deps): bump @vitest/mocker and vitest in /frontend
dependabot[bot] Oct 22, 2026
b26e95c
Merge remote-tracking branch 'origin/develop' into fix/deposit-notice…
waritctd Oct 22, 2026
12051a5
fix(sales): pricing-request มัดจำ route refuses a zero-deposit new-en…
waritctd Oct 22, 2026
06182e8
chore(docs): drop the committed implementation plan — the PR body is …
waritctd Oct 22, 2026
3f3c3d4
refactor(mock): deposit mapper reads the stored row; trim the new-eng…
waritctd Oct 22, 2026
59f623e
refactor(sales): trim the deposit-route Javadoc to single statements …
waritctd Oct 22, 2026
51b5e90
Merge pull request #1166 from waritctd/fix/deposit-notice-new-engine-pcr
waritctd Oct 22, 2026
7a3bf9b
test(release): pin the per-role sales release under the self-service …
waritctd Oct 22, 2026
3d7e2d6
feat(release): open the sales stack to sales roles; import and accoun…
waritctd Oct 22, 2026
31faed1
chore(release): pin render.yaml to backend image v2026-10-22
waritctd Oct 22, 2026
4287ff2
test(release): make the released-page checks non-vacuous; pin catalog…
waritctd Oct 22, 2026
a528e17
Merge pull request #1167 from waritctd/dependabot/npm_and_yarn/fronte…
waritctd Oct 22, 2026
963bc0b
Merge remote-tracking branch 'origin/develop' into release/2026-10-22…
waritctd Oct 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
147 changes: 147 additions & 0 deletions .agents/skills/ui-revamp/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
name: ui-revamp
description: Audit and fix web pages that look off — visual polish (type, layout, color, hierarchy, AI-slop removal) plus mobile-first responsive standards from 320px phones to wide desktops. Use when revising, critiquing, polishing or making any UI responsive.
---

# UI Revamp

One skill for fixing pages that "don't look right" and making them work on every screen, from a 320px phone to a 1440px+ desktop. It condenses three open-source approaches into one workflow: a design-system-first reasoning pass, a command vocabulary for targeted visual fixes, and mobile-first responsive guardrails.

## How to use

Say what you want in plain words, or use a mode keyword followed by a target:

```
audit the pricing page
critique landing
fix layout on the dashboard
typeset the blog post
adapt checkout for mobile
polish settings
```

With no mode named, run **audit → fix → polish** on the target.

---

## Step 1 — Gather context (always, before changing anything)

1. **Read the existing code first.** Find the stack (React/Next, Vue, plain HTML, Tailwind or plain CSS, component library) and work inside it. Never introduce a new framework to fix a page.
2. **Find the existing design system.** Look for tokens, a theme file, `tailwind.config`, CSS variables, `DESIGN.md`, or shared components. If one exists, it wins: extend it and don't override it. If none exists, extract one from the most-used values in the code (Step 2).
3. **Know the product.** Who is the audience, what is the page for, and what is the one action a visitor should take? Check for `PRODUCT.md` or a README. Ask the user only when something material is missing, and ask once.
4. **See the page.** Look at a screenshot or rendered view at 375px, 768px, 1024px and 1440px if you can. Judge the rendered result, not just the code.

## Step 2 — Lock a design system (small, explicit)

Write down, or confirm, a compact system before editing. If the project has none, save it as `DESIGN.md` at the project root so later pages stay consistent.

- **Type:** 1–2 families at most (a display face plus a text face, or a single family). Use a modular scale, e.g. 12 / 14 / 16 / 20 / 24 / 32 / 40 / 48. Body text is never below 16px on mobile.
- **Spacing:** a 4px or 8px base scale (4, 8, 12, 16, 24, 32, 48, 64, 96). No arbitrary values such as 13px or 27px.
- **Color:** a primary, an accent or CTA, a neutral ramp of 5–9 steps tinted toward the brand hue (not pure gray), plus success/warning/danger. Define these as tokens or CSS variables, and a dark set if the site has dark mode.
- **Radius and shadow:** 2–3 radius values and 2–3 elevation levels, used consistently.
- **Style direction:** one named direction that fits the product (e.g. calm and minimal for finance or health, bold and editorial for creative work, dense and functional for dashboards). Industry fit matters: trust-heavy products such as banking, health and legal avoid playful or neon styles.

**Page overrides:** if one page truly needs to deviate, record only the deviation in `design/pages/<page>.md`. Page rules override the master and everything else inherits.

## Step 3 — Diagnose (audit + critique)

Score each area **OK / Minor / Major** and list concrete findings with file and line where possible.

**Visual hierarchy and clarity (critique)**
- Is there one clear focal point and one primary CTA per view?
- Does size, weight and color tell the reader what matters first, second and third?
- Is the copy clear? Are labels and buttons action-oriented and free of jargon?

**Technical quality (audit)**
- Contrast is at least 4.5:1 for body text and 3:1 for large text and UI elements.
- Focus states are visible, keyboard order is logical, and headings run in order with none skipped.
- Images have alt text, and icon-only buttons have accessible labels.
- Layout breaks, horizontal scroll, overflow and clipped text are checked at every breakpoint.
- Performance: no huge images, no layout shift (reserve space for images and embeds), fonts load with `font-display: swap`.

**AI-slop and generic-template tells (flag and remove)**
- Inter or system default used for everything, with no typographic personality.
- Purple-to-blue gradients, glowing dark-mode blobs, gradient text on every heading.
- Cards inside cards, or every section wrapped in a card.
- A rounded-square icon tile above every heading, and emoji used as icons (use SVG icons such as Lucide, Heroicons or Phosphor).
- Gray text on colored backgrounds, and pure `#000` or pure gray (tint neutrals instead).
- Side-accent borders on every card, bounce or elastic easing, everything centered.
- Three identical feature columns with no hierarchy.

## Step 4 — Fix (pick the modes the diagnosis calls for)

| Mode | Fixes |
|---|---|
| **typeset** | Font choice and pairing, scale, weights, line height (1.4–1.6 for body, 1.1–1.25 for headings), line length (45–75 characters), heading wrapping |
| **layout** | Spacing rhythm, alignment to a grid, grouping (related items closer, sections further apart), whitespace, density |
| **colorize** | Strategic color: a neutral base, one accent used sparingly for actions and emphasis, and meaning that never relies on color alone |
| **bolder** | Bland pages: stronger scale contrast, a confident hero, a real focal point, more decisive color |
| **quieter** | Noisy pages: fewer colors, effects, borders and shadows; calmer motion |
| **distill** | Cluttered pages: cut sections, merge duplicates, remove decoration that carries no meaning |
| **harden** | Edge cases: long text and URLs wrap instead of clipping, empty, loading and error states exist, chips and badges wrap or collapse to "+n", the layout survives 200% zoom and translated text |
| **clarify** | UX copy: specific headings, verb-first buttons, helpful error messages |
| **animate** | Purposeful motion only: 150–300ms, ease-out, honors `prefers-reduced-motion`, and the final state stays correct if an animation is interrupted |
| **adapt** | Make it responsive (see the standards below) |
| **polish** | Final pass: align to the design system, make spacing and radius consistent, finish hover, focus and active states, run the pre-delivery checklist |

Make the smallest change that fixes the problem. Reuse existing components and tokens. Keep behavior and content intact unless asked otherwise.

---

## Responsive standards (always on)

**Mobile-first**
- Write base styles for the smallest screen, then add larger layouts with `min-width` media queries (Tailwind: unprefixed first, then `sm:`, `md:`, `lg:`, `xl:`).
- Always include `<meta name="viewport" content="width=device-width, initial-scale=1">`.

**Breakpoints:** use the project's existing set. Default to 640 / 768 / 1024 / 1280 / 1536px, matching Tailwind. Choose breakpoints where the content breaks, not for specific devices, and never invent one-off values.

**Fluid layouts**
- Use Flexbox and Grid. Prefer `grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr))` over fixed column counts.
- Use relative units: `rem` for type and spacing, `%`, `fr`, `vw` and `ch` for widths. No fixed pixel widths on containers. Use `max-width` with `width: 100%`.
- Constrain the content width (e.g. a max of 1200–1280px) with responsive side padding: 16px on mobile, 24–32px on tablet, 48px+ on desktop.
- Use fluid type for headings with `clamp()`, e.g. `font-size: clamp(2rem, 1.2rem + 3vw, 3.5rem)`.
- Use container queries for components that appear in different-width slots.

**Touch and interaction**
- Tap targets are at least 44×44px, with at least 8px between adjacent targets.
- Nothing depends on hover alone. Every hover reveal has a tap or focus equivalent.
- Form inputs use 16px or larger text (prevents iOS zoom), and use the correct `type` and `inputmode`.
- Add `cursor: pointer` to every clickable element.

**Content adaptation**
- Navigation collapses to a menu or bottom bar on mobile, and the primary CTA stays reachable.
- Multi-column sections stack in a sensible reading order. Don't hide important content on mobile; reprioritize it instead.
- Tables scroll horizontally inside a wrapper, or turn into stacked cards on mobile.
- Images use `max-width: 100%; height: auto`, plus `srcset`/`sizes` or the framework's image component. Set `aspect-ratio` to prevent layout shift.
- Respect safe areas on notched phones with `env(safe-area-inset-*)` for fixed bars.
- Use `100dvh` instead of `100vh` for full-height mobile sections.

**Test widths:** 320, 375, 768, 1024, 1440 and 1920px, in both orientations, plus 200% browser zoom.

---

## Pre-delivery checklist

- [ ] No horizontal scroll at 320px; layout verified at 375 / 768 / 1024 / 1440
- [ ] Text contrast is at least 4.5:1 (3:1 for large text and UI), in light and dark modes
- [ ] Visible focus states and logical tab order
- [ ] Tap targets are at least 44×44px; no hover-only interactions
- [ ] Body text is at least 16px on mobile; line length is 45–75 characters
- [ ] All spacing, color, type and radius values come from the design system
- [ ] No AI-slop tells remain (see the list in Step 3)
- [ ] SVG icons instead of emoji; icon buttons are labeled
- [ ] Long text, empty, loading and error states handled
- [ ] `prefers-reduced-motion` respected
- [ ] Images sized and lazy-loaded, with no layout shift

## Output format

1. **Findings:** a short scored list (OK / Minor / Major) with the top 3–5 problems.
2. **Changes:** what you changed and why, grouped by mode, with file references.
3. **Before/after:** screenshots or a mockup at mobile and desktop widths when possible.
4. **Checklist:** the pre-delivery checklist with every item ticked or explained.

---

*Credits: condensed and rewritten from ideas in UI UX Pro Max (nextlevelbuilder, MIT), Impeccable (Paul Bakaus, Apache-2.0) and Frontend Responsive Design Standards (am-will/codex-skills). No scripts or data files are required.*
59 changes: 59 additions & 0 deletions .design/cr1-factory-contact-flow/FRONTEND_TEST_COVERAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# CR-1 (GLA-167) frontend — test coverage list (written BEFORE implementation)

All tests below were written first and run RED before any production code changed. Red = the
assertion/lookup that fails is the missing behaviour (missing API method, missing element/label,
wrong label), not an import or syntax error. Everything is UI/mock level: **role assertions are
UI-level only (mockApi authz is not authoritative)** — the real enforcement is the Java integration
tests for `FactoryQuoteService` / `LeadTimeChangeService`.

## Red-run evidence (before implementation)

| File | Red |
|---|---|
| `src/api/mockApi.factoryContact.test.js` (new, 24) | 24 failed — `api.pricingRequests.markFactoryQuoteContacted is not a function`, `api.leadTimeChanges` undefined, EUR/PER_SQM not echoed |
| `src/features/pricingRequests/PricingRequestDetailPage.test.jsx` | 38 failed (5 rewritten old-flow tests + 33 new) — e.g. `Unable to find role=button name=สร้างเมล`, `Unable to find testid pcr-factory-terms-91`, 3s `findByTestId` timeouts for lead-time UI |
| `src/features/pricingRequests/PricingRequestCreateModal.test.jsx` | 19 failed — 7 new + 12 existing happy-path tests that now need `สกุลเงิน (ราคาโรงงาน)` / `หน่วยราคา` (`fillRequiredFields` updated) |
| `src/features/tickets/DealFulfilmentPanel.test.jsx` | 5 failed — label `สร้างใบ IR`, 4 auto-download assertions (`download` never called) |
| `src/features/tickets/DealDocumentRegister.test.jsx` | 5 failed — `register-import-requests` section absent |
| `src/api/serverContract.test.js` | 3 failed — hrApi still calls `POST /api/factory-quotes/{}/send` (removed server side); 7 new server endpoints not called; `ui-reachable.json` stale |
| `src/features/fulfilment/ImportFulfilmentPage.test.jsx` | 1 new test **passes** before implementation (characterization of existing per-factory PDF buttons, pinned deliberately) |
| 8 existing `mockApi.*.test.js` files | now call `markFactoryQuoteContacted` after `generateFactoryEmailDrafts` (B-R2); red with `is not a function` until the mock exists |

## Test cases and what they pin

### `mockApi.factoryContact.test.js` (mirrors `FactoryQuoteService#markContacted/#receive`, `LeadTimeChangeService`)
- items echo `requestedCurrency`/`requestedPriceUnitBasis`; draft seeded from them (EUR / PER_SQM).
- `sendFactoryQuote` is gone; `markFactoryQuoteContacted`: DRAFT→REQUESTED + date/note/by/at + request → AWAITING_FACTORY_RESPONSE; 409 on second call and recorded note unchanged (R7); 400 future / missing date; sales 403, CEO allowed (also edit draft + generate drafts, B-R1).
- `receive`: 409 on DRAFT (B-R2); 409 on currency mismatch; 409 on unit mismatch; OK when matching; legacy line (no terms) accepts anything.
- lead-time: create snapshots old range / PENDING / version 1; line untouched until approved; one PENDING per quote (409); validation 400 (reason, empty lines, min>max); update bumps version; withdraw frees the factory; approve (owning rep) writes new range; stale `expectedVersion` 409 changes nothing; reject needs reason; **CEO and import cannot approve/reject (B-R3)**; only import creates/updates/withdraws; list readable by import/ceo/sales/sales_manager, not account.

### `PricingRequestDetailPage.test.jsx` (factory section, UI)
- Card: chip `ยังไม่ติดต่อ`; `สร้างเมล` + `ติดต่อโรงงานแล้ว`; retired labels (`ร่างอีเมล`, `ดูอีเมล`, `ส่งแล้ว`) absent.
- Locked terms strip `EUR · ต่อ ตร.ม. · ตามคำขอของฝ่ายขาย`; currency/unit comboboxes removed for lines with terms; legacy line keeps both selects (characterization, passes pre-impl); inputs disabled + hint `กด ติดต่อโรงงานแล้ว ก่อนกรอกราคา`; contacted chip `ติดต่อแล้ว 1 ต.ค. · <name>`, note shown, inputs unlocked, **no ติดต่อโรงงานแล้ว button and no undo (R7)**; `ยืนยันราคาแล้ว`; receive payload carries EUR/PER_SQM; CEO has no inputs/confirm/lead-time button.
- Rewritten old tests: draft edit via `สร้างเมล`/`บันทึกร่าง`; lock hint testid `pcr-await-contact-*`; DRAFT stays locked **past the window** (B-R2 reverses #1062) with no contact button; mail modal read-only when contacted / outside window.
- Contact dialog: date defaults to today (Bangkok) with `max`=today; confirm → `markFactoryQuoteContacted(id,{contactedOn,note})` + refetch of quotes and request (F); blank note omitted; future date → confirm disabled, nothing sent; cancel; 409 → error toast; CEO can use both buttons (R5).
- `สร้างเมล` modal: ถึง prefilled from factory email (R8), หัวข้อ, เนื้อหา; only `บันทึกร่าง`/`คัดลอกเมล`(+ปิด); copy changes no status; close changes no status; ticked request attachments listed.
- Lead-time (import): per-line `ระยะเวลานำเข้า`; panel with new min/max, required reason, non-stock lines pre-ticked (stock line never offered); submit sends ticked lines; unticked excluded; per-line override; min>max / empty reason blocks; pending shows `75–90 → 120–150 วัน · รอฝ่ายขายอนุมัติ`, `แก้ไข`/`ถอนคำขอ`, no second request; withdraw; edit → `update`; compact approved/rejected history with reason; **CEO read-only badge**.
- Lead-time (deciders): owning rep / sales_manager see one banner (factory, reason, old→new) with `อนุมัติ`/`ไม่อนุมัติ`; approve sends `expectedVersion` and refreshes the request; reject needs reason then sends reason+version; **409 → `คำขอถูกแก้ไขแล้ว กรุณาตรวจสอบอีกครั้ง` + refetch**; non-owning sales / CEO / import see no decide controls; history-only → no banner.
- IR row on the factory card (R9): `IR26001 · … · PDF` downloads, `ฉบับร่าง`, no create/issue/revise control for import, matches factory by id else name, ignores SUPERSEDED/other factories, absent when none.

### `PricingRequestCreateModal.test.jsx` (F4)
selects blank for hand-typed line; blocked with per-row errors; catalogue pick auto-fills (EUR / `per_sqm`→PER_SQM) and sales may change before submit; unknown catalogue unit leaves unit blank; hand-typed line payload; edit seeds + resends; legacy persisted line must be completed before save.

### `DealFulfilmentPanel.test.jsx` / `DealDocumentRegister.test.jsx` / `ImportFulfilmentPage.test.jsx`
`สร้างใบ IR` (+ `สร้างใบ IR โรงงานที่ยังไม่มี`) relabel; after create, PDF of **each newly created** IR downloads (existing ones skipped); failed PDF keeps the create + error toast; invalidation of stored IRs and `['tickets','list']` (characterization). Register: 5th section `ใบขอซื้อ (รายโรงงาน)`, one row per IR, `ฉบับร่าง`, SUPERSEDED hidden, PDF download, empty line, read gate (import/ceo/sales_manager/owner yes; other sales/account no and no fetch). `/fulfilment`: per-factory internal + factory PDF download pinned.

### API parity
`contract.test.js` (hrApi↔mockApi, same arity) and `serverContract.test.js` (hrApi↔springdoc, ui-reachable.json) — red now, green after the API layer change.

## Deliberately NOT covered
- **Authz correctness** (who may mark contacted / decide a lead-time change): UI conditionals only; real enforcement = Java integration tests. Mock authz is approximate and not evidence.
- Visual layout / 375px: not unit-testable here; listed for manual browser verification in the handoff. The mock-frontend e2e suite no longer exists.
- Real PDF bytes / clipboard in a real browser; Bangkok-vs-browser-timezone edge at 00:00–07:00 is covered only by computing "today" with `Intl` in Asia/Bangkok.
- `/fulfilment` still lists only deals with ISSUED rows: a deal whose IRs are all DRAFT is not shown there (unchanged; flagged in the handoff, not changed).
- Factory-master default currency/unit autofill for hand-typed lines: that endpoint is import/CEO-only, so sales has no source — the field stays blank + required.
- Quotation re-issue after acceptance (B-R5): out of CR-1 scope.

## Green run (after implementation)
`cd frontend && npm run lint` 0 errors (1 pre-existing warning in `QuotationContactPicker.test.jsx`, untouched) · `npm test` 220 files / 3995 tests passed · `npm run build` ok.
Two existing tests (`PricingRequestPanel.test.jsx` edit-draft, `PricingRequestDetailPage.test.jsx` revision modal) needed their fixture line to carry `requestedCurrency`/`requestedPriceUnitBasis`: a legacy line must now be completed before it can be saved (intended, pinned in `PricingRequestCreateModal.test.jsx`).
Loading
Loading