Skip to content

fix(rolecheck): FX read for SM, import toast, catalog factory filter, HR payroll month (RC-01..04) - #1196

Merged
waritctd merged 2 commits into
developfrom
claude/vibrant-taussig-9be69b
Oct 29, 2026
Merged

waritctd merged 2 commits into
developfrom
claude/vibrant-taussig-9be69b

Conversation

@waritctd

@waritctd waritctd commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Fixes the four errors found by the 2026-10-29 role-by-role check of main (self-service lock on). Each one was a request the server refused or rejected, and the page swallowed the error.

Symptom Fix Ruling
RC-01 sales_manager got 403 on GET /api/fx-rates on every deal-page load, so foreign-currency prices didn't convert to THB FxRateController.READ_ROLES adds sales_manager. Writes stay CEO-only. Owner, 2026-10-29: add SM
RC-02 import's S17 advance called api.tickets.get, which TicketService#get refuses for import, so the "รับครบทุกโรงงาน" toast never showed ImportFulfilmentPage reads api.importDeals.get → deal.fulfillmentStatus (import's own projection; import scope covers ORDER_RECEIVED→end). No ticket access widened. not needed
RC-03 sales/SM got 403 on GET /api/price-import/factories on /catalog, so the factory filter was silently empty CatalogSearchPage reads the names-only GET /api/factory-configs/names (#1194; ceo/import/sales/SM). /price-import/factories is not widened, because it carries supplier emails. Owner, 2026-10-29: use /names
RC-04 HR landing got 400 on GET /api/payroll on every load (no payrollMonth) HrOverview sends the current Bangkok month, under its own query key [...payrollCurrent(m), 'overview'] not needed

Tests (written first, shown red, then green)

  • FxRateControllerTest › listIsAllowedForTheRuledReadRoles / listIsForbiddenForEveryRoleOutsideTheRuling: SM allowed. employee/warehouse/qc/hr/account still 403. Write cases unchanged (still CEO-only).
  • CatalogPricingReadAuthzIntegrationTest › new salesManagerCanReadFxRatesPerOwnerRuling20261029; SM removed from the deny list. Real Postgres.
  • ImportFulfilmentPage.test.jsx › X4 block (5 cases revised). tickets.get is now mocked the way Java answers import (403), where before it was faked as a success. The toast is keyed on importDeals.get. The negative cases still never claim completion.
  • CatalogSearchPage.test.jsx › fills the factory filter for sales|sales_manager from the names-only endpoint. priceImport.factories is mocked as 403, as Java answers sales.
  • HrOverview.test.jsx › asks for the current Bangkok payroll month (2026-10-31T18:00Z → 2026-11) and leaves the payroll page cache entry for the same month untouched.

Deliberately not covered:

  • No frontend test for RC-01, because no frontend code changed (the Java gate is the fix).
  • No test of the mockApi hasRole mirrors, which aren't authoritative.

Review

Sonnet implemented, and Opus reviewed twice: the full diff, then the delta after rework.

  • Revert checks: each production fix was reverted alone, and its test went red.
  • Integration tests: CatalogPricingReadAuthzIntegrationTest 11/11 and PriceImportFactoryMasterDataAuthzIntegrationTest 25/25 passed on a throwaway Postgres.
  • Bug found by the review, then fixed: the first RC-04 version shared PayrollPage's cache key, which has a different shape. Opening เงินเดือน within 30s of the landing would have shown an empty table.

Code-review round (commit d938c14)

/code-review found 6 issues; all are fixed on this PR, tests first (each shown red, then a revert check by Opus):

  • account can now read GET /api/factory-configs/names (owner ruling 2026-10-29), so its /catalog filter fills. Pinned by FactoryConfigControllerTest.
  • Import toast decides from the rows GET /api/import/deals/{id} already carries. The duplicate listForTicket fetch is dropped.
  • PayrollPage opens on the Bangkok month (was UTC), matching the HR landing. Pinned by opens on the current Bangkok month, not the UTC month.
  • HR landing shows โหลดรอบเงินเดือนไม่สำเร็จ when the payroll read fails, instead of "not started". Pinned by says the payroll period failed to load….
  • Cleanup: the stale fx-rates comment in PricingRequestDetailPage.jsx is fixed (no test: comment-only), and the cosmetic it.each catalog test is collapsed to one case.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
demo-glr Ready Ready Preview Oct 29, 2026 5:25am UTC

Request Review

waritctd and others added 2 commits October 29, 2026 12:13
… main

- RC-01: GET /api/fx-rates read widens to sales_manager (owner ruling
  2026-10-29) so the deal page converts SM's foreign-currency prices to THB.
  Writes stay CEO-only.
- RC-02: import's S17 completion toast reads its own projection
  (GET /api/import/deals/{id}) instead of GET /api/tickets/{id}, which
  TicketService#get refuses for import. No ticket access widened.
- RC-03: the /catalog factory filter reads the names-only
  GET /api/factory-configs/names (sales + sales_manager can read it) instead
  of the ceo/import-only /api/price-import/factories, which stays unwidened.
- RC-04: the HR landing sends the current Bangkok payrollMonth to
  GET /api/payroll (400 without it), under its own query key so it never
  overwrites PayrollPage's differently-shaped cache entry for that month.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- account can read GET /api/factory-configs/names (owner ruling
  2026-10-29): it can open /catalog, whose factory filter reads it.
- Import's RECEIVED toast decides from the rows GET /api/import/deals/{id}
  already carries; the duplicate listForTicket fetch is gone.
- PayrollPage opens on the Bangkok month (was UTC), matching the HR landing.
- The HR landing shows "โหลดรอบเงินเดือนไม่สำเร็จ" when the payroll read
  fails instead of claiming the period has not started.
- Stale fx-rates comment in PricingRequestDetailPage; catalog test collapsed
  to one case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@waritctd
waritctd force-pushed the claude/vibrant-taussig-9be69b branch from d0e8404 to d938c14 Compare October 29, 2026 05:25
@waritctd
waritctd merged commit 7fd772c into develop Oct 29, 2026
7 checks passed

This branch was successfully deployed

1 active deployment
Preview — d938c14c Deployed Oct 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant