- Shipped
- August 27, 2026 at 4:39 AM UTC
- Author
- Kamo
- Commit
- c8b58ce
SW5 Task 3, library half. ServiceTaskBookService exposes books, categories, tasks and options behind an org-scoped API, plus resolveTaskByCode - the lookup a quote or work order performs when it stores a taskCode. That one is a single indexed query against idx_service_task_book_code, reached through ServiceTask's direct book FK, not a fetch-the-book-then-scan. Every entry point takes orgId as its first argument and hands it to a repository whose JPQL carries the predicate. Nothing loads by uid and checks the org afterwards; that shape is what made six commerce endpoints cross-tenant reads before SW1 repaired them. ServiceTaskBookServiceShapeTest pins both halves - the signature rule and 'every servicework @Query names organization.id'. Two repositories were needed that Task 1 did not create: categories and options carry no org of their own, so their org-scoped reads join through the book (two hops for an option). Ids and timestamps leave as strings in both directions. Offering.uid is a 19-digit Long and a JSON number in a browser is a double, which is the same trap that forced QuoteConversionResult.orderUid to become a String in SW4. Reads map to views inside the transaction rather than handing entities to a controller, so nothing depends on open-in-view staying true. Deletes refuse rather than cascade: a book that still holds priced entries and a category that still holds tasks both answer 409. Retiring a book is isActive/effectiveUntil, which leaves every sold line resolvable.