@mohasinac/appkit 4.52.4 โ 4.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-stamp.json +4 -4
- package/dist/_internal/client/features/sticker-trace/canvas-codec.d.ts +2 -0
- package/dist/_internal/client/features/sticker-trace/canvas-codec.js +148 -0
- package/dist/_internal/server/features/auctions/actions.js +1 -1
- package/dist/_internal/server/features/categories/data.js +23 -7
- package/dist/_internal/server/features/checkout/actions.js +10 -3
- package/dist/_internal/server/features/checkout/data.d.ts +15 -0
- package/dist/_internal/server/features/checkout/data.js +20 -3
- package/dist/_internal/server/features/lottery/actions.js +9 -1
- package/dist/_internal/server/features/lottery/og.d.ts +40 -0
- package/dist/_internal/server/features/lottery/og.js +79 -0
- package/dist/_internal/server/features/messages/actions.js +4 -0
- package/dist/_internal/server/features/offers/adapters.js +17 -3
- package/dist/_internal/server/features/orders/actions.js +7 -2
- package/dist/_internal/server/features/raffle/actions.d.ts +19 -0
- package/dist/_internal/server/features/raffle/actions.js +25 -0
- package/dist/_internal/server/features/reviews/actions.js +1 -1
- package/dist/_internal/server/features/reviews/data.d.ts +1 -1
- package/dist/_internal/server/features/search/index-build/artifact-store.d.ts +89 -0
- package/dist/_internal/server/features/search/index-build/artifact-store.js +208 -0
- package/dist/_internal/server/features/search/index-build/build.d.ts +57 -0
- package/dist/_internal/server/features/search/index-build/build.js +285 -0
- package/dist/_internal/server/features/search/index-build/sources.d.ts +53 -0
- package/dist/_internal/server/features/search/index-build/sources.js +385 -0
- package/dist/_internal/server/features/search/search-sources.d.ts +0 -15
- package/dist/_internal/server/features/search/search-sources.js +142 -7
- package/dist/_internal/server/features/seo/robots.js +21 -1
- package/dist/_internal/server/features/seo/sitemap.js +1 -1
- package/dist/_internal/server/features/shared/listing-data-factory.js +16 -4
- package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
- package/dist/_internal/server/features/site-settings/adapters.js +26 -0
- package/dist/_internal/server/features/sticker-trace/actions.d.ts +109 -0
- package/dist/_internal/server/features/sticker-trace/actions.js +172 -0
- package/dist/_internal/server/features/sticker-trace/adapters.d.ts +80 -0
- package/dist/_internal/server/features/sticker-trace/adapters.js +174 -0
- package/dist/_internal/server/features/sticker-trace/build-cut-file.d.ts +26 -0
- package/dist/_internal/server/features/sticker-trace/build-cut-file.js +127 -0
- package/dist/_internal/server/features/sticker-trace/coordinator.d.ts +27 -0
- package/dist/_internal/server/features/sticker-trace/coordinator.js +169 -0
- package/dist/_internal/server/features/sticker-trace/fanout.d.ts +43 -0
- package/dist/_internal/server/features/sticker-trace/fanout.js +180 -0
- package/dist/_internal/server/features/sticker-trace/finalizer.d.ts +25 -0
- package/dist/_internal/server/features/sticker-trace/finalizer.js +123 -0
- package/dist/_internal/server/features/sticker-trace/mosaic-inputs.d.ts +30 -0
- package/dist/_internal/server/features/sticker-trace/mosaic-inputs.js +112 -0
- package/dist/_internal/server/features/sticker-trace/progress.d.ts +81 -0
- package/dist/_internal/server/features/sticker-trace/progress.js +198 -0
- package/dist/_internal/server/features/sticker-trace/promote.d.ts +23 -0
- package/dist/_internal/server/features/sticker-trace/promote.js +193 -0
- package/dist/_internal/server/features/sticker-trace/shard.d.ts +50 -0
- package/dist/_internal/server/features/sticker-trace/shard.js +174 -0
- package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +141 -0
- package/dist/_internal/server/features/sticker-trace/sheet-actions.js +279 -0
- package/dist/_internal/server/features/sticker-trace/storage.d.ts +135 -0
- package/dist/_internal/server/features/sticker-trace/storage.js +282 -0
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +25 -1
- package/dist/_internal/server/jobs/core/_event-ref.d.ts +51 -0
- package/dist/_internal/server/jobs/core/_event-ref.js +63 -0
- package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +18 -0
- package/dist/_internal/server/jobs/core/assignSpinPrize.js +77 -16
- package/dist/_internal/server/jobs/core/auctionSettlement.js +13 -4
- package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +44 -15
- package/dist/_internal/server/jobs/core/bundleStockSync.js +3 -4
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +44 -0
- package/dist/_internal/server/jobs/core/event-draw-reasons.d.ts +78 -0
- package/dist/_internal/server/jobs/core/event-draw-reasons.js +133 -0
- package/dist/_internal/server/jobs/core/listingProcessor.js +28 -8
- package/dist/_internal/server/jobs/core/onOrderCreate.js +12 -1
- package/dist/_internal/server/jobs/core/onScamReportCreate.js +13 -2
- package/dist/_internal/server/jobs/core/onScamReportRejected.js +8 -2
- package/dist/_internal/server/jobs/core/onScamReportVerified.js +8 -2
- package/dist/_internal/server/jobs/core/onStoreWrite.js +11 -4
- package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +5 -4
- package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +1 -4
- package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +1 -2
- package/dist/_internal/server/jobs/core/promotions.js +7 -4
- package/dist/_internal/server/jobs/core/searchIndexBuild.d.ts +7 -0
- package/dist/_internal/server/jobs/core/searchIndexBuild.js +211 -0
- package/dist/_internal/server/jobs/core/triggerEventRaffle.d.ts +35 -0
- package/dist/_internal/server/jobs/core/triggerEventRaffle.js +213 -31
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +20 -14
- package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +8 -0
- package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +15 -15
- package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
- package/dist/_internal/server/jobs/handlers/index.js +1 -0
- package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/onProductWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/onReviewWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/onScamReportUpdate.js +18 -0
- package/dist/_internal/server/jobs/handlers/onStoreWrite.js +18 -0
- package/dist/_internal/server/jobs/handlers/searchIndexBuild.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/searchIndexBuild.js +2 -0
- package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +8 -0
- package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +15 -6
- package/dist/_internal/shared/actions/action-registry.js +29 -0
- package/dist/_internal/shared/cache/revalidate-targets.d.ts +0 -1
- package/dist/_internal/shared/cache/revalidate-targets.js +10 -8
- package/dist/_internal/shared/features/events/config.d.ts +14 -0
- package/dist/_internal/shared/features/events/config.js +14 -0
- package/dist/_internal/shared/features/notifications/action-url.js +8 -0
- package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
- package/dist/_internal/shared/features/sticker-trace/codec.d.ts +81 -0
- package/dist/_internal/shared/features/sticker-trace/codec.js +30 -0
- package/dist/_internal/shared/features/sticker-trace/config.d.ts +81 -0
- package/dist/_internal/shared/features/sticker-trace/config.js +177 -0
- package/dist/_internal/shared/features/sticker-trace/cut-contour.d.ts +20 -0
- package/dist/_internal/shared/features/sticker-trace/cut-contour.js +60 -0
- package/dist/_internal/shared/features/sticker-trace/export/build-export-set.d.ts +65 -0
- package/dist/_internal/shared/features/sticker-trace/export/build-export-set.js +176 -0
- package/dist/_internal/shared/features/sticker-trace/export/cut-svg.d.ts +56 -0
- package/dist/_internal/shared/features/sticker-trace/export/cut-svg.js +120 -0
- package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.d.ts +92 -0
- package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.js +153 -0
- package/dist/_internal/shared/features/sticker-trace/export/nesting.d.ts +51 -0
- package/dist/_internal/shared/features/sticker-trace/export/nesting.js +110 -0
- package/dist/_internal/shared/features/sticker-trace/export/page-sizes.d.ts +68 -0
- package/dist/_internal/shared/features/sticker-trace/export/page-sizes.js +223 -0
- package/dist/_internal/shared/features/sticker-trace/export/part-tiling.d.ts +51 -0
- package/dist/_internal/shared/features/sticker-trace/export/part-tiling.js +178 -0
- package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.d.ts +26 -0
- package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.js +134 -0
- package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.d.ts +40 -0
- package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.js +195 -0
- package/dist/_internal/shared/features/sticker-trace/index.d.ts +2 -0
- package/dist/_internal/shared/features/sticker-trace/index.js +59 -0
- package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.d.ts +11 -0
- package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.js +66 -0
- package/dist/_internal/shared/features/sticker-trace/math/edt.d.ts +27 -0
- package/dist/_internal/shared/features/sticker-trace/math/edt.js +165 -0
- package/dist/_internal/shared/features/sticker-trace/math/label.d.ts +15 -0
- package/dist/_internal/shared/features/sticker-trace/math/label.js +156 -0
- package/dist/_internal/shared/features/sticker-trace/math/marching-squares.d.ts +16 -0
- package/dist/_internal/shared/features/sticker-trace/math/marching-squares.js +242 -0
- package/dist/_internal/shared/features/sticker-trace/math/morphology.d.ts +46 -0
- package/dist/_internal/shared/features/sticker-trace/math/morphology.js +168 -0
- package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.d.ts +88 -0
- package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.js +286 -0
- package/dist/_internal/shared/features/sticker-trace/math/rdp.d.ts +10 -0
- package/dist/_internal/shared/features/sticker-trace/math/rdp.js +74 -0
- package/dist/_internal/shared/features/sticker-trace/resume.d.ts +50 -0
- package/dist/_internal/shared/features/sticker-trace/resume.js +160 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cluster.d.ts +20 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cluster.js +132 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.d.ts +28 -0
- package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.js +120 -0
- package/dist/_internal/shared/features/sticker-trace/trace/flood.d.ts +21 -0
- package/dist/_internal/shared/features/sticker-trace/trace/flood.js +104 -0
- package/dist/_internal/shared/features/sticker-trace/trace/geometry.d.ts +3 -0
- package/dist/_internal/shared/features/sticker-trace/trace/geometry.js +140 -0
- package/dist/_internal/shared/features/sticker-trace/trace/line-filter.d.ts +15 -0
- package/dist/_internal/shared/features/sticker-trace/trace/line-filter.js +138 -0
- package/dist/_internal/shared/features/sticker-trace/trace/merge.d.ts +27 -0
- package/dist/_internal/shared/features/sticker-trace/trace/merge.js +187 -0
- package/dist/_internal/shared/features/sticker-trace/trace/paper.d.ts +32 -0
- package/dist/_internal/shared/features/sticker-trace/trace/paper.js +147 -0
- package/dist/_internal/shared/features/sticker-trace/trace/prefilter.d.ts +30 -0
- package/dist/_internal/shared/features/sticker-trace/trace/prefilter.js +125 -0
- package/dist/_internal/shared/features/sticker-trace/trace/quantise.d.ts +10 -0
- package/dist/_internal/shared/features/sticker-trace/trace/quantise.js +153 -0
- package/dist/_internal/shared/features/sticker-trace/trace/ridge.d.ts +88 -0
- package/dist/_internal/shared/features/sticker-trace/trace/ridge.js +344 -0
- package/dist/_internal/shared/features/sticker-trace/trace/segment.d.ts +10 -0
- package/dist/_internal/shared/features/sticker-trace/trace/segment.js +251 -0
- package/dist/_internal/shared/features/sticker-trace/types.d.ts +197 -0
- package/dist/_internal/shared/features/sticker-trace/types.js +49 -0
- package/dist/_internal/shared/listing-types/_registry.d.ts +11 -0
- package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/art/config.js +1 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/config.js +1 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/classified/config.js +1 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +1 -0
- package/dist/_internal/shared/listing-types/feature-flags.d.ts +7 -0
- package/dist/_internal/shared/listing-types/feature-flags.js +9 -0
- package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/live/config.js +1 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/config.js +1 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +1 -0
- package/dist/_internal/shared/media/limits.d.ts +12 -2
- package/dist/_internal/shared/media/limits.js +12 -2
- package/dist/_internal/shared/search/artifact-url.d.ts +35 -0
- package/dist/_internal/shared/search/artifact-url.js +119 -0
- package/dist/_internal/shared/search/index-record.d.ts +68 -0
- package/dist/_internal/shared/search/index-record.js +96 -0
- package/dist/_internal/shared/search/match.d.ts +65 -0
- package/dist/_internal/shared/search/match.js +263 -0
- package/dist/client.d.ts +8 -7
- package/dist/client.js +12 -5
- package/dist/configs/eslint.js +22 -2
- package/dist/constants/api-endpoints.d.ts +68 -0
- package/dist/constants/api-endpoints.js +32 -0
- package/dist/constants/field-names.d.ts +7 -1
- package/dist/constants/field-names.js +36 -1
- package/dist/contracts/repository.d.ts +8 -7
- package/dist/contracts/search.d.ts +2 -2
- package/dist/contracts/table.d.ts +3 -3
- package/dist/contracts/table.js +3 -3
- package/dist/core/contact-submissions.repository.js +2 -2
- package/dist/core/integration-keys.js +7 -1
- package/dist/core/newsletter.repository.js +2 -2
- package/dist/core/site-config.js +1 -1
- package/dist/errors/error-codes.d.ts +30 -0
- package/dist/errors/error-codes.js +30 -0
- package/dist/errors/error-display-map.js +40 -1
- package/dist/features/account/api/[userId]/addresses/route.js +1 -1
- package/dist/features/account/components/UserBidsView.js +1 -1
- package/dist/features/account/components/index.d.ts +0 -8
- package/dist/features/account/components/index.js +0 -4
- package/dist/features/addresses/repository/addresses.repository.d.ts +17 -6
- package/dist/features/addresses/repository/addresses.repository.js +65 -9
- package/dist/features/addresses/schemas/firestore.d.ts +17 -6
- package/dist/features/admin/actions/notification-actions.js +15 -6
- package/dist/features/admin/api/bids/route.js +1 -1
- package/dist/features/admin/api/coupons/route.js +1 -1
- package/dist/features/admin/api/products/route.js +1 -1
- package/dist/features/admin/api/reviews/route.js +1 -1
- package/dist/features/admin/components/AdminAdEditorView.js +19 -5
- package/dist/features/admin/components/AdminAuditLogView.js +1 -1
- package/dist/features/admin/components/AdminBlogEditorView.js +0 -1
- package/dist/features/admin/components/AdminBlogView.js +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +17 -1
- package/dist/features/admin/components/AdminCategoryEditorView.js +0 -1
- package/dist/features/admin/components/AdminContactView.js +1 -1
- package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -3
- package/dist/features/admin/components/AdminNewsletterView.js +1 -1
- package/dist/features/admin/components/AdminOrdersView.js +9 -2
- package/dist/features/admin/components/AdminPayoutsView.js +1 -1
- package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -0
- package/dist/features/admin/components/AdminProductEditorView.d.ts +10 -1
- package/dist/features/admin/components/AdminProductEditorView.js +24 -37
- package/dist/features/admin/components/AdminProductsView.js +10 -3
- package/dist/features/admin/components/AdminScammersView.js +1 -1
- package/dist/features/admin/components/AdminSectionsView.js +21 -5
- package/dist/features/admin/components/AdminSessionsView.js +1 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +22 -1
- package/dist/features/admin/components/AdminTeamView.js +1 -1
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +0 -1
- package/dist/features/admin/components/AdminUsersView.js +1 -1
- package/dist/features/admin/components/DataListingView.d.ts +2 -1
- package/dist/features/admin/components/DataListingView.js +9 -4
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +0 -2
- package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
- package/dist/features/admin/repository/site-settings.repository.js +8 -3
- package/dist/features/admin/schemas/firestore.d.ts +62 -1
- package/dist/features/admin/schemas/firestore.js +32 -0
- package/dist/features/admin/types/index.d.ts +1 -1
- package/dist/features/auctions/actions/bid-actions.d.ts +2 -2
- package/dist/features/auctions/actions/bid-actions.js +16 -4
- package/dist/features/auctions/api/route.js +1 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +4 -0
- package/dist/features/auctions/repository/bid.repository.d.ts +46 -4
- package/dist/features/auctions/repository/bid.repository.js +114 -13
- package/dist/features/auctions/schemas/firestore.d.ts +24 -4
- package/dist/features/auctions/schemas/firestore.js +1 -0
- package/dist/features/auth/actions/profile-actions.js +30 -4
- package/dist/features/auth/components/index.d.ts +0 -1
- package/dist/features/auth/components/index.js +0 -1
- package/dist/features/auth/repository/session.repository.d.ts +17 -3
- package/dist/features/auth/repository/session.repository.js +46 -5
- package/dist/features/auth/repository/token.repository.d.ts +27 -4
- package/dist/features/auth/repository/token.repository.js +65 -11
- package/dist/features/auth/repository/user.repository.d.ts +33 -7
- package/dist/features/auth/repository/user.repository.js +100 -15
- package/dist/features/auth/schemas/firestore.d.ts +63 -12
- package/dist/features/auth/schemas/firestore.js +11 -0
- package/dist/features/before-after/api/route.js +1 -1
- package/dist/features/blog/components/BlogListView.js +16 -3
- package/dist/features/blog/components/BlogPostView.js +1 -1
- package/dist/features/blog/schemas/index.d.ts +2 -2
- package/dist/features/cart/api/route.js +1 -1
- package/dist/features/catalogue/repository/catalogue.repository.d.ts +7 -7
- package/dist/features/catalogue/repository/catalogue.repository.js +28 -10
- package/dist/features/catalogue/schemas/firestore.d.ts +11 -0
- package/dist/features/categories/api/route.js +10 -10
- package/dist/features/categories/components/CategoryDetailPageView.js +35 -5
- package/dist/features/categories/components/CategorySelectorCreate.js +0 -1
- package/dist/features/categories/components/index.d.ts +0 -2
- package/dist/features/categories/components/index.js +0 -1
- package/dist/features/categories/repository/categories.repository.d.ts +1 -0
- package/dist/features/categories/repository/categories.repository.js +31 -1
- package/dist/features/categories/schemas/index.d.ts +2 -2
- package/dist/features/categories/utils/taxonomy-visual.d.ts +21 -0
- package/dist/features/categories/utils/taxonomy-visual.js +58 -0
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +8 -1
- package/dist/features/collections/api/[slug]/route.js +3 -3
- package/dist/features/collections/api/route.js +1 -1
- package/dist/features/consultation/api/route.js +1 -1
- package/dist/features/consultation/repository/consultations.repository.js +1 -1
- package/dist/features/consultation/types/index.d.ts +1 -1
- package/dist/features/contact/components/ContactForm.js +1 -3
- package/dist/features/corporate/api/route.js +1 -1
- package/dist/features/corporate/repository/corporate.repository.js +1 -1
- package/dist/features/corporate/types/index.d.ts +1 -1
- package/dist/features/cron/jobs/auction-expiry.job.js +1 -1
- package/dist/features/cron/jobs/preorder-reminder.job.js +1 -1
- package/dist/features/events/actions/event-actions.d.ts +14 -0
- package/dist/features/events/actions/event-actions.js +82 -3
- package/dist/features/events/api/[id]/route.js +2 -2
- package/dist/features/events/components/AdminEventEditorView.js +22 -3
- package/dist/features/events/components/AdminEventsView.js +32 -8
- package/dist/features/events/components/EventRafflesSection.d.ts +34 -1
- package/dist/features/events/components/EventRafflesSection.js +52 -3
- package/dist/features/events/components/SpinWheelView.d.ts +2 -2
- package/dist/features/events/components/SpinWheelView.js +41 -4
- package/dist/features/events/repository/event-entry.repository.d.ts +14 -2
- package/dist/features/events/repository/event-entry.repository.js +41 -7
- package/dist/features/events/schemas/firestore.d.ts +17 -4
- package/dist/features/events/types/index.d.ts +37 -0
- package/dist/features/faq/repository/faqs.repository.js +1 -1
- package/dist/features/faq/schemas/index.d.ts +5 -2
- package/dist/features/faq/schemas/index.js +6 -0
- package/dist/features/faq/types/index.d.ts +0 -1
- package/dist/features/grouped/components/GroupedListingEditorView.js +17 -2
- package/dist/features/homepage/api/carousel/[id]/route.js +1 -1
- package/dist/features/homepage/api/carousel/route.js +4 -4
- package/dist/features/homepage/api/route.js +2 -2
- package/dist/features/homepage/api/sections/route.js +1 -1
- package/dist/features/homepage/components/AnnouncementBar.d.ts +1 -9
- package/dist/features/homepage/components/AnnouncementBar.js +13 -19
- package/dist/features/homepage/components/MarketplaceHomepageView.js +6 -1
- package/dist/features/homepage/components/index.d.ts +0 -2
- package/dist/features/homepage/components/index.js +0 -1
- package/dist/features/homepage/repository/homepage.repository.js +1 -1
- package/dist/features/homepage/schemas/firestore.d.ts +6 -0
- package/dist/features/homepage/schemas/index.d.ts +10 -10
- package/dist/features/layout/AppLayoutShell.d.ts +12 -3
- package/dist/features/layout/AppLayoutShell.js +65 -13
- package/dist/features/layout/BottomActionsContext.d.ts +16 -0
- package/dist/features/layout/BottomActionsContext.js +5 -0
- package/dist/features/layout/BottomChrome.js +48 -9
- package/dist/features/layout/BottomNavbar.d.ts +14 -0
- package/dist/features/layout/BottomNavbar.js +43 -3
- package/dist/features/layout/MainNavbar.d.ts +11 -0
- package/dist/features/layout/NavbarLayout.d.ts +3 -0
- package/dist/features/layout/NavbarLayout.js +88 -11
- package/dist/features/layout/SideActionDock.d.ts +1 -0
- package/dist/features/layout/SideActionDock.js +219 -0
- package/dist/features/layout/TitleBarLayout.d.ts +1 -3
- package/dist/features/layout/TitleBarLayout.js +3 -4
- package/dist/features/layout/cta-anchor.d.ts +31 -0
- package/dist/features/layout/cta-anchor.js +31 -0
- package/dist/features/layout/hooks/useBottomActions.d.ts +7 -0
- package/dist/features/layout/hooks/useBottomActions.js +6 -1
- package/dist/features/layout/index.d.ts +9 -1
- package/dist/features/layout/index.js +9 -1
- package/dist/features/layout/useCtaReveal.d.ts +24 -0
- package/dist/features/layout/useCtaReveal.js +82 -0
- package/dist/features/layout/useHoldToOpen.d.ts +41 -0
- package/dist/features/layout/useHoldToOpen.js +84 -0
- package/dist/features/lottery/repository/lottery-entry.repository.d.ts +18 -3
- package/dist/features/lottery/repository/lottery-entry.repository.js +48 -6
- package/dist/features/lottery/schemas/firestore.d.ts +33 -5
- package/dist/features/loyalty/api/balance/route.js +1 -1
- package/dist/features/loyalty/api/history/route.js +1 -1
- package/dist/features/media/MediaImage.js +0 -1
- package/dist/features/media/MediaPickerModal.js +7 -1
- package/dist/features/media/modals/ImageEditor.js +5 -1
- package/dist/features/media/modals/VideoThumbnailSelector.js +17 -1
- package/dist/features/media/repository/media-assets.repository.d.ts +19 -0
- package/dist/features/media/upload/CameraCapture.js +16 -1
- package/dist/features/media/upload/ImageUpload.js +42 -4
- package/dist/features/media/upload/MediaUploadField.js +69 -13
- package/dist/features/media/upload/downscale-image.d.ts +56 -0
- package/dist/features/media/upload/downscale-image.js +150 -0
- package/dist/features/messages/components/ConversationThreadView.js +45 -2
- package/dist/features/messages/components/MessageSellerButton.d.ts +15 -1
- package/dist/features/messages/components/MessageSellerButton.js +10 -2
- package/dist/features/messages/schemas/firestore.d.ts +15 -0
- package/dist/features/orders/hooks/useOrders.js +4 -2
- package/dist/features/orders/repository/orders.repository.d.ts +15 -4
- package/dist/features/orders/repository/orders.repository.js +52 -20
- package/dist/features/orders/schemas/firestore.d.ts +15 -4
- package/dist/features/orders/schemas/index.d.ts +8 -8
- package/dist/features/orders/types/index.d.ts +2 -2
- package/dist/features/payments/repository/payments.repository.js +2 -2
- package/dist/features/payments/repository/payout.repository.d.ts +23 -6
- package/dist/features/payments/repository/payout.repository.js +63 -23
- package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +17 -6
- package/dist/features/payments/repository/saved-payment-methods.repository.js +59 -11
- package/dist/features/payments/schemas/firestore.d.ts +14 -3
- package/dist/features/payments/schemas/saved-methods-firestore.d.ts +12 -1
- package/dist/features/pre-orders/api/[slug]/route.js +1 -1
- package/dist/features/pre-orders/api/admin/route.js +1 -1
- package/dist/features/pre-orders/api/route.js +1 -1
- package/dist/features/pre-orders/repository/pre-orders.repository.d.ts +3 -3
- package/dist/features/pre-orders/repository/pre-orders.repository.js +6 -6
- package/dist/features/products/api/[id]/route.js +1 -1
- package/dist/features/products/components/ListingBottomActions.js +4 -0
- package/dist/features/products/components/ProductDetailPageView.js +2 -1
- package/dist/features/products/components/ProductGalleryClient.js +2 -2
- package/dist/features/products/components/ProductGrid.js +12 -1
- package/dist/features/products/components/index.d.ts +0 -2
- package/dist/features/products/components/index.js +0 -1
- package/dist/features/products/config/listing-type-listing-config.d.ts +0 -3
- package/dist/features/products/config/listing-type-listing-config.js +27 -2
- package/dist/features/products/constants/listing-tabs.d.ts +9 -0
- package/dist/features/products/constants/listing-tabs.js +3 -2
- package/dist/features/products/hooks/useProducts.js +2 -2
- package/dist/features/products/repository/products.repository.js +13 -1
- package/dist/features/products/schemas/index.d.ts +2 -2
- package/dist/features/products/types/index.d.ts +1 -1
- package/dist/features/promotions/api/route.js +1 -1
- package/dist/features/reviews/actions/review-actions.d.ts +6 -6
- package/dist/features/reviews/actions/review-actions.js +22 -8
- package/dist/features/reviews/components/ReviewDetailPageView.js +13 -1
- package/dist/features/reviews/components/ReviewsIndexPageView.js +21 -4
- package/dist/features/reviews/repository/reviews.repository.d.ts +19 -7
- package/dist/features/reviews/repository/reviews.repository.js +63 -12
- package/dist/features/reviews/schemas/firestore.d.ts +13 -2
- package/dist/features/reviews/schemas/index.d.ts +2 -2
- package/dist/features/scams/actions/scam-actions.js +16 -4
- package/dist/features/search/components/SearchResultsPageView.js +2 -1
- package/dist/features/search/hooks/useSearchIndex.d.ts +34 -0
- package/dist/features/search/hooks/useSearchIndex.js +172 -0
- package/dist/features/search/repository/search.repository.js +2 -2
- package/dist/features/seller/actions/offer-actions.d.ts +5 -5
- package/dist/features/seller/actions/offer-actions.js +38 -8
- package/dist/features/seller/actions/seller-actions.js +34 -7
- package/dist/features/seller/api/coupons/route.js +1 -1
- package/dist/features/seller/api/products/route.js +1 -1
- package/dist/features/seller/api/store/route.js +1 -1
- package/dist/features/seller/components/SellerBidsView.js +1 -1
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerListingTypeView.js +9 -1
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +0 -1
- package/dist/features/seller/components/SellerPayoutsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.js +0 -1
- package/dist/features/seller/components/SellerProductsView.js +1 -1
- package/dist/features/seller/components/SellerShippingView.js +0 -1
- package/dist/features/seller/components/SellerStorefrontView.js +0 -1
- package/dist/features/seller/components/index.d.ts +0 -4
- package/dist/features/seller/components/index.js +0 -2
- package/dist/features/seller/repository/offer.repository.d.ts +15 -3
- package/dist/features/seller/repository/offer.repository.js +43 -7
- package/dist/features/seller/schemas/firestore.d.ts +14 -3
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/seller/schemas/order-forms.d.ts +39 -0
- package/dist/features/seller/schemas/order-forms.js +37 -0
- package/dist/features/shell/FormShell.js +6 -2
- package/dist/features/shell/QuickFormDrawer.js +15 -1
- package/dist/features/shipments/components/AdminShipmentEditorView.js +0 -1
- package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
- package/dist/features/sticker-trace/components/StickerCommitPanel.d.ts +30 -0
- package/dist/features/sticker-trace/components/StickerCommitPanel.js +93 -0
- package/dist/features/sticker-trace/components/StickerPrintPanel.d.ts +33 -0
- package/dist/features/sticker-trace/components/StickerPrintPanel.js +104 -0
- package/dist/features/sticker-trace/components/StickerRetryPanel.d.ts +20 -0
- package/dist/features/sticker-trace/components/StickerRetryPanel.js +128 -0
- package/dist/features/sticker-trace/components/StickerRunHistoryPanel.d.ts +45 -0
- package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +84 -0
- package/dist/features/sticker-trace/components/StickerTraceStudio.d.ts +27 -0
- package/dist/features/sticker-trace/components/StickerTraceStudio.js +171 -0
- package/dist/features/sticker-trace/constants/help-content.d.ts +23 -0
- package/dist/features/sticker-trace/constants/help-content.js +172 -0
- package/dist/features/sticker-trace/hooks/useLiveTrace.d.ts +27 -0
- package/dist/features/sticker-trace/hooks/useLiveTrace.js +160 -0
- package/dist/features/sticker-trace/hooks/useStickerTraceProgress.d.ts +22 -0
- package/dist/features/sticker-trace/hooks/useStickerTraceProgress.js +106 -0
- package/dist/features/sticker-trace/repository/sticker-sheets.repository.d.ts +113 -0
- package/dist/features/sticker-trace/repository/sticker-sheets.repository.js +146 -0
- package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.d.ts +132 -0
- package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.js +174 -0
- package/dist/features/sticker-trace/schemas/firestore.d.ts +248 -0
- package/dist/features/sticker-trace/schemas/firestore.js +79 -0
- package/dist/features/sticker-trace/server.d.ts +8 -0
- package/dist/features/sticker-trace/server.js +51 -0
- package/dist/features/stores/actions/store-query-actions.d.ts +2 -2
- package/dist/features/stores/actions/store-query-actions.js +7 -2
- package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -3
- package/dist/features/stores/api/[storeSlug]/products/route.js +3 -3
- package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
- package/dist/features/stores/api/[storeSlug]/route.js +1 -1
- package/dist/features/stores/components/StoreNavTabs.js +17 -2
- package/dist/features/stores/manifest.js +8 -4
- package/dist/features/support/repository/support.repository.d.ts +14 -3
- package/dist/features/support/repository/support.repository.js +93 -13
- package/dist/features/support/schemas/firestore.d.ts +16 -5
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +61 -19
- package/dist/features/tester/seed-data/authored/buying__browsing-search.js +19 -3
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +243 -0
- package/dist/features/tester/seed-data/authored/content-discovery__events.js +36 -10
- package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +209 -0
- package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +90 -0
- package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.js +85 -0
- package/dist/features/tester/seed-data/authored/index.js +10 -0
- package/dist/features/tester/seed-data/authored/selling__media-limits.js +19 -17
- package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +10 -5
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +283 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +235 -22
- package/dist/index.d.ts +10 -23
- package/dist/index.js +27 -19
- package/dist/next/api/routeHandler.js +9 -0
- package/dist/next/routing/require-record.d.ts +13 -0
- package/dist/next/routing/require-record.js +62 -0
- package/dist/next/routing/route-map.d.ts +4 -4
- package/dist/next/routing/route-map.js +25 -3
- package/dist/providers/db-firebase/base.d.ts +4 -2
- package/dist/providers/db-firebase/base.js +21 -5
- package/dist/providers/db-firebase/base.repository.d.ts +11 -9
- package/dist/providers/db-firebase/base.repository.js +19 -0
- package/dist/providers/db-firebase/rtdb-paths.d.ts +12 -0
- package/dist/providers/db-firebase/rtdb-paths.js +12 -0
- package/dist/react/ErrorBoundary.js +6 -1
- package/dist/react/hooks/realtime-event-constants.d.ts +1 -0
- package/dist/react/hooks/realtime-event-constants.js +8 -0
- package/dist/react/hooks/useEntityDelete.js +5 -1
- package/dist/react/hooks/useMessage.js +5 -1
- package/dist/repositories/index.d.ts +2 -2
- package/dist/repositories/index.js +6 -1
- package/dist/schemas/registry.d.ts +13 -20
- package/dist/schemas/registry.js +31 -14
- package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
- package/dist/security/encrypted.d.ts +117 -0
- package/dist/security/encrypted.js +100 -0
- package/dist/security/index.d.ts +5 -2
- package/dist/security/index.js +16 -2
- package/dist/security/pii-accessors.d.ts +71 -0
- package/dist/security/pii-accessors.js +150 -0
- package/dist/security/pii-encrypt.d.ts +0 -8
- package/dist/security/pii-encrypt.js +22 -15
- package/dist/security/pii-mask.d.ts +18 -0
- package/dist/security/pii-mask.js +27 -0
- package/dist/seed/_helpers/search-txt-wrappers.d.ts +6 -6
- package/dist/seed/_helpers/search-txt-wrappers.js +22 -0
- package/dist/seed/addresses-seed-data.d.ts +2 -2
- package/dist/seed/authenticity-knowledge-seed-data.d.ts +34 -0
- package/dist/seed/authenticity-knowledge-seed-data.js +1277 -0
- package/dist/seed/bids-seed-data.d.ts +2 -2
- package/dist/seed/bids-seed-data.js +23 -2
- package/dist/seed/events-seed-data.d.ts +2 -2
- package/dist/seed/events-seed-data.js +5 -0
- package/dist/seed/faq-seed-data.js +175 -5
- package/dist/seed/homepage-sections-seed-data.js +39 -23
- package/dist/seed/index.d.ts +1 -0
- package/dist/seed/index.js +1 -0
- package/dist/seed/lottery-entries-seed-data.d.ts +2 -2
- package/dist/seed/offers-seed-data.d.ts +2 -2
- package/dist/seed/offers-seed-data.js +1 -1
- package/dist/seed/orders-seed-data.d.ts +2 -2
- package/dist/seed/payouts-seed-data.d.ts +2 -2
- package/dist/seed/payouts-seed-data.js +1 -1
- package/dist/seed/reviews-seed-data.d.ts +1 -2
- package/dist/seed/seed-purpose.js +7 -0
- package/dist/seed/sessions-seed-data.d.ts +2 -2
- package/dist/seed/sessions-seed-data.js +5 -0
- package/dist/seed/site-settings-seed-data.js +1 -1
- package/dist/seed/support-tickets-seed-data.d.ts +2 -2
- package/dist/seed/support-tickets-seed-data.js +1 -1
- package/dist/seed/users-seed-data.d.ts +2 -2
- package/dist/seed/users-seed-data.js +1 -1
- package/dist/seo/json-ld.js +5 -1
- package/dist/server.d.ts +18 -3
- package/dist/server.js +59 -3
- package/dist/styles.css +237 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Button.js +7 -1
- package/dist/ui/components/FilterChipGroup.d.ts +11 -0
- package/dist/ui/components/FilterChipGroup.js +1 -1
- package/dist/ui/components/ImageGallery.js +6 -1
- package/dist/ui/components/ListingLayout.js +14 -8
- package/dist/ui/components/OverflowRow.d.ts +92 -0
- package/dist/ui/components/OverflowRow.js +203 -0
- package/dist/ui/components/OverflowRow.style.css +235 -0
- package/dist/ui/components/RecordDetailModal.js +14 -1
- package/dist/ui/components/RowActionMenu.js +5 -1
- package/dist/ui/components/SideDrawer.js +5 -1
- package/dist/ui/components/SideModal.js +9 -1
- package/dist/ui/components/TabBarShell.d.ts +12 -1
- package/dist/ui/components/TabBarShell.js +3 -2
- package/dist/ui/components/Tabs.js +36 -24
- package/dist/ui/components/Toast.d.ts +3 -24
- package/dist/ui/components/Toast.js +2 -19
- package/dist/ui/components/TopBannerPortal.d.ts +15 -0
- package/dist/ui/components/TopBannerPortal.js +19 -0
- package/dist/ui/components/UnsavedChangesModal.js +5 -1
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/components/row-collapse.d.ts +15 -0
- package/dist/ui/components/row-collapse.js +127 -0
- package/dist/ui/components/toast-context.d.ts +63 -0
- package/dist/ui/components/toast-context.js +48 -0
- package/dist/ui/components/top-banner-slot.d.ts +37 -0
- package/dist/ui/components/top-banner-slot.js +45 -0
- package/dist/ui/icons/icon-registry.d.ts +6 -0
- package/dist/ui/icons/icon-registry.js +17 -1
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/utils/array.helper.d.ts +2 -2
- package/dist/utils/array.helper.js +5 -5
- package/dist/utils/id-generators.d.ts +6 -0
- package/dist/utils/id-generators.js +10 -0
- package/dist/utils/media-url.js +0 -2
- package/dist/utils/search-txt-builders.d.ts +28 -4
- package/dist/utils/search-txt-builders.js +41 -1
- package/dist/validation/schemas.d.ts +8 -8
- package/package.json +6 -2
- package/scripts/seed-cli.mjs +3 -0
- package/dist/features/account/components/UserAddressesView.d.ts +0 -13
- package/dist/features/account/components/UserAddressesView.js +0 -5
- package/dist/features/account/components/UserNotificationsView.d.ts +0 -15
- package/dist/features/account/components/UserNotificationsView.js +0 -12
- package/dist/features/account/components/UserSettingsView.d.ts +0 -16
- package/dist/features/account/components/UserSettingsView.js +0 -13
- package/dist/features/account/components/UserSupportView.d.ts +0 -3
- package/dist/features/account/components/UserSupportView.js +0 -166
- package/dist/features/admin/components/DemoSeedView.d.ts +0 -11
- package/dist/features/admin/components/DemoSeedView.js +0 -5
- package/dist/features/auth/components/AuthStatusPanel.d.ts +0 -10
- package/dist/features/auth/components/AuthStatusPanel.js +0 -22
- package/dist/features/categories/components/CategoryProductsView.d.ts +0 -45
- package/dist/features/categories/components/CategoryProductsView.js +0 -21
- package/dist/features/homepage/components/HowItWorksInfoView.d.ts +0 -36
- package/dist/features/homepage/components/HowItWorksInfoView.js +0 -10
- package/dist/features/layout/BottomActions.d.ts +0 -1
- package/dist/features/layout/BottomActions.js +0 -311
- package/dist/features/products/components/ProductsView.d.ts +0 -6
- package/dist/features/products/components/ProductsView.js +0 -5
- package/dist/features/seller/components/SellerStoreView.d.ts +0 -8
- package/dist/features/seller/components/SellerStoreView.js +0 -8
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/*
|
|
3
|
+
* WHY: A trace takes minutes and fans out across shards. "Even if we fail we
|
|
4
|
+
* know" was the requirement, and a spinner cannot express which of eleven
|
|
5
|
+
* stages a run died in.
|
|
6
|
+
* WHAT: Subscribe to one run's live progress on sticker_trace/{runId}.
|
|
7
|
+
*
|
|
8
|
+
* ๐ Built on `useRealtimeEvent`, not on a fresh RTDB subscription. That hook
|
|
9
|
+
* already owns the per-event custom-token sign-in, the reference-counted
|
|
10
|
+
* session lease, the timeout and the unsubscribe โ and `useBulkEvent` is the
|
|
11
|
+
* precedent for wrapping it per feature. Rolling a second subscription would
|
|
12
|
+
* duplicate the lease accounting, which is the part that leaks a connection
|
|
13
|
+
* when it is wrong.
|
|
14
|
+
*
|
|
15
|
+
* ๐ This is the LIVE bar only. The durable record is the run document's capped
|
|
16
|
+
* `events[]`, which is what a post-mortem reads weeks later โ and the RTDB node
|
|
17
|
+
* is pruned at 60 minutes. A UI that treats this hook as the history will show
|
|
18
|
+
* nothing for any run older than an hour.
|
|
19
|
+
*
|
|
20
|
+
* EXPORTS: useStickerTraceProgress, StickerTraceProgress
|
|
21
|
+
*
|
|
22
|
+
* @tag domain:sticker-trace
|
|
23
|
+
* @tag layer:feature
|
|
24
|
+
* @tag pattern:hook
|
|
25
|
+
* @tag access:client
|
|
26
|
+
* @tag consumers:sticker-trace/components
|
|
27
|
+
* @tag sideEffects:none
|
|
28
|
+
*/
|
|
29
|
+
import { useCallback, useMemo } from "react";
|
|
30
|
+
import { useRealtimeEvent } from "../../../react/hooks/useRealtimeEvent.js";
|
|
31
|
+
import { RealtimeEventType } from "../../../react/hooks/realtime-event-constants.js";
|
|
32
|
+
import { RTDB_PATHS } from "../../../providers/db-firebase/rtdb-paths.js";
|
|
33
|
+
const BLANK = {
|
|
34
|
+
stage: null,
|
|
35
|
+
pct: 0,
|
|
36
|
+
partsDone: null,
|
|
37
|
+
partsTotal: null,
|
|
38
|
+
shardsDone: null,
|
|
39
|
+
shardsTotal: null,
|
|
40
|
+
message: null,
|
|
41
|
+
level: null,
|
|
42
|
+
terminal: false,
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* ๐ Every field is read DEFENSIVELY, and nulls are preserved rather than
|
|
46
|
+
* defaulted to 0.
|
|
47
|
+
*
|
|
48
|
+
* The writer is the coordinator, the shards and the finalizer โ three
|
|
49
|
+
* processes, writing partial payloads at different stages (a shard reports
|
|
50
|
+
* parts and knows nothing about exports). Defaulting a missing `partsTotal` to
|
|
51
|
+
* 0 would render "12 of 0 parts", which reads as a bug in the tracer rather
|
|
52
|
+
* than as a field this stage does not populate. Null means "not applicable
|
|
53
|
+
* here", and the UI can omit the clause.
|
|
54
|
+
*/
|
|
55
|
+
function extract(raw) {
|
|
56
|
+
if (!raw || typeof raw !== "object")
|
|
57
|
+
return null;
|
|
58
|
+
const r = raw;
|
|
59
|
+
const num = (v) => (typeof v === "number" && Number.isFinite(v) ? v : null);
|
|
60
|
+
const str = (v) => (typeof v === "string" && v.length > 0 ? v : null);
|
|
61
|
+
return {
|
|
62
|
+
stage: str(r.stage) ?? null,
|
|
63
|
+
pct: num(r.pct) ?? 0,
|
|
64
|
+
partsDone: num(r.partsDone),
|
|
65
|
+
partsTotal: num(r.partsTotal),
|
|
66
|
+
shardsDone: num(r.shardsDone),
|
|
67
|
+
shardsTotal: num(r.shardsTotal),
|
|
68
|
+
message: str(r.message),
|
|
69
|
+
level: str(r.level) ?? null,
|
|
70
|
+
terminal: r.terminal === true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function useStickerTraceProgress() {
|
|
74
|
+
const { data, subscribe, error } = useRealtimeEvent({
|
|
75
|
+
type: RealtimeEventType.STICKER_TRACE,
|
|
76
|
+
rtdbPath: RTDB_PATHS.STICKER_TRACE,
|
|
77
|
+
extractData: (raw) => extract(raw),
|
|
78
|
+
/*
|
|
79
|
+
* 20 minutes. The channel's own prune window is 60, and a `max`-tier
|
|
80
|
+
* fan-out across sixty parts can run for several โ so a short client
|
|
81
|
+
* timeout would report a dead run that is still working, which is the one
|
|
82
|
+
* false signal this channel exists to prevent. The run document remains
|
|
83
|
+
* authoritative either way.
|
|
84
|
+
*/
|
|
85
|
+
timeoutMs: 20 * 60 * 1000,
|
|
86
|
+
});
|
|
87
|
+
const progress = data ?? BLANK;
|
|
88
|
+
/*
|
|
89
|
+
* The label names the STAGE, never just a percentage. "Processing 43%" is
|
|
90
|
+
* what a spinner says; "ridge 22%" is what lets an operator recognise that a
|
|
91
|
+
* halftone scan is stuck in the detector rather than in the upload.
|
|
92
|
+
*/
|
|
93
|
+
const label = useMemo(() => {
|
|
94
|
+
if (!progress.stage)
|
|
95
|
+
return null;
|
|
96
|
+
const parts = progress.partsDone !== null && progress.partsTotal !== null
|
|
97
|
+
? ` ${progress.partsDone}/${progress.partsTotal} parts`
|
|
98
|
+
: "";
|
|
99
|
+
const shards = progress.shardsDone !== null && progress.shardsTotal !== null
|
|
100
|
+
? ` ยท shard ${progress.shardsDone}/${progress.shardsTotal}`
|
|
101
|
+
: "";
|
|
102
|
+
return `${progress.stage} ${progress.pct}%${parts}${shards}`;
|
|
103
|
+
}, [progress]);
|
|
104
|
+
const start = useCallback((runId, customToken) => subscribe(runId, customToken), [subscribe]);
|
|
105
|
+
return { progress, subscribe: start, label, error };
|
|
106
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { BaseRepository, parseSieveDateValue, type SieveModel, type FirebaseSieveResult } from "../../../providers/db-firebase";
|
|
2
|
+
import { type SheetArtifacts, type SheetPart, type StickerSheetDocument } from "../schemas/firestore";
|
|
3
|
+
/** What a caller supplies to register a freshly uploaded scan. */
|
|
4
|
+
export interface StickerSheetCreateInput {
|
|
5
|
+
title: string;
|
|
6
|
+
scanType: StickerSheetDocument["scanType"];
|
|
7
|
+
widthPx: number;
|
|
8
|
+
heightPx: number;
|
|
9
|
+
sourceScan: StickerSheetDocument["sourceScan"];
|
|
10
|
+
dpi?: number;
|
|
11
|
+
dpiSource?: StickerSheetDocument["dpiSource"];
|
|
12
|
+
}
|
|
13
|
+
export declare class StickerSheetsRepository extends BaseRepository<StickerSheetDocument> {
|
|
14
|
+
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* The ONE create path, so a sheet cannot exist without its counters.
|
|
17
|
+
*
|
|
18
|
+
* `traceStatus` starts `queued` rather than absent: a Firestore equality
|
|
19
|
+
* cannot match a missing field, so a sheet with no status would be absent
|
|
20
|
+
* from its own admin list while rendering perfectly by id (Root Cause #101).
|
|
21
|
+
*
|
|
22
|
+
* Deliberately not `createWithId` โ that does a read-after-write, costing a
|
|
23
|
+
* Firestore read on every create against Rule #6's budget, for a document
|
|
24
|
+
* this function already holds in full.
|
|
25
|
+
*/
|
|
26
|
+
create(input: StickerSheetCreateInput): Promise<StickerSheetDocument>;
|
|
27
|
+
/**
|
|
28
|
+
* Accept a run's result as the sheet's current one.
|
|
29
|
+
*
|
|
30
|
+
* ๐ `artifacts` is REPLACED, not merged. A promotion means "this run's
|
|
31
|
+
* output is what the sheet shows now", so carrying a previous run's
|
|
32
|
+
* `overlayPath` forward would leave the sheet pointing at an overlay drawn
|
|
33
|
+
* from different geometry than its own `parts` โ two halves of two different
|
|
34
|
+
* runs, with nothing anywhere contradicting it (Root Cause #42's shape).
|
|
35
|
+
* The superseded run keeps its own artifacts on its own document; nothing is
|
|
36
|
+
* lost, and the history is what makes that safe.
|
|
37
|
+
*/
|
|
38
|
+
promoteRun(sheetId: string, runId: string, result: {
|
|
39
|
+
parts: SheetPart[];
|
|
40
|
+
groupCount: number;
|
|
41
|
+
artifacts: SheetArtifacts;
|
|
42
|
+
}): Promise<StickerSheetDocument>;
|
|
43
|
+
/**
|
|
44
|
+
* Rename one part, or mark it a duplicate of another.
|
|
45
|
+
*
|
|
46
|
+
* Matched on `ordinal`, never on array index โ removing a part shifts every
|
|
47
|
+
* later index by one, so an index-wise write renames the wrong sticker. Same
|
|
48
|
+
* rule as ยง "Lottery Config Writes" merges by `slotNumber`.
|
|
49
|
+
*
|
|
50
|
+
* An unknown ordinal is a no-op that throws rather than a silent miss: the
|
|
51
|
+
* caller named a part that is not on this sheet, and answering 200 to that
|
|
52
|
+
* is how a rename appears to work and does nothing (Root Cause #40).
|
|
53
|
+
*/
|
|
54
|
+
updatePart(sheetId: string, ordinal: number, patch: Partial<Pick<SheetPart, "name" | "duplicateOf">>): Promise<StickerSheetDocument>;
|
|
55
|
+
listForAdmin(model: SieveModel): Promise<FirebaseSieveResult<StickerSheetDocument>>;
|
|
56
|
+
/**
|
|
57
|
+
* Every sheet's stored bytes, for the usage meter.
|
|
58
|
+
*
|
|
59
|
+
* `.select()` on the two size fields rather than a full read: the meter sums
|
|
60
|
+
* numbers and never renders a sheet's parts, and a full scan of documents
|
|
61
|
+
* carrying up to sixty `SheetPart` entries each is real payload for a figure
|
|
62
|
+
* that is two integers wide.
|
|
63
|
+
*/
|
|
64
|
+
listSizes(): Promise<Array<{
|
|
65
|
+
id: string;
|
|
66
|
+
title: string;
|
|
67
|
+
bytes: number;
|
|
68
|
+
}>>;
|
|
69
|
+
/**
|
|
70
|
+
* ๐ Every Timestamp field carries `parseSieveDateValue`.
|
|
71
|
+
*
|
|
72
|
+
* Without it a GTE/LTE filter reaches Firestore as an ISO *string* against a
|
|
73
|
+
* stored Timestamp, matches ZERO documents, and raises nothing โ Root Cause
|
|
74
|
+
* #47, which cost 27 repository files to fix once.
|
|
75
|
+
*/
|
|
76
|
+
static readonly SIEVE_FIELDS: {
|
|
77
|
+
id: {
|
|
78
|
+
canFilter: boolean;
|
|
79
|
+
canSort: boolean;
|
|
80
|
+
};
|
|
81
|
+
title: {
|
|
82
|
+
canFilter: boolean;
|
|
83
|
+
canSort: boolean;
|
|
84
|
+
};
|
|
85
|
+
scanType: {
|
|
86
|
+
canFilter: boolean;
|
|
87
|
+
canSort: boolean;
|
|
88
|
+
};
|
|
89
|
+
traceStatus: {
|
|
90
|
+
canFilter: boolean;
|
|
91
|
+
canSort: boolean;
|
|
92
|
+
};
|
|
93
|
+
activeRunId: {
|
|
94
|
+
canFilter: boolean;
|
|
95
|
+
canSort: boolean;
|
|
96
|
+
};
|
|
97
|
+
partCount: {
|
|
98
|
+
canFilter: boolean;
|
|
99
|
+
canSort: boolean;
|
|
100
|
+
};
|
|
101
|
+
createdAt: {
|
|
102
|
+
canFilter: boolean;
|
|
103
|
+
canSort: boolean;
|
|
104
|
+
parseValue: typeof parseSieveDateValue;
|
|
105
|
+
};
|
|
106
|
+
updatedAt: {
|
|
107
|
+
canFilter: boolean;
|
|
108
|
+
canSort: boolean;
|
|
109
|
+
parseValue: typeof parseSieveDateValue;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export declare const stickerSheetsRepository: StickerSheetsRepository;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: One scanned sheet, and the CURRENT accepted result for it. Every
|
|
3
|
+
* attempt that produced that result lives in `stickerTraceRuns` โ this
|
|
4
|
+
* document only ever holds the one a human chose.
|
|
5
|
+
* WHAT: Reads, the create funnel, and promotion of a run's artifacts onto the
|
|
6
|
+
* sheet.
|
|
7
|
+
*
|
|
8
|
+
* ๐ This repository holds NO PII and declares no `piiFields`. A sticker sheet
|
|
9
|
+
* is an admin's own scan: the only person-shaped field anywhere near it is
|
|
10
|
+
* `PromotedArtifacts.by`, which is an Auth UID โ the same thing every
|
|
11
|
+
* `actorUid` in ยง "Status History" is, and explicitly NOT PII there either.
|
|
12
|
+
* Declaring a `piiFields` list for a document with nothing to encrypt is the
|
|
13
|
+
* fiction Root Cause #50 is about: a named mechanism whose name is the only
|
|
14
|
+
* evidence it does anything.
|
|
15
|
+
*
|
|
16
|
+
* EXPORTS: StickerSheetsRepository, stickerSheetsRepository
|
|
17
|
+
*
|
|
18
|
+
* @tag domain:sticker-trace
|
|
19
|
+
* @tag layer:feature
|
|
20
|
+
* @tag pattern:repository
|
|
21
|
+
* @tag access:server
|
|
22
|
+
* @tag consumers:sticker-trace/actions,api/admin/sticker-sheets
|
|
23
|
+
* @tag sideEffects:firestore
|
|
24
|
+
*/
|
|
25
|
+
import { BaseRepository, prepareForFirestore, parseSieveDateValue, } from "../../../providers/db-firebase/index.js";
|
|
26
|
+
import { generateStickerSheetId } from "../../../utils/id-generators.js";
|
|
27
|
+
import { STICKER_SHEETS_COLLECTION, STICKER_SHEET_FIELDS, TraceRunStatusValues, } from "../schemas/firestore.js";
|
|
28
|
+
export class StickerSheetsRepository extends BaseRepository {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(STICKER_SHEETS_COLLECTION);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The ONE create path, so a sheet cannot exist without its counters.
|
|
34
|
+
*
|
|
35
|
+
* `traceStatus` starts `queued` rather than absent: a Firestore equality
|
|
36
|
+
* cannot match a missing field, so a sheet with no status would be absent
|
|
37
|
+
* from its own admin list while rendering perfectly by id (Root Cause #101).
|
|
38
|
+
*
|
|
39
|
+
* Deliberately not `createWithId` โ that does a read-after-write, costing a
|
|
40
|
+
* Firestore read on every create against Rule #6's budget, for a document
|
|
41
|
+
* this function already holds in full.
|
|
42
|
+
*/
|
|
43
|
+
async create(input) {
|
|
44
|
+
const id = generateStickerSheetId({ title: input.title });
|
|
45
|
+
const now = new Date();
|
|
46
|
+
const data = {
|
|
47
|
+
...input,
|
|
48
|
+
traceStatus: TraceRunStatusValues.QUEUED,
|
|
49
|
+
partCount: 0,
|
|
50
|
+
groupCount: 0,
|
|
51
|
+
artifacts: {},
|
|
52
|
+
parts: [],
|
|
53
|
+
createdAt: now,
|
|
54
|
+
updatedAt: now,
|
|
55
|
+
};
|
|
56
|
+
await this.getCollection().doc(id).set(prepareForFirestore(data));
|
|
57
|
+
return { id, ...data };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Accept a run's result as the sheet's current one.
|
|
61
|
+
*
|
|
62
|
+
* ๐ `artifacts` is REPLACED, not merged. A promotion means "this run's
|
|
63
|
+
* output is what the sheet shows now", so carrying a previous run's
|
|
64
|
+
* `overlayPath` forward would leave the sheet pointing at an overlay drawn
|
|
65
|
+
* from different geometry than its own `parts` โ two halves of two different
|
|
66
|
+
* runs, with nothing anywhere contradicting it (Root Cause #42's shape).
|
|
67
|
+
* The superseded run keeps its own artifacts on its own document; nothing is
|
|
68
|
+
* lost, and the history is what makes that safe.
|
|
69
|
+
*/
|
|
70
|
+
async promoteRun(sheetId, runId, result) {
|
|
71
|
+
return this.update(sheetId, {
|
|
72
|
+
activeRunId: runId,
|
|
73
|
+
traceStatus: TraceRunStatusValues.SUCCEEDED,
|
|
74
|
+
partCount: result.parts.length,
|
|
75
|
+
groupCount: result.groupCount,
|
|
76
|
+
parts: result.parts,
|
|
77
|
+
artifacts: result.artifacts,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Rename one part, or mark it a duplicate of another.
|
|
82
|
+
*
|
|
83
|
+
* Matched on `ordinal`, never on array index โ removing a part shifts every
|
|
84
|
+
* later index by one, so an index-wise write renames the wrong sticker. Same
|
|
85
|
+
* rule as ยง "Lottery Config Writes" merges by `slotNumber`.
|
|
86
|
+
*
|
|
87
|
+
* An unknown ordinal is a no-op that throws rather than a silent miss: the
|
|
88
|
+
* caller named a part that is not on this sheet, and answering 200 to that
|
|
89
|
+
* is how a rename appears to work and does nothing (Root Cause #40).
|
|
90
|
+
*/
|
|
91
|
+
async updatePart(sheetId, ordinal, patch) {
|
|
92
|
+
const sheet = await this.findByIdOrFail(sheetId);
|
|
93
|
+
const index = sheet.parts.findIndex((p) => p.ordinal === ordinal);
|
|
94
|
+
if (index === -1) {
|
|
95
|
+
throw new Error(`Sticker sheet ${sheetId} has no part with ordinal ${ordinal}`);
|
|
96
|
+
}
|
|
97
|
+
const parts = [...sheet.parts];
|
|
98
|
+
parts[index] = { ...parts[index], ...patch };
|
|
99
|
+
return this.update(sheetId, { parts });
|
|
100
|
+
}
|
|
101
|
+
async listForAdmin(model) {
|
|
102
|
+
return this.sieveQuery(model, StickerSheetsRepository.SIEVE_FIELDS, {
|
|
103
|
+
defaultPageSize: 25,
|
|
104
|
+
maxPageSize: 50,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Every sheet's stored bytes, for the usage meter.
|
|
109
|
+
*
|
|
110
|
+
* `.select()` on the two size fields rather than a full read: the meter sums
|
|
111
|
+
* numbers and never renders a sheet's parts, and a full scan of documents
|
|
112
|
+
* carrying up to sixty `SheetPart` entries each is real payload for a figure
|
|
113
|
+
* that is two integers wide.
|
|
114
|
+
*/
|
|
115
|
+
async listSizes() {
|
|
116
|
+
const snap = await this.getCollection()
|
|
117
|
+
.select(STICKER_SHEET_FIELDS.TITLE, "sourceScan")
|
|
118
|
+
.get();
|
|
119
|
+
return snap.docs.map((doc) => {
|
|
120
|
+
const data = doc.data();
|
|
121
|
+
return {
|
|
122
|
+
id: doc.id,
|
|
123
|
+
title: data.title ?? doc.id,
|
|
124
|
+
bytes: data.sourceScan?.bytes ?? 0,
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* ๐ Every Timestamp field carries `parseSieveDateValue`.
|
|
131
|
+
*
|
|
132
|
+
* Without it a GTE/LTE filter reaches Firestore as an ISO *string* against a
|
|
133
|
+
* stored Timestamp, matches ZERO documents, and raises nothing โ Root Cause
|
|
134
|
+
* #47, which cost 27 repository files to fix once.
|
|
135
|
+
*/
|
|
136
|
+
StickerSheetsRepository.SIEVE_FIELDS = {
|
|
137
|
+
id: { canFilter: true, canSort: false },
|
|
138
|
+
title: { canFilter: true, canSort: true },
|
|
139
|
+
scanType: { canFilter: true, canSort: false },
|
|
140
|
+
traceStatus: { canFilter: true, canSort: false },
|
|
141
|
+
activeRunId: { canFilter: true, canSort: false },
|
|
142
|
+
partCount: { canFilter: true, canSort: true },
|
|
143
|
+
createdAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
|
|
144
|
+
updatedAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
|
|
145
|
+
};
|
|
146
|
+
export const stickerSheetsRepository = new StickerSheetsRepository();
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { BaseRepository, parseSieveDateValue, type SieveModel, type FirebaseSieveResult } from "../../../providers/db-firebase";
|
|
2
|
+
import { type PromotedArtifacts, type RunArtifacts, type StickerTraceRunDocument, type TraceRunError, type TraceRunEvent } from "../schemas/firestore";
|
|
3
|
+
export interface StickerTraceRunCreateInput {
|
|
4
|
+
sheetId: string;
|
|
5
|
+
/** ๐ Mandatory. The reason history is worth keeping is being able to tell runs apart. */
|
|
6
|
+
name: string;
|
|
7
|
+
tier: StickerTraceRunDocument["tier"];
|
|
8
|
+
params: StickerTraceRunDocument["params"];
|
|
9
|
+
requestedBy: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class StickerTraceRunsRepository extends BaseRepository<StickerTraceRunDocument> {
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* A run is born `queued` with an empty event log and zeroed counts.
|
|
15
|
+
*
|
|
16
|
+
* Firestore assigns the id (the ยง "Slug Prefix System" convention for
|
|
17
|
+
* `carts` / `jobs` / `notifications`): a run carries a mandatory human NAME,
|
|
18
|
+
* which is what anyone reads, so a second slug prefix would add a parse
|
|
19
|
+
* surface and a collision story for no reader. The id appears only in a
|
|
20
|
+
* Storage path and an RTDB channel key.
|
|
21
|
+
*/
|
|
22
|
+
create(input: StickerTraceRunCreateInput): Promise<StickerTraceRunDocument>;
|
|
23
|
+
/**
|
|
24
|
+
* Append one progress transition, FIFO-capped.
|
|
25
|
+
*
|
|
26
|
+
* ๐ `arrayUnion` cannot enforce a cap, so this folds in memory and writes
|
|
27
|
+
* the whole array โ the same constraint ยง "Status History" records, and the
|
|
28
|
+
* reason `prior` exists here: the coordinator and the finalizer each hold
|
|
29
|
+
* the run already, so threading it costs **zero extra reads**. Omitting it
|
|
30
|
+
* is legal and pays one read.
|
|
31
|
+
*
|
|
32
|
+
* ๐ Truncation is RECORDED, never silent. `eventsTruncated` is what lets a
|
|
33
|
+
* reader say "earlier progress trimmed" instead of implying a `max`-tier run
|
|
34
|
+
* with sixty shards simply had ten events.
|
|
35
|
+
*/
|
|
36
|
+
appendEvent(runId: string, event: TraceRunEvent, prior?: StickerTraceRunDocument | null): Promise<StickerTraceRunDocument>;
|
|
37
|
+
/** `queued` โ `running`, stamping the clock the duration is measured from. */
|
|
38
|
+
markStarted(runId: string, shardCount?: number): Promise<StickerTraceRunDocument>;
|
|
39
|
+
/**
|
|
40
|
+
* Terminal success.
|
|
41
|
+
*
|
|
42
|
+
* `durationMs` is computed from the run's own `startedAt` rather than
|
|
43
|
+
* accepted from the caller โ two call sites each subtracting their own pair
|
|
44
|
+
* of timestamps is how the number ends up meaning different things on
|
|
45
|
+
* different runs (Root Cause #75).
|
|
46
|
+
*/
|
|
47
|
+
markSucceeded(runId: string, result: {
|
|
48
|
+
partCount: number;
|
|
49
|
+
groupCount: number;
|
|
50
|
+
artifacts: RunArtifacts;
|
|
51
|
+
}, prior?: StickerTraceRunDocument | null): Promise<StickerTraceRunDocument>;
|
|
52
|
+
/**
|
|
53
|
+
* Terminal failure, naming the stage it died in.
|
|
54
|
+
*
|
|
55
|
+
* ๐ `error.message` must already be user-safe โ resolved through
|
|
56
|
+
* `toUserMessage`, never raw server text. A Node `MODULE_NOT_FOUND` with a
|
|
57
|
+
* full require stack rendered inside a progress panel is Root Cause #86, and
|
|
58
|
+
* it reached a buyer's bid modal once already.
|
|
59
|
+
*
|
|
60
|
+
* Partial artifacts are KEPT when the caller has them: a run that failed at
|
|
61
|
+
* `parts` still produced a preview and an overlay, and those are exactly
|
|
62
|
+
* what makes the failure diagnosable.
|
|
63
|
+
*/
|
|
64
|
+
markFailed(runId: string, error: TraceRunError, partial?: Partial<Pick<StickerTraceRunDocument, "artifacts" | "partCount" | "groupCount">>, prior?: StickerTraceRunDocument | null): Promise<StickerTraceRunDocument>;
|
|
65
|
+
/** Records that this run's full-resolution parts and exports now exist. */
|
|
66
|
+
markPromoted(runId: string, promoted: PromotedArtifacts): Promise<StickerTraceRunDocument>;
|
|
67
|
+
/**
|
|
68
|
+
* One sheet's attempt history, newest first.
|
|
69
|
+
*
|
|
70
|
+
* A single equality plus one `orderBy` on `createdAt`, which every document
|
|
71
|
+
* carries โ `BaseRepository.create` writes it. Ordering by an OPTIONAL field
|
|
72
|
+
* (`startedAt`, `finishedAt`) would silently drop every queued run from its
|
|
73
|
+
* own history, which is Root Cause #100.
|
|
74
|
+
*/
|
|
75
|
+
listBySheet(sheetId: string, limit?: number): Promise<StickerTraceRunDocument[]>;
|
|
76
|
+
listForAdmin(model: SieveModel): Promise<FirebaseSieveResult<StickerTraceRunDocument>>;
|
|
77
|
+
/** Every Timestamp field carries `parseSieveDateValue` โ Root Cause #47. */
|
|
78
|
+
static readonly SIEVE_FIELDS: {
|
|
79
|
+
id: {
|
|
80
|
+
canFilter: boolean;
|
|
81
|
+
canSort: boolean;
|
|
82
|
+
};
|
|
83
|
+
sheetId: {
|
|
84
|
+
canFilter: boolean;
|
|
85
|
+
canSort: boolean;
|
|
86
|
+
};
|
|
87
|
+
name: {
|
|
88
|
+
canFilter: boolean;
|
|
89
|
+
canSort: boolean;
|
|
90
|
+
};
|
|
91
|
+
tier: {
|
|
92
|
+
canFilter: boolean;
|
|
93
|
+
canSort: boolean;
|
|
94
|
+
};
|
|
95
|
+
status: {
|
|
96
|
+
canFilter: boolean;
|
|
97
|
+
canSort: boolean;
|
|
98
|
+
};
|
|
99
|
+
stage: {
|
|
100
|
+
canFilter: boolean;
|
|
101
|
+
canSort: boolean;
|
|
102
|
+
};
|
|
103
|
+
requestedBy: {
|
|
104
|
+
canFilter: boolean;
|
|
105
|
+
canSort: boolean;
|
|
106
|
+
};
|
|
107
|
+
partCount: {
|
|
108
|
+
canFilter: boolean;
|
|
109
|
+
canSort: boolean;
|
|
110
|
+
};
|
|
111
|
+
durationMs: {
|
|
112
|
+
canFilter: boolean;
|
|
113
|
+
canSort: boolean;
|
|
114
|
+
};
|
|
115
|
+
startedAt: {
|
|
116
|
+
canFilter: boolean;
|
|
117
|
+
canSort: boolean;
|
|
118
|
+
parseValue: typeof parseSieveDateValue;
|
|
119
|
+
};
|
|
120
|
+
finishedAt: {
|
|
121
|
+
canFilter: boolean;
|
|
122
|
+
canSort: boolean;
|
|
123
|
+
parseValue: typeof parseSieveDateValue;
|
|
124
|
+
};
|
|
125
|
+
createdAt: {
|
|
126
|
+
canFilter: boolean;
|
|
127
|
+
canSort: boolean;
|
|
128
|
+
parseValue: typeof parseSieveDateValue;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export declare const stickerTraceRunsRepository: StickerTraceRunsRepository;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: An attempt is a RECORD, not an overwrite. Tuning a halftone scan takes
|
|
3
|
+
* several runs, and the whole value of keeping them is being able to ask
|
|
4
|
+
* weeks later what run 2 did differently and which stage run 3 died in.
|
|
5
|
+
* WHAT: Create, the capped event log, terminal transitions, and per-sheet
|
|
6
|
+
* history.
|
|
7
|
+
*
|
|
8
|
+
* ๐ A finished run is never edited. `markSucceeded` / `markFailed` are the
|
|
9
|
+
* last writes it takes; a re-trace creates a NEW document. Promotion writes to
|
|
10
|
+
* the SHEET (`promoteRun`) plus this run's own `promoted` block, and nothing
|
|
11
|
+
* else about the run moves.
|
|
12
|
+
*
|
|
13
|
+
* Holds no PII โ see the same note on `sticker-sheets.repository`.
|
|
14
|
+
*
|
|
15
|
+
* EXPORTS: StickerTraceRunsRepository, stickerTraceRunsRepository,
|
|
16
|
+
* StickerTraceRunCreateInput
|
|
17
|
+
*
|
|
18
|
+
* @tag domain:sticker-trace
|
|
19
|
+
* @tag layer:feature
|
|
20
|
+
* @tag pattern:repository
|
|
21
|
+
* @tag access:server
|
|
22
|
+
* @tag consumers:sticker-trace/actions,functions/sticker-trace
|
|
23
|
+
* @tag sideEffects:firestore
|
|
24
|
+
*/
|
|
25
|
+
import { BaseRepository, parseSieveDateValue, } from "../../../providers/db-firebase/index.js";
|
|
26
|
+
import { RUN_EVENTS_MAX, STICKER_TRACE_RUNS_COLLECTION, STICKER_TRACE_RUN_FIELDS, TraceRunStatusValues, } from "../schemas/firestore.js";
|
|
27
|
+
export class StickerTraceRunsRepository extends BaseRepository {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(STICKER_TRACE_RUNS_COLLECTION);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A run is born `queued` with an empty event log and zeroed counts.
|
|
33
|
+
*
|
|
34
|
+
* Firestore assigns the id (the ยง "Slug Prefix System" convention for
|
|
35
|
+
* `carts` / `jobs` / `notifications`): a run carries a mandatory human NAME,
|
|
36
|
+
* which is what anyone reads, so a second slug prefix would add a parse
|
|
37
|
+
* surface and a collision story for no reader. The id appears only in a
|
|
38
|
+
* Storage path and an RTDB channel key.
|
|
39
|
+
*/
|
|
40
|
+
async create(input) {
|
|
41
|
+
return super.create({
|
|
42
|
+
...input,
|
|
43
|
+
status: TraceRunStatusValues.QUEUED,
|
|
44
|
+
stage: "queued",
|
|
45
|
+
events: [],
|
|
46
|
+
partCount: 0,
|
|
47
|
+
groupCount: 0,
|
|
48
|
+
artifacts: {},
|
|
49
|
+
promoted: null,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Append one progress transition, FIFO-capped.
|
|
54
|
+
*
|
|
55
|
+
* ๐ `arrayUnion` cannot enforce a cap, so this folds in memory and writes
|
|
56
|
+
* the whole array โ the same constraint ยง "Status History" records, and the
|
|
57
|
+
* reason `prior` exists here: the coordinator and the finalizer each hold
|
|
58
|
+
* the run already, so threading it costs **zero extra reads**. Omitting it
|
|
59
|
+
* is legal and pays one read.
|
|
60
|
+
*
|
|
61
|
+
* ๐ Truncation is RECORDED, never silent. `eventsTruncated` is what lets a
|
|
62
|
+
* reader say "earlier progress trimmed" instead of implying a `max`-tier run
|
|
63
|
+
* with sixty shards simply had ten events.
|
|
64
|
+
*/
|
|
65
|
+
async appendEvent(runId, event, prior) {
|
|
66
|
+
const current = prior !== undefined && prior !== null ? prior : await this.findByIdOrFail(runId);
|
|
67
|
+
const merged = [...(current.events ?? []), event];
|
|
68
|
+
const overflow = Math.max(0, merged.length - RUN_EVENTS_MAX);
|
|
69
|
+
return this.update(runId, {
|
|
70
|
+
events: overflow > 0 ? merged.slice(overflow) : merged,
|
|
71
|
+
...(overflow > 0
|
|
72
|
+
? { eventsTruncated: (current.eventsTruncated ?? 0) + overflow }
|
|
73
|
+
: {}),
|
|
74
|
+
stage: event.stage,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/** `queued` โ `running`, stamping the clock the duration is measured from. */
|
|
78
|
+
async markStarted(runId, shardCount) {
|
|
79
|
+
return this.update(runId, {
|
|
80
|
+
status: TraceRunStatusValues.RUNNING,
|
|
81
|
+
startedAt: new Date(),
|
|
82
|
+
...(shardCount !== undefined ? { shardCount } : {}),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Terminal success.
|
|
87
|
+
*
|
|
88
|
+
* `durationMs` is computed from the run's own `startedAt` rather than
|
|
89
|
+
* accepted from the caller โ two call sites each subtracting their own pair
|
|
90
|
+
* of timestamps is how the number ends up meaning different things on
|
|
91
|
+
* different runs (Root Cause #75).
|
|
92
|
+
*/
|
|
93
|
+
async markSucceeded(runId, result, prior) {
|
|
94
|
+
const current = prior !== undefined && prior !== null ? prior : await this.findByIdOrFail(runId);
|
|
95
|
+
const finishedAt = new Date();
|
|
96
|
+
return this.update(runId, {
|
|
97
|
+
status: TraceRunStatusValues.SUCCEEDED,
|
|
98
|
+
stage: "done",
|
|
99
|
+
finishedAt,
|
|
100
|
+
...(current.startedAt
|
|
101
|
+
? { durationMs: finishedAt.getTime() - current.startedAt.getTime() }
|
|
102
|
+
: {}),
|
|
103
|
+
...result,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Terminal failure, naming the stage it died in.
|
|
108
|
+
*
|
|
109
|
+
* ๐ `error.message` must already be user-safe โ resolved through
|
|
110
|
+
* `toUserMessage`, never raw server text. A Node `MODULE_NOT_FOUND` with a
|
|
111
|
+
* full require stack rendered inside a progress panel is Root Cause #86, and
|
|
112
|
+
* it reached a buyer's bid modal once already.
|
|
113
|
+
*
|
|
114
|
+
* Partial artifacts are KEPT when the caller has them: a run that failed at
|
|
115
|
+
* `parts` still produced a preview and an overlay, and those are exactly
|
|
116
|
+
* what makes the failure diagnosable.
|
|
117
|
+
*/
|
|
118
|
+
async markFailed(runId, error, partial, prior) {
|
|
119
|
+
const current = prior !== undefined && prior !== null ? prior : await this.findByIdOrFail(runId);
|
|
120
|
+
const finishedAt = new Date();
|
|
121
|
+
return this.update(runId, {
|
|
122
|
+
status: TraceRunStatusValues.FAILED,
|
|
123
|
+
stage: error.stage,
|
|
124
|
+
finishedAt,
|
|
125
|
+
...(current.startedAt
|
|
126
|
+
? { durationMs: finishedAt.getTime() - current.startedAt.getTime() }
|
|
127
|
+
: {}),
|
|
128
|
+
error,
|
|
129
|
+
...(partial ?? {}),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/** Records that this run's full-resolution parts and exports now exist. */
|
|
133
|
+
async markPromoted(runId, promoted) {
|
|
134
|
+
return this.update(runId, { promoted });
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* One sheet's attempt history, newest first.
|
|
138
|
+
*
|
|
139
|
+
* A single equality plus one `orderBy` on `createdAt`, which every document
|
|
140
|
+
* carries โ `BaseRepository.create` writes it. Ordering by an OPTIONAL field
|
|
141
|
+
* (`startedAt`, `finishedAt`) would silently drop every queued run from its
|
|
142
|
+
* own history, which is Root Cause #100.
|
|
143
|
+
*/
|
|
144
|
+
async listBySheet(sheetId, limit = 50) {
|
|
145
|
+
const snap = await this.getCollection()
|
|
146
|
+
.where(STICKER_TRACE_RUN_FIELDS.SHEET_ID, "==", sheetId)
|
|
147
|
+
.orderBy(STICKER_TRACE_RUN_FIELDS.CREATED_AT, "desc")
|
|
148
|
+
.limit(limit)
|
|
149
|
+
.get();
|
|
150
|
+
return snap.docs.map((doc) => this.mapDoc(doc));
|
|
151
|
+
}
|
|
152
|
+
async listForAdmin(model) {
|
|
153
|
+
return this.sieveQuery(model, StickerTraceRunsRepository.SIEVE_FIELDS, {
|
|
154
|
+
defaultPageSize: 25,
|
|
155
|
+
maxPageSize: 50,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/** Every Timestamp field carries `parseSieveDateValue` โ Root Cause #47. */
|
|
160
|
+
StickerTraceRunsRepository.SIEVE_FIELDS = {
|
|
161
|
+
id: { canFilter: true, canSort: false },
|
|
162
|
+
sheetId: { canFilter: true, canSort: false },
|
|
163
|
+
name: { canFilter: true, canSort: true },
|
|
164
|
+
tier: { canFilter: true, canSort: false },
|
|
165
|
+
status: { canFilter: true, canSort: false },
|
|
166
|
+
stage: { canFilter: true, canSort: false },
|
|
167
|
+
requestedBy: { canFilter: true, canSort: false },
|
|
168
|
+
partCount: { canFilter: true, canSort: true },
|
|
169
|
+
durationMs: { canFilter: true, canSort: true },
|
|
170
|
+
startedAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
|
|
171
|
+
finishedAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
|
|
172
|
+
createdAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
|
|
173
|
+
};
|
|
174
|
+
export const stickerTraceRunsRepository = new StickerTraceRunsRepository();
|