Commit Graph

12 Commits

Author SHA1 Message Date
Mike Kell 197cc66169 feat(stage-11c): custom order tracking and fulfillment
Adds the workshop-side counterpart to Stage 11B's intake form: a tracking workspace filtered by fulfillment stage, an auditable timeline of stage changes, and inventory deduction on completion. Closes audit finding P2.2; Stage 11 is complete.

Domain: FulfillmentEvent (append-only transition record with operator notes and a malformed-line-tolerant wire format), MaterialUsage, MaterialConsumptionPort + MaterialDeductionResult. Order gains fulfillmentHistory, materialUsage, derived stage accessors, and withFulfillmentEvent(). All existing fields, defaults, and copyWith semantics preserved.

Data: advanceFulfillmentStatus() records an event with an optional note and injectable clock; recordMaterialUsage() added. WooCommerce round-trips both through _kc_ meta keys, skipping malformed lines and never blanking remote values.

Application/presentation: AdvanceFulfillment, CompleteCustomOrder, CustomOrderTrackingController, CustomOrderTrackingPage, FulfillmentTimeline, showAdvanceStageDialog. Illegal transitions surface the domain rejection reason verbatim.

Architecture: inventory deduction crosses the feature boundary through an outbound port, not a package dependency. feature_orders still has no dependency on feature_inventory; each app supplies InventoryMaterialConsumptionAdapter. Completion advances first and deducts second, so a rejected transition can never decrement stock, and a deduction failure warns rather than failing the commission.

Tests: 329 new (293 feature_orders, 22 kell_mobile, 14 kell_web). 1085/1085 feature_orders, 109/109 kell_mobile, 81/81 kell_web. dart analyze --fatal-infos clean.
2026-09-25 16:54:51 -04:00
Mike Kell 595d0b5a93 feat(stage-11b): custom order intake UI
Adds the operator-facing intake flow for made-to-order commissions on top of
the Stage 11A domain and data layers. The form, validation, and confirmation
receipt all live in feature_orders, so web and mobile host the same widget
rather than forking business logic per platform.

Stage 11C still covers the tracking page, the status-change timeline, and
inventory deduction on completion.

Application:

- CreateCustomOrder and RecordDeposit use cases wrapping the repository
  methods added in Stage 11A, so presentation never assembles a custom order
  aggregate by hand. RecordDeposit deliberately accepts no payment identifier.
- CustomOrderFormController with field-keyed validation, so each input renders
  its own error rather than a single form-level message. Clock and ID
  generator are injected, which keeps created-at stamps and order IDs
  deterministic under test.
- All money is typed as text and converted to integer cents by
  parseMoneyToCents before it reaches DepositInfo, consistent with
  PaymentResult.amountCents. Thousands separators, currency symbols, excess
  precision, and negatives are rejected or normalised at the boundary. The
  only double is the derived OrderItem.unitPrice, computed once from cents.
- Derived balance clamps at zero rather than reporting a credit when a deposit
  exceeds the quoted total, matching DepositInfo.balanceDueCents.

Presentation:

- CustomOrderFormPage — sectioned intake (customer, specification, pricing and
  deposit, reference images) over the shared design-system widgets.
- CustomOrderConfirmationPage — order summary, spec rendering, and a deposit
  receipt showing amount, method, date, and balance only.
- FulfillmentStatusChip over the design-system KcStatusChip, covering all
  seven pipeline values.
- showReferenceImageDialog() plus ReferenceImageDialogResult with URL
  validation and de-duplication.
- OrdersPage gains an optional onCreateCustomOrder callback. When null the
  "New Custom Order" action is not rendered, so the page stays usable in hosts
  that have no intake route.

Hosts:

- kell_web: new /orders/custom route rendering CustomOrderFormPage inside
  AppShell, with ordersToCustomOrder() and customOrderToOrders() handoffs on
  AppNavigation. Confirmation returns to Orders pre-selecting the new order.
- kell_mobile: new MobileCustomOrderPage, a full-screen SafeArea host for the
  shared form, reached from an extended FAB on the orders list. Market intake
  is the primary custom-order use case, so mobile gets a dedicated route
  rather than an inline panel. The list reloads on return.

Privacy:

- The deposit receipt renders amount, method, date, and balance only. The
  transaction ID stays on PaymentResult and is asserted absent from the
  rendered confirmation by test. The controller holds no payment identifier at
  any point.

Deferred to Stage 11C, recorded in the Stage 11B section:

- Product-base selection from the catalogue; the form captures a free-text
  specification instead.
- Platform camera and file-picker capture for reference images; the dialog
  accepts validated URLs only.

Validation:

- 146 new tests: 82 on CustomOrderFormController (money parsing, setters,
  derived balance and clamping, reference image add/remove/dedupe, the full
  validation matrix, buildSpec mapping, submission, quoted vs. collected
  deposit, repository failure, duplicate ID, reset), 26 on the form page, 24
  on the confirmation page including the no-payment-identifier assertion, 3 on
  the OrdersPage entry point, 6 on MobileCustomOrderPage, and 5 on the web
  route.
- 2,044/2,044 passing across all 11 packages and apps, up from the 1,898
  baseline at 0e3987b, with no regression.
- dart analyze --fatal-infos clean across all packages and apps.
- dart format --line-length 100 clean on every file touched by this slice.

Test-harness note: the intake form is taller than the default 800x600 test
view, so the submit-button tests resize tester.view rather than working around
a layout defect. The page scrolls normally on device.

Toolchain note: kell_web/pubspec.lock picked up SDK-pinned transitive bumps on
flutter pub get (matcher 0.12.19 to 0.12.20, meta 1.18.0 to 1.19.0, test_api
0.7.11 to 0.7.12, vector_math 2.2.0 to 2.4.3). Same accepted class as the
kell_mobile bumps recorded under chore/state-reconciliation-flutter-347;
committed so the lock file matches the toolchain in use.

Closes: P2.2 (intake UI portion)
2026-09-25 15:45:04 -04:00
Mike Kell 47b13b1ed1 feat(stage-10c): Square Mobile POS / Checkout
- Add PaymentMethod enum (cash, card) with label/iconHint extensions
- Add PaymentResult value object (transactionId, amountCents, method, completedAt, receiptUrl, amountFormatted)
- Add PaymentService abstract contract + PaymentException
- Add CheckoutController (ChangeNotifier) with CartEntry and sealed CheckoutState hierarchy
- Add FakePaymentService (always succeeds, counter-based IDs)
- Update feature_orders barrel exports
- Add MobileCheckoutPage (product selection -> cart -> payment -> receipt flow)
- Add Sales tab (index 4) to MobileShell; 6 tabs total
- Wire paymentService + checkoutCatalogue into all MobileAppServices factories
- Add 36 new feature_orders tests (234 total)
- Add 18 new kell_mobile tests (72 total); 1373 total across all packages
- Update widget_test.dart: destination count 5 -> 6
- Update build_execution_tracker.md and master_development_brief.md

All tests passing. dart analyze clean.
2026-07-25 17:37:36 -04:00
Mike Kell 116255f8ac feat(stage-10F): SquareSyncStatusPanel + IntegrationsPage + MobileIntegrationsPage + squareSyncController wired into both shells 2026-07-25 16:55:46 -04:00
Mike Kell a127ddba3a feat(stage-9d): product creation UI, category management page, mobile create-product page 2026-07-11 10:50:32 -04:00
Mike Kell e92788038a feat(orders): Stage 9A - WooCommerce Orders API integration
- Extend OrderStatus with onHold, refunded, failed
- Extend OrderItem with productId, variationId, customizations
- Extend Order with paymentMethod, source, customFields
- Add OrderSource enum (online, market, manual)
- Add getOrder(id) to OrdersRepository contract and FakeOrdersRepository
- Add WooCommerceOrderMapper (WooCommerce JSON <-> Order domain)
- Add WooCommerceOrdersRepository implementing full OrdersRepository
- Add orders API methods to WooCommerceApiClient (getOrders, getOrder,
  updateOrderStatus, createOrder, addOrderNote)
- Export WooCommerceApiClient/WooCommerceApiException from feature_wordpress
- Add feature_wordpress + http dev deps to feature_orders pubspec
- 83 new tests: mapper (25), repository+API client (23), FakeRepo.getOrder (3),
  plus existing suite grows to 198/198 feature_orders
- All packages analyze clean; 847/847 total tests passing
- Update master_development_brief.md and build_execution_tracker.md
2026-07-11 09:45:36 -04:00
Mike Kell 585dc14829 feat(mobile): Stage 6C — mobile inventory surface
- Add MobileInventoryPage with search bar, horizontal status filter chips
  (All / In Stock / Low Stock / Out of Stock / Draft), item count display,
  compact _MobileInventoryCard list at 120px height (name, SKU, status chip,
  quantity-on-hand), pull-to-refresh, and _detailPageActive guard to suppress
  behind-route SnackBars
- Add MobileInventoryDetailPage wrapping shared InventoryDetailPanel; local
  controller listener for SnackBar feedback; showAdjustQuantityDialog on
  Adjust Quantity tap; haptic feedback (mediumImpact on result, lightImpact
  on successful adjust); SafeArea wrapper
- Update MobileShell Inventory tab (case 1) from shared InventoryPage to
  MobileInventoryPage; remove unused feature_inventory direct import
- Add 6 Stage 6C widget tests: Inventory tab search bar, status filter chips,
  item count, card navigation to detail, adjust quantity dialog, back
  navigation returning to list (26/26 kell_mobile total)

All tests passing: 26/26 kell_mobile, 75/75 feature_inventory
dart analyze --fatal-infos: no issues found
Stage 6 complete — Products, Orders, and Inventory all have mobile surfaces
2026-07-10 20:13:27 -04:00
Mike Kell 6697bb02dd feat(mobile): Stage 6B — mobile orders surface
- Add MobileOrdersPage with search bar, horizontal status filter chips
  (All/Pending/Processing/Shipped/Delivered/Cancelled), order count
  display, OrderCard list at 160px height, pull-to-refresh, and
  \_detailPageActive guard to suppress behind-route SnackBars
- Add MobileOrderDetailPage wrapping shared OrderDetailPanel as a
  StatefulWidget with local controller listener for SnackBar feedback,
  confirmation dialog before status changes, haptic feedback
  (mediumImpact for status, lightImpact for note additions), and SafeArea
- Wire Orders tab (case 3) in MobileShell to MobileOrdersPage; remove
  unused feature_orders direct import from shell
- Add 6 new Stage 6B widget tests: Orders tab search bar, status filter
  chips, order count, order card navigation to detail, confirmation dialog
  for status change, back navigation returning to orders list
- Update build_execution_tracker.md and master_development_brief.md

Tests: 20/20 kell_mobile, 115/115 feature_orders — all passing
Analyze: dart analyze --fatal-infos — no issues found
2026-07-10 20:03:22 -04:00
Mike Kell 871ae8c48b feat(Stage 6B): Android mobile workflow hardening
- Restore Material Design 48x48dp minimum touch targets on 12 IconButtons
  in ProductPreviewPanel by removing constraints/padding overrides
- Replace fixed-width SizedBox(width:80) on price edit TextField with
  Expanded for flexible layout on narrow mobile screens
- Add tooltip 'Edit price' for consistency with other edit buttons
- Wrap ProductPreviewPanel in SafeArea in MobileProductDetailPage to
  prevent content clipping under notches/gesture bars
- Add 6 new touch target rendered-size tests verifying >= 48x48dp
- Update master_development_brief.md and build_execution_tracker.md

Tests: 300/300 feature_wordpress, 14/14 kell_mobile, 24/24 kell_web,
       41/41 design_system — 379 total, all passing.
Stage 6 (Android operational maturity) complete.
2026-05-30 09:45:10 -04:00
Mike Kell e23d41b098 feat(mobile): Stage 6A — Android feedback and action polish
Validate Docs / validate-docs (push) Successful in 55s Details
Flutter Analyze / Dart Analyze (push) Has been cancelled Details
Flutter Test / Flutter Tests (push) Has been cancelled Details
- Convert MobileProductDetailPage to StatefulWidget with local controller
  listener for SnackBar feedback in detail page context
- Add confirmation dialogs for publish/move-to-draft status changes
- Add haptic feedback (mediumImpact for status, lightImpact for field edits)
  on successful actions
- Guard MobilePublishingPage SnackBars with _detailPageActive flag to prevent
  invisible behind-route feedback when detail page is pushed
- Add 4 new Stage 6A widget tests (14 total kell_mobile tests passing)
- Update build_execution_tracker.md and master_development_brief.md
2026-05-29 19:13:46 -04:00
Mike Kell 591de0c5c4 feat(mobile): add Android publishing surface (Stage 5B)
Validate Docs / validate-docs (push) Successful in 2m12s Details
Publish Docs / publish-docs (push) Successful in 59s Details
Flutter Analyze / Dart Analyze (push) Has been cancelled Details
Flutter Test / Flutter Tests (push) Has been cancelled Details
- Add MobilePublishingPage with search, filter chips, sort, product count,
  compact card list, pull-to-refresh, and push navigation to detail
- Add MobileProductDetailPage wrapping shared ProductPreviewPanel with
  all narrow edit callbacks (status, price, name, description, category)
- Switch Products tab in MobileShell from ProductPublishingPage to
  MobilePublishingPage
- Expand feature_wordpress barrel exports for mobile consumption
- Add 4 new widget tests (10 total kell_mobile tests passing)
- Zero business logic forked — all shared layers reused
- dart analyze clean, all tests passing

Stage 5 (Android application foundation) complete.
2026-05-29 02:32:28 -04:00
Mike Kell 65466ba513 feat(mobile): Stage 5A — Android app shell and bootstrap
Validate Docs / validate-docs (push) Successful in 3m31s Details
Flutter Analyze / Dart Analyze (push) Has been cancelled Details
Flutter Test / Flutter Tests (push) Has been cancelled Details
Replace default Flutter counter template in kell_mobile with a fully
integrated mobile operations platform shell reusing shared packages.

Mobile app shell:
- MobileAppServices extending KcAppServices with fake()/wp() factories
- KellMobileApp with KcAppScope<MobileAppServices>, KcTheme, env badge
- MobileShell with 5-tab NavigationBar (Dashboard, Inventory, Orders,
  Publishing, More) using IndexedStack for state preservation
- KcBootstrap entry point with --dart-define environment variables

Dashboard:
- DashboardSummary value object with fromData()/empty() constructors
- GetDashboardSummary use case aggregating inventory, orders, publishing
- DashboardController (ChangeNotifier) with loading/error/summary state
- MobileDashboardPage with GridView summary cards using design system
  widgets (KcSectionHeader, KcSummaryCard, KcEmptyState)

Placeholder pages:
- FinancePlaceholderPage, IntegrationsPlaceholderPage for More tab
- Feature tab pages delegate to shared feature presentation layers

Infrastructure:
- pubspec.yaml references all shared packages (core, design_system,
  feature_inventory, feature_orders, feature_policy, feature_wordpress)
- SDK constraint corrected from ^3.11.4 to ^3.11.0 across all 14
  pubspec.yaml files to match installed Dart SDK 3.11.3

Tests:
- 6 new kell_mobile widget tests: shell loading, summary cards,
  environment badge, navigation bar destinations, tab switching, More menu
- All existing tests remain passing (24/24 kell_web, 294/294
  feature_wordpress)

Documentation:
- master_development_brief.md: Stage 5A marked complete, next branch
  updated to feat/android-publishing-surface (Stage 5B), kell_mobile
  platform description updated
- build_execution_tracker.md: Stage 5A entry added with full file list
2026-05-28 19:10:14 -04:00